/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module2 = __require(id) ?? {}; return module2.__esModule && module2.default ? module2.default : module2; }, __require); })() "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // node_modules/obsidian-dev-utils/dist/lib/Function.cjs var require_Function = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/Function.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Function_exports = {}; __export2(Function_exports, { noop: () => noop, noopAsync: () => noopAsync, omitAsyncReturnType: () => omitAsyncReturnType2, omitReturnType: () => omitReturnType }); module2.exports = __toCommonJS2(Function_exports); function noop() { } async function noopAsync() { } function omitAsyncReturnType2(fn) { return async (...args) => { await fn(...args); }; } function omitReturnType(fn) { return (...args) => { fn(...args); }; } } }); // node_modules/obsidian-typings/dist/implementations.cjs var require_implementations = __commonJS({ "node_modules/obsidian-typings/dist/implementations.cjs"(exports2, module2) { "use strict"; var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var implementations_exports = {}; __export2(implementations_exports, { CustomArrayDictImpl: () => CustomArrayDictImpl, InternalPluginName: () => InternalPluginName, constructApp: () => constructApp, constructInternalPlugin: () => constructInternalPlugin, constructInternalPlugins: () => constructInternalPlugins, constructTFile: () => constructTFile, constructTFolder: () => constructTFolder, createTFileInstance: () => createTFileInstance, createTFolderInstance: () => createTFolderInstance, isEmbedCache: () => isEmbedCache, isFrontmatterLinkCache: () => isFrontmatterLinkCache, isLinkCache: () => isLinkCache, isReferenceCache: () => isReferenceCache, parentFolderPath: () => parentFolderPath }); module2.exports = __toCommonJS2(implementations_exports); function parentFolderPath(path) { return path.replace(/\/?[^\/]*$/, "") || "/"; } var import_obsidian5 = require("obsidian"); function constructTFolder(vault, path) { return new import_obsidian5.TFolder(vault, path); } function createTFolderInstance(vault, path) { let folder = vault.getFolderByPath(path); if (folder) { return folder; } folder = constructTFolder(vault, path); folder.parent = createTFolderInstance(vault, parentFolderPath(path)); folder.deleted = true; return folder; } var CustomArrayDictImpl = class { data = /* @__PURE__ */ new Map(); add(key, value) { let values = this.get(key); if (!values) { values = []; this.data.set(key, values); } if (!values.includes(value)) { values.push(value); } } remove(key, value) { const values = this.get(key); if (!values) { return; } values.remove(value); if (values.length === 0) { this.clear(key); } } get(key) { return this.data.get(key) || null; } keys() { return Array.from(this.data.keys()); } clear(key) { this.data.delete(key); } clearAll() { this.data.clear(); } contains(key, value) { return !!this.get(key)?.contains(value); } count() { let ans = 0; for (const key in this.keys()) { ans += this.get(key)?.length ?? 0; } return ans; } }; var InternalPluginName = { AudioRecorder: "audio-recorder", Backlink: "backlink", Bookmarks: "bookmarks", Canvas: "canvas", CommandPalette: "command-palette", DailyNotes: "daily-notes", EditorStatus: "editor-status", FileExplorer: "file-explorer", FileRecovery: "file-recovery", GlobalSearch: "global-search", Graph: "graph", MarkdownImporter: "markdown-importer", NoteComposer: "note-composer", OutgoingLink: "outgoing-link", Outline: "outline", PagePreview: "page-preview", Properties: "properties", Publish: "publish", RandomNote: "random-note", SlashCommand: "slash-command", Slides: "slides", Switcher: "switcher", Sync: "sync", TagPane: "tag-pane", Templates: "templates", WordCount: "word-count", Workspaces: "workspaces", ZkPrefixer: "zk-prefixer" }; var import_obsidian22 = require("obsidian"); function constructTFile(vault, path) { return new import_obsidian22.TFile(vault, path); } function createTFileInstance(vault, path) { let file = vault.getFileByPath(path); if (file) { return file; } file = constructTFile(vault, path); file.parent = createTFolderInstance(vault, parentFolderPath(path)); file.deleted = true; return file; } function isReferenceCache(reference) { return !!reference.position; } function isEmbedCache(reference) { return isReferenceCache(reference) && reference.original[0] === "!"; } function isFrontmatterLinkCache(reference) { return !!reference.key; } function isLinkCache(reference) { return isReferenceCache(reference) && reference.original[0] !== "!"; } function constructInternalPlugins(app) { return new app.internalPlugins.constructor(app); } function constructInternalPlugin(app, instance, internalPlugins) { const anyPlugin = Object.values(app.internalPlugins.plugins)[0]; if (!anyPlugin) { throw new Error("No internal plugin found"); } return new anyPlugin.constructor(app, instance, internalPlugins); } var import_obsidian32 = require("obsidian"); function constructApp(adapter, appId) { return new import_obsidian32.App(adapter, appId); } } }); // node_modules/path-browserify/index.js var require_path_browserify = __commonJS({ "node_modules/path-browserify/index.js"(exports2, module2) { var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; function assertPath(path) { if (typeof path !== "string") { throw new TypeError("Path must be a string. Received " + JSON.stringify(path)); } } function normalizeStringPosix(path, allowAboveRoot) { var res = ""; var lastSegmentLength = 0; var lastSlash = -1; var dots = 0; var code; for (var i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); else if (code === 47) break; else code = 47; if (code === 47) { if (lastSlash === i - 1 || dots === 1) { } else if (lastSlash !== i - 1 && dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) { if (res.length > 2) { var lastSlashIndex = res.lastIndexOf("/"); if (lastSlashIndex !== res.length - 1) { if (lastSlashIndex === -1) { res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); } lastSlash = i; dots = 0; continue; } } else if (res.length === 2 || res.length === 1) { res = ""; lastSegmentLength = 0; lastSlash = i; dots = 0; continue; } } if (allowAboveRoot) { if (res.length > 0) res += "/.."; else res = ".."; lastSegmentLength = 2; } } else { if (res.length > 0) res += "/" + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); lastSegmentLength = i - lastSlash - 1; } lastSlash = i; dots = 0; } else if (code === 46 && dots !== -1) { ++dots; } else { dots = -1; } } return res; } function _format(sep, pathObject) { var dir = pathObject.dir || pathObject.root; var base = pathObject.base || (pathObject.name || "") + (pathObject.ext || ""); if (!dir) { return base; } if (dir === pathObject.root) { return dir + base; } return dir + sep + base; } var posix = { // path.resolve([from ...], to) resolve: function resolve() { var resolvedPath = ""; var resolvedAbsolute = false; var cwd; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path; if (i >= 0) path = arguments[i]; else { if (cwd === void 0) cwd = __process2.cwd(); path = cwd; } assertPath(path); if (path.length === 0) { continue; } resolvedPath = path + "/" + resolvedPath; resolvedAbsolute = path.charCodeAt(0) === 47; } resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute) { if (resolvedPath.length > 0) return "/" + resolvedPath; else return "/"; } else if (resolvedPath.length > 0) { return resolvedPath; } else { return "."; } }, normalize: function normalize(path) { assertPath(path); if (path.length === 0) return "."; var isAbsolute = path.charCodeAt(0) === 47; var trailingSeparator = path.charCodeAt(path.length - 1) === 47; path = normalizeStringPosix(path, !isAbsolute); if (path.length === 0 && !isAbsolute) path = "."; if (path.length > 0 && trailingSeparator) path += "/"; if (isAbsolute) return "/" + path; return path; }, isAbsolute: function isAbsolute(path) { assertPath(path); return path.length > 0 && path.charCodeAt(0) === 47; }, join: function join2() { if (arguments.length === 0) return "."; var joined; for (var i = 0; i < arguments.length; ++i) { var arg = arguments[i]; assertPath(arg); if (arg.length > 0) { if (joined === void 0) joined = arg; else joined += "/" + arg; } } if (joined === void 0) return "."; return posix.normalize(joined); }, relative: function relative(from, to) { assertPath(from); assertPath(to); if (from === to) return ""; from = posix.resolve(from); to = posix.resolve(to); if (from === to) return ""; var fromStart = 1; for (; fromStart < from.length; ++fromStart) { if (from.charCodeAt(fromStart) !== 47) break; } var fromEnd = from.length; var fromLen = fromEnd - fromStart; var toStart = 1; for (; toStart < to.length; ++toStart) { if (to.charCodeAt(toStart) !== 47) break; } var toEnd = to.length; var toLen = toEnd - toStart; var length = fromLen < toLen ? fromLen : toLen; var lastCommonSep = -1; var i = 0; for (; i <= length; ++i) { if (i === length) { if (toLen > length) { if (to.charCodeAt(toStart + i) === 47) { return to.slice(toStart + i + 1); } else if (i === 0) { return to.slice(toStart + i); } } else if (fromLen > length) { if (from.charCodeAt(fromStart + i) === 47) { lastCommonSep = i; } else if (i === 0) { lastCommonSep = 0; } } break; } var fromCode = from.charCodeAt(fromStart + i); var toCode = to.charCodeAt(toStart + i); if (fromCode !== toCode) break; else if (fromCode === 47) lastCommonSep = i; } var out = ""; for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) { if (i === fromEnd || from.charCodeAt(i) === 47) { if (out.length === 0) out += ".."; else out += "/.."; } } if (out.length > 0) return out + to.slice(toStart + lastCommonSep); else { toStart += lastCommonSep; if (to.charCodeAt(toStart) === 47) ++toStart; return to.slice(toStart); } }, _makeLong: function _makeLong(path) { return path; }, dirname: function dirname4(path) { assertPath(path); if (path.length === 0) return "."; var code = path.charCodeAt(0); var hasRoot = code === 47; var end = -1; var matchedSlash = true; for (var i = path.length - 1; i >= 1; --i) { code = path.charCodeAt(i); if (code === 47) { if (!matchedSlash) { end = i; break; } } else { matchedSlash = false; } } if (end === -1) return hasRoot ? "/" : "."; if (hasRoot && end === 1) return "//"; return path.slice(0, end); }, basename: function basename(path, ext) { if (ext !== void 0 && typeof ext !== "string") throw new TypeError('"ext" argument must be a string'); assertPath(path); var start = 0; var end = -1; var matchedSlash = true; var i; if (ext !== void 0 && ext.length > 0 && ext.length <= path.length) { if (ext.length === path.length && ext === path) return ""; var extIdx = ext.length - 1; var firstNonSlashEnd = -1; for (i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47) { if (!matchedSlash) { start = i + 1; break; } } else { if (firstNonSlashEnd === -1) { matchedSlash = false; firstNonSlashEnd = i + 1; } if (extIdx >= 0) { if (code === ext.charCodeAt(extIdx)) { if (--extIdx === -1) { end = i; } } else { extIdx = -1; end = firstNonSlashEnd; } } } } if (start === end) end = firstNonSlashEnd; else if (end === -1) end = path.length; return path.slice(start, end); } else { for (i = path.length - 1; i >= 0; --i) { if (path.charCodeAt(i) === 47) { if (!matchedSlash) { start = i + 1; break; } } else if (end === -1) { matchedSlash = false; end = i + 1; } } if (end === -1) return ""; return path.slice(start, end); } }, extname: function extname(path) { assertPath(path); var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; var preDotState = 0; for (var i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47) { if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { matchedSlash = false; end = i + 1; } if (code === 46) { if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { return ""; } return path.slice(startDot, end); }, format: function format(pathObject) { if (pathObject === null || typeof pathObject !== "object") { throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject); } return _format("/", pathObject); }, parse: function parse(path) { assertPath(path); var ret = { root: "", dir: "", base: "", ext: "", name: "" }; if (path.length === 0) return ret; var code = path.charCodeAt(0); var isAbsolute = code === 47; var start; if (isAbsolute) { ret.root = "/"; start = 1; } else { start = 0; } var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; var i = path.length - 1; var preDotState = 0; for (; i >= start; --i) { code = path.charCodeAt(i); if (code === 47) { if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { matchedSlash = false; end = i + 1; } if (code === 46) { if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { if (end !== -1) { if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end); else ret.base = ret.name = path.slice(startPart, end); } } else { if (startPart === 0 && isAbsolute) { ret.name = path.slice(1, startDot); ret.base = path.slice(1, end); } else { ret.name = path.slice(startPart, startDot); ret.base = path.slice(startPart, end); } ret.ext = path.slice(startDot, end); } if (startPart > 0) ret.dir = path.slice(0, startPart - 1); else if (isAbsolute) ret.dir = "/"; return ret; }, sep: "/", delimiter: ":", win32: null, posix: null }; posix.posix = posix; module2.exports = posix; } }); // node_modules/eventemitter3/index.js var require_eventemitter3 = __commonJS({ "node_modules/eventemitter3/index.js"(exports2, module2) { "use strict"; var has = Object.prototype.hasOwnProperty; var prefix = "~"; function Events() { } if (Object.create) { Events.prototype = /* @__PURE__ */ Object.create(null); if (!new Events().__proto__) prefix = false; } function EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } function addListener(emitter, event, fn, context, once) { if (typeof fn !== "function") { throw new TypeError("The listener must be a function"); } var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event; if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); else emitter._events[evt] = [emitter._events[evt], listener]; return emitter; } function clearEvent(emitter, evt) { if (--emitter._eventsCount === 0) emitter._events = new Events(); else delete emitter._events[evt]; } function EventEmitter() { this._events = new Events(); this._eventsCount = 0; } EventEmitter.prototype.eventNames = function eventNames() { var names = [], events, name; if (this._eventsCount === 0) return names; for (name in events = this._events) { if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); } if (Object.getOwnPropertySymbols) { return names.concat(Object.getOwnPropertySymbols(events)); } return names; }; EventEmitter.prototype.listeners = function listeners(event) { var evt = prefix ? prefix + event : event, handlers = this._events[evt]; if (!handlers) return []; if (handlers.fn) return [handlers.fn]; for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { ee[i] = handlers[i].fn; } return ee; }; EventEmitter.prototype.listenerCount = function listenerCount(event) { var evt = prefix ? prefix + event : event, listeners = this._events[evt]; if (!listeners) return 0; if (listeners.fn) return 1; return listeners.length; }; EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return false; var listeners = this._events[evt], len = arguments.length, args, i; if (listeners.fn) { if (listeners.once) this.removeListener(event, listeners.fn, void 0, true); switch (len) { case 1: return listeners.fn.call(listeners.context), true; case 2: return listeners.fn.call(listeners.context, a1), true; case 3: return listeners.fn.call(listeners.context, a1, a2), true; case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } for (i = 1, args = new Array(len - 1); i < len; i++) { args[i - 1] = arguments[i]; } listeners.fn.apply(listeners.context, args); } else { var length = listeners.length, j; for (i = 0; i < length; i++) { if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true); switch (len) { case 1: listeners[i].fn.call(listeners[i].context); break; case 2: listeners[i].fn.call(listeners[i].context, a1); break; case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; default: if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) { args[j - 1] = arguments[j]; } listeners[i].fn.apply(listeners[i].context, args); } } } return true; }; EventEmitter.prototype.on = function on(event, fn, context) { return addListener(this, event, fn, context, false); }; EventEmitter.prototype.once = function once(event, fn, context) { return addListener(this, event, fn, context, true); }; EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { var evt = prefix ? prefix + event : event; if (!this._events[evt]) return this; if (!fn) { clearEvent(this, evt); return this; } var listeners = this._events[evt]; if (listeners.fn) { if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) { clearEvent(this, evt); } } else { for (var i = 0, events = [], length = listeners.length; i < length; i++) { if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) { events.push(listeners[i]); } } if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; else clearEvent(this, evt); } return this; }; EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { var evt; if (event) { evt = prefix ? prefix + event : event; if (this._events[evt]) clearEvent(this, evt); } else { this._events = new Events(); this._eventsCount = 0; } return this; }; EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.addListener = EventEmitter.prototype.on; EventEmitter.prefixed = prefix; EventEmitter.EventEmitter = EventEmitter; if ("undefined" !== typeof module2) { module2.exports = EventEmitter; } } }); // node_modules/obsidian-dev-utils/dist/lib/Error.cjs var require_Error = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/Error.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Error_exports = {}; __export2(Error_exports, { emitAsyncErrorEvent: () => emitAsyncErrorEvent, errorToString: () => errorToString, getStackTrace: () => getStackTrace, printError: () => printError, registerAsyncErrorEventHandler: () => registerAsyncErrorEventHandler, throwExpression: () => throwExpression }); module2.exports = __toCommonJS2(Error_exports); var import_eventemitter3 = require_eventemitter3(); var ASYNC_ERROR_EVENT = "asyncError"; var asyncErrorEventEmitter = new import_eventemitter3.EventEmitter(); asyncErrorEventEmitter.on(ASYNC_ERROR_EVENT, handleAsyncError); function emitAsyncErrorEvent(asyncError) { asyncErrorEventEmitter.emit(ASYNC_ERROR_EVENT, asyncError); } function errorToString(error) { return parseErrorEntries(error).map((entry) => " ".repeat(entry.level) + entry.message).join("\n"); } function getStackTrace() { const stack = new Error().stack ?? ""; const lines = stack.split("\n"); return lines.slice(2).join("\n"); } function printError(error) { const entries = parseErrorEntries(error); for (const entry of entries) { if (entry.shouldClearAnsiSequence) { console.error(`\x1B[0m${entry.message}\x1B[0m`); } else { console.error(entry.message); } } } function registerAsyncErrorEventHandler(handler) { asyncErrorEventEmitter.on(ASYNC_ERROR_EVENT, handler); return () => asyncErrorEventEmitter.off(ASYNC_ERROR_EVENT, handler); } function throwExpression(error) { throw error; } function handleAsyncError(asyncError) { printError(new Error("An unhandled error occurred executing async operation", { cause: asyncError })); } function parseErrorEntries(error, level = 0, entries = []) { if (error === void 0) { return entries; } if (!(error instanceof Error)) { let str = ""; if (error === null) { str = "(null)"; } else if (typeof error === "string") { str = error; } else { str = JSON.stringify(error); } entries.push({ level, message: str }); return entries; } const title = `${error.name}: ${error.message}`; entries.push({ level, message: title, shouldClearAnsiSequence: true }); if (error.stack) { const restStack = error.stack.startsWith(title) ? error.stack.slice(title.length + 1) : error.stack; entries.push({ level, message: `Error stack: ${restStack}` }); } if (error.cause !== void 0) { entries.push({ level, message: "Caused by:" }); parseErrorEntries(error.cause, level + 1, entries); } return entries; } } }); // node_modules/obsidian-dev-utils/dist/lib/RegExp.cjs var require_RegExp = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/RegExp.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var RegExp_exports = {}; __export2(RegExp_exports, { escapeRegExp: () => escapeRegExp }); module2.exports = __toCommonJS2(RegExp_exports); function escapeRegExp(str) { return str.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&"); } } }); // node_modules/obsidian-dev-utils/dist/lib/ValueProvider.cjs var require_ValueProvider = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/ValueProvider.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var ValueProvider_exports = {}; __export2(ValueProvider_exports, { resolveValue: () => resolveValue }); module2.exports = __toCommonJS2(ValueProvider_exports); async function resolveValue(provider, ...args) { if (isFunction(provider)) { return await provider(...args); } else { return provider; } } function isFunction(value) { return typeof value === "function"; } } }); // node_modules/obsidian-dev-utils/dist/lib/String.cjs var require_String = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/String.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var String_exports = {}; __export2(String_exports, { ensureEndsWith: () => ensureEndsWith, ensureStartsWith: () => ensureStartsWith, escape: () => escape, insertAt: () => insertAt, makeValidVariableName: () => makeValidVariableName, normalize: () => normalize, replace: () => replace, replaceAllAsync: () => replaceAllAsync, trimEnd: () => trimEnd, trimStart: () => trimStart, unescape: () => unescape }); module2.exports = __toCommonJS2(String_exports); var import_Error = require_Error(); var import_RegExp = require_RegExp(); var import_ValueProvider = require_ValueProvider(); var ESCAPE_MAP = { "\n": "\\n", "\r": "\\r", " ": "\\t", "\b": "\\b", "\f": "\\f", "'": "\\'", '"': '\\"', "\\": "\\\\" }; var UNESCAPE_MAP = {}; for (const [key, value] of Object.entries(ESCAPE_MAP)) { UNESCAPE_MAP[value] = key; } function ensureEndsWith(str, suffix) { return str.endsWith(suffix) ? str : str + suffix; } function ensureStartsWith(str, prefix) { return str.startsWith(prefix) ? str : prefix + str; } function escape(str) { return replace(str, ESCAPE_MAP); } function insertAt(str, substring, startIndex, endIndex) { endIndex ??= startIndex; return str.slice(0, startIndex) + substring + str.slice(endIndex); } function makeValidVariableName(str) { return str.replace(/[^a-zA-Z0-9_]/g, "_"); } function normalize(str) { return str.replace(/\u00A0|\u202F/g, " ").normalize("NFC"); } function replace(str, replacementsMap) { const regExp = new RegExp(Object.keys(replacementsMap).map((source) => (0, import_RegExp.escapeRegExp)(source)).join("|"), "g"); return str.replaceAll(regExp, (source) => replacementsMap[source] ?? (0, import_Error.throwExpression)(new Error(`Unexpected replacement source: ${source}`))); } async function replaceAllAsync(str, searchValue, replacer) { const replacementPromises = []; str.replaceAll(searchValue, (substring, ...args) => { replacementPromises.push((0, import_ValueProvider.resolveValue)(replacer, substring, ...args)); return substring; }); const replacements = await Promise.all(replacementPromises); return str.replaceAll(searchValue, () => replacements.shift() ?? (0, import_Error.throwExpression)(new Error("Unexpected empty replacement"))); } function trimEnd(str, suffix, validate) { if (str.endsWith(suffix)) { return str.slice(0, -suffix.length); } if (validate) { throw new Error(`String ${str} does not end with suffix ${suffix}`); } return str; } function trimStart(str, prefix, validate) { if (str.startsWith(prefix)) { return str.slice(prefix.length); } if (validate) { throw new Error(`String ${str} does not start with prefix ${prefix}`); } return str; } function unescape(str) { return replace(str, UNESCAPE_MAP); } } }); // node_modules/obsidian-dev-utils/dist/lib/Path.cjs var require_Path = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/Path.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __create2 = Object.create; var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __getProtoOf2 = Object.getPrototypeOf; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Path_exports = {}; __export2(Path_exports, { basename: () => basename, delimiter: () => delimiter, dirname: () => dirname4, extname: () => extname, format: () => format, getDirname: () => getDirname, getFilename: () => getFilename, isAbsolute: () => isAbsolute, join: () => join2, makeFileName: () => makeFileName, normalize: () => normalize, normalizeIfRelative: () => normalizeIfRelative, parse: () => parse, posix: () => posix, relative: () => relative, resolve: () => resolve, sep: () => sep, toPosixBuffer: () => toPosixBuffer, toPosixPath: () => toPosixPath }); module2.exports = __toCommonJS2(Path_exports); var import_path_browserify = __toESM2(require_path_browserify(), 1); var import_String = require_String(); var WINDOWS_POSIX_LIKE_PATH_REG_EXP = /[a-zA-Z]:\/[^:]*$/; var posix = import_path_browserify.default.posix; var delimiter = posix.delimiter; var sep = import_path_browserify.default.posix.sep; var basename = posix.basename; var dirname4 = posix.dirname; var extname = posix.extname; var format = posix.format; function isAbsolute(path2) { return posix.isAbsolute(path2) || WINDOWS_POSIX_LIKE_PATH_REG_EXP.exec(path2)?.[0] === path2; } var join2 = posix.join; var normalize = posix.normalize; var parse = posix.parse; var relative = posix.relative; function getDirname(importMetaUrl) { return dirname4(getFilename(importMetaUrl)); } function getFilename(importMetaUrl) { return resolve(new URL(importMetaUrl).pathname); } function makeFileName(fileName, extension) { return extension ? `${fileName}.${extension}` : fileName; } function normalizeIfRelative(path2) { if (path2.startsWith("/") || path2.includes(":")) { return path2; } return (0, import_String.ensureStartsWith)(path2, "./"); } function resolve(...pathSegments) { let path2 = posix.resolve(...pathSegments); path2 = toPosixPath(path2); const match = WINDOWS_POSIX_LIKE_PATH_REG_EXP.exec(path2); return match?.[0] ?? path2; } function toPosixBuffer(buffer) { return Buffer.from(toPosixPath(buffer.toString())); } function toPosixPath(path2) { return path2.replace(/\\/g, "/"); } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/FileSystem.cjs var require_FileSystem = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/FileSystem.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var FileSystem_exports = {}; __export2(FileSystem_exports, { CANVAS_FILE_EXTENSION: () => CANVAS_FILE_EXTENSION, MARKDOWN_FILE_EXTENSION: () => MARKDOWN_FILE_EXTENSION2, checkExtension: () => checkExtension, getAbstractFile: () => getAbstractFile, getAbstractFileOrNull: () => getAbstractFileOrNull, getFile: () => getFile, getFileOrNull: () => getFileOrNull3, getFolder: () => getFolder, getFolderOrNull: () => getFolderOrNull, getMarkdownFiles: () => getMarkdownFiles, getOrCreateFile: () => getOrCreateFile2, getOrCreateFolder: () => getOrCreateFolder, getPath: () => getPath, isAbstractFile: () => isAbstractFile, isCanvasFile: () => isCanvasFile, isFile: () => isFile, isFolder: () => isFolder, isMarkdownFile: () => isMarkdownFile2, isNote: () => isNote2, trimMarkdownExtension: () => trimMarkdownExtension }); module2.exports = __toCommonJS2(FileSystem_exports); var import_obsidian5 = require("obsidian"); var import_implementations = require_implementations(); var import_Path4 = require_Path(); var import_String = require_String(); var MARKDOWN_FILE_EXTENSION2 = "md"; var CANVAS_FILE_EXTENSION = "canvas"; function checkExtension(pathOrFile, extension) { if (pathOrFile === null) { return false; } return (0, import_Path4.extname)(getPath(pathOrFile)).toLowerCase().slice(1) === extension.toLowerCase(); } function getAbstractFile(app, pathOrFile, insensitive) { const file = getAbstractFileOrNull(app, pathOrFile, insensitive); if (!file) { throw new Error(`Abstract file not found: ${pathOrFile}`); } return file; } function getAbstractFileOrNull(app, pathOrFile, insensitive) { if (pathOrFile === null) { return null; } if (pathOrFile === "." || pathOrFile === "") { return app.vault.getRoot(); } if (isAbstractFile(pathOrFile)) { return pathOrFile; } if (insensitive) { return app.vault.getAbstractFileByPathInsensitive(pathOrFile); } return app.vault.getAbstractFileByPath(pathOrFile); } function getFile(app, pathOrFile, allowNonExisting, insensitive) { let file = getFileOrNull3(app, pathOrFile, insensitive); if (!file) { if (allowNonExisting) { file = (0, import_implementations.createTFileInstance)(app.vault, pathOrFile); } else { throw new Error(`File not found: ${pathOrFile}`); } } return file; } function getFileOrNull3(app, pathOrFile, insensitive) { const file = getAbstractFileOrNull(app, pathOrFile, insensitive); if (isFile(file)) { return file; } return null; } function getFolder(app, pathOrFolder, allowNonExisting, insensitive) { let folder = getFolderOrNull(app, pathOrFolder, insensitive); if (!folder) { if (allowNonExisting) { folder = (0, import_implementations.createTFolderInstance)(app.vault, pathOrFolder); } else { throw new Error(`Folder not found: ${pathOrFolder}`); } } return folder; } function getFolderOrNull(app, pathOrFolder, insensitive) { const folder = getAbstractFileOrNull(app, pathOrFolder, insensitive); if (isFolder(folder)) { return folder; } return null; } function getMarkdownFiles(app, pathOrFolder, isRecursive) { const folder = getFolder(app, pathOrFolder); let markdownFiles = []; if (!isRecursive) { markdownFiles = folder.children.filter((file) => isMarkdownFile2(file)); } else { import_obsidian5.Vault.recurseChildren(folder, (abstractFile) => { if (isMarkdownFile2(abstractFile)) { markdownFiles.push(abstractFile); } }); } markdownFiles = markdownFiles.sort((a, b) => a.path.localeCompare(b.path)); return markdownFiles; } async function getOrCreateFile2(app, path) { const file = getFileOrNull3(app, path); if (file) { return file; } const folderPath = (0, import_implementations.parentFolderPath)(path); await getOrCreateFolder(app, folderPath); return await app.vault.create(path, ""); } async function getOrCreateFolder(app, path) { const folder = getFolderOrNull(app, path); if (folder) { return folder; } return await app.vault.createFolder(path); } function getPath(pathOrFile) { return isAbstractFile(pathOrFile) ? pathOrFile.path : pathOrFile; } function isAbstractFile(file) { return file instanceof import_obsidian5.TAbstractFile; } function isCanvasFile(pathOrFile) { return checkExtension(pathOrFile, CANVAS_FILE_EXTENSION); } function isFile(file) { return file instanceof import_obsidian5.TFile; } function isFolder(file) { return file instanceof import_obsidian5.TFolder; } function isMarkdownFile2(pathOrFile) { return checkExtension(pathOrFile, MARKDOWN_FILE_EXTENSION2); } function isNote2(pathOrFile) { return isMarkdownFile2(pathOrFile) || isCanvasFile(pathOrFile); } function trimMarkdownExtension(file) { if (!isMarkdownFile2(file)) { return file.path; } return (0, import_String.trimEnd)(file.path, "." + MARKDOWN_FILE_EXTENSION2); } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettings.cjs var require_PluginSettings = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettings.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var PluginSettings_exports = {}; __export2(PluginSettings_exports, { clonePluginSettings: () => clonePluginSettings, loadPluginSettings: () => loadPluginSettings }); module2.exports = __toCommonJS2(PluginSettings_exports); function clonePluginSettings(defaultPluginSettingsFactory, settings) { return loadPluginSettings(defaultPluginSettingsFactory, settings); } function loadPluginSettings(defaultPluginSettingsFactory, data) { const defaultPluginSettings = defaultPluginSettingsFactory(); if (data && typeof data === "object") { const record = data; for (const [key, value] of Object.entries(record)) { if (key in defaultPluginSettings) { defaultPluginSettings[key] = value; } } } return defaultPluginSettings; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginBase.cjs var require_PluginBase = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginBase.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var PluginBase_exports = {}; __export2(PluginBase_exports, { PluginBase: () => PluginBase2 }); module2.exports = __toCommonJS2(PluginBase_exports); var import_obsidian5 = require("obsidian"); var import_Error = require_Error(); var import_Function2 = require_Function(); var import_PluginSettings = require_PluginSettings(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; var PluginBase2 = class extends import_obsidian5.Plugin { /** * Gets a copy of the current plugin settings. * * @returns A copy of the plugin settings. */ get settingsCopy() { return (0, import_PluginSettings.clonePluginSettings)(this.createDefaultPluginSettings.bind(this), this.settings); } /** * Gets the AbortSignal used for aborting long-running operations. * * @returns The abort signal. */ get abortSignal() { return this._abortSignal; } /** * Gets the plugin settings. * * @returns The plugin settings. */ get settings() { return this._settings; } _abortSignal; _settings; notice; /** * Called when the plugin is loaded */ async onload() { this.register((0, import_Error.registerAsyncErrorEventHandler)(() => { this.showNotice("An unhandled error occurred. Please check the console for more information."); })); await this.loadSettings(); const pluginSettingsTab = this.createPluginSettingsTab(); if (pluginSettingsTab) { this.addSettingTab(pluginSettingsTab); } const abortController = new AbortController(); this._abortSignal = abortController.signal; this.register(() => { abortController.abort(); }); await this.onloadComplete(); this.app.workspace.onLayoutReady(this.onLayoutReady.bind(this)); } /** * Saves the new plugin settings. * * @param newSettings - The new settings to save. * @returns A promise that resolves when the settings are saved. */ async saveSettings(newSettings) { this._settings = (0, import_PluginSettings.clonePluginSettings)(this.createDefaultPluginSettings.bind(this), newSettings); await this.saveData(this.settings); } /** * Called when the layout is ready. This method can be overridden by subclasses to perform actions once * the layout is ready. * * @returns A promise or void indicating the completion of the layout setup. */ onLayoutReady() { (0, import_Function2.noop)(); } /** * Called when the plugin loading is complete. This method must be implemented by subclasses to perform * any additional setup required after loading is complete. * * @returns A promise or void indicating the completion of the load process. */ onloadComplete() { (0, import_Function2.noop)(); } /** * Parses the provided settings data and returns the parsed `PluginSettings`. * * @param data - The raw data to be parsed into `PluginSettings`. * @returns A promise that resolves to `PluginSettings` or the settings directly. */ parseSettings(data) { return (0, import_PluginSettings.loadPluginSettings)(this.createDefaultPluginSettings.bind(this), data); } /** * Displays a notice message to the user. * * @param message - The message to display. */ showNotice(message) { if (this.notice) { this.notice.hide(); } this.notice = new import_obsidian5.Notice(`${this.manifest.name} ${message}`); } /** * Loads the plugin settings from the saved data. * * @returns A promise that resolves when the settings are loaded. */ async loadSettings() { const data = await this.loadData(); this._settings = await this.parseSettings(data); } }; } }); // node_modules/obsidian-dev-utils/dist/lib/Async.cjs var require_Async = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/Async.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Async_exports = {}; __export2(Async_exports, { addErrorHandler: () => addErrorHandler, asyncFilter: () => asyncFilter, asyncFlatMap: () => asyncFlatMap, asyncMap: () => asyncMap, convertAsyncToSync: () => convertAsyncToSync, convertSyncToAsync: () => convertSyncToAsync, invokeAsyncSafely: () => invokeAsyncSafely, marksAsTerminateRetry: () => marksAsTerminateRetry, retryWithTimeout: () => retryWithTimeout, runWithTimeout: () => runWithTimeout, sleep: () => sleep, timeout: () => timeout, toArray: () => toArray }); module2.exports = __toCommonJS2(Async_exports); var import_Error = require_Error(); async function addErrorHandler(asyncFn) { try { await asyncFn(); } catch (asyncError) { (0, import_Error.emitAsyncErrorEvent)(asyncError); } } async function asyncFilter(arr, predicate) { const predicateResults = await asyncMap(arr, predicate); return arr.filter((_, index) => predicateResults[index]); } async function asyncFlatMap(arr, callback) { return (await asyncMap(arr, callback)).flat(); } async function asyncMap(arr, callback) { return await Promise.all(arr.map(callback)); } function convertAsyncToSync(asyncFunc) { return (...args) => { invokeAsyncSafely(() => asyncFunc(...args)); }; } function convertSyncToAsync(syncFn) { return (...args) => Promise.resolve().then(() => syncFn(...args)); } function invokeAsyncSafely(asyncFn) { void addErrorHandler(asyncFn); } function marksAsTerminateRetry(error) { return Object.assign(error, { __terminateRetry: true }); } async function retryWithTimeout(fn, retryOptions = {}) { const stackTrace = (0, import_Error.getStackTrace)(); const DEFAULT_RETRY_OPTIONS = { retryDelayInMilliseconds: 100, shouldRetryOnError: true, timeoutInMilliseconds: 5e3 }; const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions }; await runWithTimeout(overriddenOptions.timeoutInMilliseconds, async () => { let attempt = 0; for (; ; ) { attempt++; let isSuccess; try { isSuccess = await fn(); } catch (error) { if (!overriddenOptions.shouldRetryOnError || error.__terminateRetry) { throw error; } (0, import_Error.printError)(error); isSuccess = false; } if (isSuccess) { if (attempt > 1) { console.debug(`Retry completed successfully after ${attempt.toString()} attempts`); } return; } console.debug(`Retry attempt ${attempt.toString()} completed unsuccessfully. Trying again in ${overriddenOptions.retryDelayInMilliseconds.toString()} milliseconds`, { fn, stackTrace }); await sleep(overriddenOptions.retryDelayInMilliseconds); } }); } async function runWithTimeout(timeoutInMilliseconds, fn) { let timedOut = false; let result = null; await Promise.race([run(), timeout2()]); if (timedOut) { console.error(`Timed out in ${timeoutInMilliseconds.toString()} milliseconds`, { fn }); throw new Error("Timed out"); } return result; async function run() { result = await fn(); timedOut = false; } async function timeout2() { await sleep(timeoutInMilliseconds); timedOut = true; } } async function sleep(milliseconds) { await new Promise((resolve) => setTimeout(resolve, milliseconds)); } async function timeout(timeoutInMilliseconds) { await sleep(timeoutInMilliseconds); throw new Error(`Timed out in ${timeoutInMilliseconds.toString()} milliseconds`); } async function toArray(iter) { const arr = []; for await (const item of iter) { arr.push(item); } return arr; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/App.cjs var require_App = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/App.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var App_exports = {}; __export2(App_exports, { ValueWrapper: () => ValueWrapper, getApp: () => getApp, getObsidianDevUtilsState: () => getObsidianDevUtilsState }); module2.exports = __toCommonJS2(App_exports); var ValueWrapper = class { constructor(value) { this.value = value; } }; function getApp() { let canRequire; try { globalThis.require.resolve("obsidian/app"); canRequire = true; } catch { canRequire = false; } if (canRequire) { return globalThis.require("obsidian/app"); } const app = globalThis.app; if (app) { return app; } throw new Error("Obsidian app not found"); } function getObsidianDevUtilsState(app, key, defaultValue) { const sharedStateWrapper = app; const sharedState = sharedStateWrapper.obsidianDevUtilsState ??= {}; return sharedState[key] ??= new ValueWrapper(defaultValue); } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Logger.cjs var require_Logger = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Logger.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Logger_exports = {}; __export2(Logger_exports, { invokeAsyncAndLog: () => invokeAsyncAndLog }); module2.exports = __toCommonJS2(Logger_exports); var import_Error = require_Error(); async function invokeAsyncAndLog(title, fn, stackTrace) { const timestampStart = Date.now(); if (stackTrace === void 0) { stackTrace = (0, import_Error.getStackTrace)().split("\n").slice(1).join("\n"); } console.debug(`${title}:start`, { fn, stackTrace, timestampStart }); try { await fn(); const timestampEnd = Date.now(); console.debug(`${title}:end`, { duration: timestampEnd - timestampStart, timestampEnd, timestampStart }); } catch (error) { const timestampEnd = Date.now(); console.debug(`${title}:error`, { duration: timestampEnd - timestampStart, error, timestampEnd: Date.now(), timestampStart }); throw error; } } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Queue.cjs var require_Queue = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Queue.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Queue_exports = {}; __export2(Queue_exports, { addToQueue: () => addToQueue2, addToQueueAndWait: () => addToQueueAndWait, flushQueue: () => flushQueue }); module2.exports = __toCommonJS2(Queue_exports); var import_Async = require_Async(); var import_Error = require_Error(); var import_Function2 = require_Function(); var import_App = require_App(); var import_Logger = require_Logger(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; function addToQueue2(app, fn, timeoutInMilliseconds) { void addToQueueAndWait(app, fn, timeoutInMilliseconds); } async function addToQueueAndWait(app, fn, timeoutInMilliseconds) { const DEFAULT_TIMEOUT_IN_MILLISECONDS = 6e4; timeoutInMilliseconds ??= DEFAULT_TIMEOUT_IN_MILLISECONDS; const stackTrace = (0, import_Error.getStackTrace)(); const queue = getQueue(app).value; queue.items.push({ fn, stackTrace, timeoutInMilliseconds }); queue.promise = queue.promise.then(() => processNextQueueItem(app)); await queue.promise; } async function flushQueue(app) { await addToQueueAndWait(app, import_Function2.noop); } function getQueue(app) { return (0, import_App.getObsidianDevUtilsState)(app, "queue", { items: [], promise: Promise.resolve() }); } async function processNextQueueItem(app) { const queue = getQueue(app).value; const item = queue.items[0]; if (!item) { return; } await (0, import_Async.addErrorHandler)(() => (0, import_Async.runWithTimeout)(item.timeoutInMilliseconds, () => (0, import_Logger.invokeAsyncAndLog)(processNextQueueItem.name, item.fn, item.stackTrace))); queue.items.shift(); } } }); // node_modules/monkey-around/dist/index.cjs var require_dist = __commonJS({ "node_modules/monkey-around/dist/index.cjs"(exports2) { "use strict"; function around(obj, factories) { const removers = Object.keys(factories).map((key) => around1(obj, key, factories[key])); return removers.length === 1 ? removers[0] : function() { removers.forEach((r) => r()); }; } function around1(obj, method, createWrapper) { const inherited = obj[method], hadOwn = obj.hasOwnProperty(method), original = hadOwn ? inherited : function() { return Object.getPrototypeOf(obj)[method].apply(this, arguments); }; let current = createWrapper(original); if (inherited) Object.setPrototypeOf(current, inherited); Object.setPrototypeOf(wrapper, current); obj[method] = wrapper; return remove; function wrapper(...args) { if (current === original && obj[method] === wrapper) remove(); return current.apply(this, args); } function remove() { if (obj[method] === wrapper) { if (hadOwn) obj[method] = original; else delete obj[method]; } if (current === original) return; current = original; Object.setPrototypeOf(wrapper, inherited || Function); } } function dedupe(key, oldFn, newFn) { check[key] = key; return check; function check(...args) { return (oldFn[key] === key ? oldFn : newFn).apply(this, args); } } function after(promise, cb) { return promise.then(cb, cb); } function serialize(asyncFunction) { let lastRun = Promise.resolve(); function wrapper(...args) { return lastRun = new Promise((res, rej) => { after(lastRun, () => { asyncFunction.apply(this, args).then(res, rej); }); }); } wrapper.after = function() { return lastRun = new Promise((res, rej) => { after(lastRun, res); }); }; return wrapper; } exports2.after = after; exports2.around = around; exports2.dedupe = dedupe; exports2.serialize = serialize; } }); // node_modules/obsidian-dev-utils/dist/lib/Object.cjs var require_Object = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/Object.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Object_exports = {}; __export2(Object_exports, { assignWithNonEnumerableProperties: () => assignWithNonEnumerableProperties, cloneWithNonEnumerableProperties: () => cloneWithNonEnumerableProperties, deepEqual: () => deepEqual, getNestedPropertyValue: () => getNestedPropertyValue, getPrototypeOf: () => getPrototypeOf, nameof: () => nameof, setNestedPropertyValue: () => setNestedPropertyValue, toJson: () => toJson }); module2.exports = __toCommonJS2(Object_exports); var import_Error = require_Error(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; function assignWithNonEnumerableProperties(target, ...sources) { return _assignWithNonEnumerableProperties(target, ...sources); } function cloneWithNonEnumerableProperties(obj) { return Object.create(getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); } function deepEqual(a, b) { if (a === b) { return true; } if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) { return false; } const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) { return false; } const aRecord = a; const bRecord = b; for (const key of keysA) { if (!keysB.includes(key) || !deepEqual(aRecord[key], bRecord[key])) { return false; } } return true; } function getNestedPropertyValue(obj, path) { let node = obj; const keys = path.split("."); for (const key of keys) { if (node === void 0) { return void 0; } node = node[key]; } return node; } function getPrototypeOf(instance) { if (instance === void 0 || instance === null) { return instance; } return Object.getPrototypeOf(instance); } function nameof(name) { return name; } function setNestedPropertyValue(obj, path, value) { const error = new Error(`Property path ${path} not found`); let node = obj; const keys = path.split("."); for (const key of keys.slice(0, -1)) { if (node === void 0) { throw error; } node = node[key]; } const lastKey = keys.at(-1); if (node === void 0 || lastKey === void 0) { throw error; } node[lastKey] = value; } function toJson(value, options = {}) { const { shouldHandleFunctions = false, space = 2 } = options; if (!shouldHandleFunctions) { return JSON.stringify(value, null, space); } const functionTexts = []; const replacer = (_, value2) => { if (typeof value2 === "function") { const index = functionTexts.length; functionTexts.push(value2.toString()); return `__FUNCTION_${index.toString()}`; } return value2; }; let json = JSON.stringify(value, replacer, space); json = json.replaceAll(/"__FUNCTION_(\d+)"/g, (_, indexStr) => functionTexts[parseInt(indexStr)] ?? (0, import_Error.throwExpression)(new Error(`Function with index ${indexStr} not found`))); return json; } function _assignWithNonEnumerableProperties(target, ...sources) { for (const source of sources) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } const sourcePrototypes = sources.map((source) => getPrototypeOf(source)).filter((proto) => !!proto); if (sourcePrototypes.length > 0) { const targetPrototype = _assignWithNonEnumerableProperties({}, getPrototypeOf(target), ...sourcePrototypes); Object.setPrototypeOf(target, targetPrototype); } return target; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/AttachmentPath.cjs var require_AttachmentPath = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/AttachmentPath.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var AttachmentPath_exports = {}; __export2(AttachmentPath_exports, { getAttachmentFilePath: () => getAttachmentFilePath2, getAttachmentFolderPath: () => getAttachmentFolderPath, getAvailablePathForAttachments: () => getAvailablePathForAttachments, hasOwnAttachmentFolder: () => hasOwnAttachmentFolder }); module2.exports = __toCommonJS2(AttachmentPath_exports); var import_implementations = require_implementations(); var import_Path4 = require_Path(); var import_String = require_String(); var import_FileSystem4 = require_FileSystem(); async function getAttachmentFilePath2(app, attachmentPathOrFile, notePathOrFile) { const attachmentPath = (0, import_FileSystem4.getPath)(attachmentPathOrFile); const notePath = (0, import_FileSystem4.getPath)(notePathOrFile); const note = (0, import_FileSystem4.getFile)(app, notePath, true); const ext = (0, import_Path4.extname)(attachmentPath); const fileName = (0, import_Path4.basename)(attachmentPath, ext); const internalFn = app.vault.getAvailablePathForAttachments; if (internalFn.isExtended) { return internalFn(fileName, ext.slice(1), note, true); } return await getAvailablePathForAttachments(app, fileName, ext.slice(1), note, true); } async function getAttachmentFolderPath(app, notePathOrFile) { return (0, import_implementations.parentFolderPath)(await getAttachmentFilePath2(app, "DUMMY_FILE.pdf", notePathOrFile)); } async function getAvailablePathForAttachments(app, filename, extension, file, skipFolderCreation) { let attachmentFolderPath = app.vault.getConfig("attachmentFolderPath"); const isCurrentFolder = attachmentFolderPath === "." || attachmentFolderPath === "./"; let relativePath = null; if (attachmentFolderPath.startsWith("./")) { relativePath = (0, import_String.trimStart)(attachmentFolderPath, "./"); } if (isCurrentFolder) { attachmentFolderPath = file ? file.parent?.path ?? "" : ""; } else if (relativePath) { attachmentFolderPath = (file ? file.parent?.getParentPrefix() ?? "" : "") + relativePath; } attachmentFolderPath = (0, import_String.normalize)(normalizeSlashes(attachmentFolderPath)); filename = (0, import_String.normalize)(normalizeSlashes(filename)); let folder = (0, import_FileSystem4.getFolderOrNull)(app, attachmentFolderPath, true); if (!folder && relativePath) { if (!skipFolderCreation) { folder = await app.vault.createFolder(attachmentFolderPath); } else { folder = (0, import_FileSystem4.getFolder)(app, attachmentFolderPath, true); } } const prefix = folder?.getParentPrefix() ?? ""; return app.vault.getAvailablePath(prefix + filename, extension); } async function hasOwnAttachmentFolder(app, path) { const attachmentFolderPath = await getAttachmentFolderPath(app, path); const dummyAttachmentFolderPath = await getAttachmentFolderPath(app, (0, import_Path4.join)((0, import_Path4.dirname)(path), "DUMMY_FILE.md")); return attachmentFolderPath !== dummyAttachmentFolderPath; } function normalizeSlashes(path) { path = path.replace(/([\\/])+/g, "/"); path = path.replace(/(^\/+|\/+$)/g, ""); return path || "/"; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/FrontMatter.cjs var require_FrontMatter = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/FrontMatter.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var FrontMatter_exports = {}; __export2(FrontMatter_exports, { parseFrontMatter: () => parseFrontMatter, setFrontMatter: () => setFrontMatter }); module2.exports = __toCommonJS2(FrontMatter_exports); var import_obsidian5 = require("obsidian"); var import_String = require_String(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; function parseFrontMatter(content) { const frontMatterInfo = (0, import_obsidian5.getFrontMatterInfo)(content); return (0, import_obsidian5.parseYaml)(frontMatterInfo.frontmatter) ?? {}; } function setFrontMatter(content, newFrontMatter) { const frontMatterInfo = (0, import_obsidian5.getFrontMatterInfo)(content); if (Object.keys(newFrontMatter).length === 0) { return content.slice(frontMatterInfo.contentStart); } const newFrontMatterStr = (0, import_obsidian5.stringifyYaml)(newFrontMatter); return frontMatterInfo.exists ? (0, import_String.insertAt)(content, newFrontMatterStr, frontMatterInfo.from, frontMatterInfo.to) : "---\n" + newFrontMatterStr + "---\n" + content; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Reference.cjs var require_Reference = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Reference.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Reference_exports = {}; __export2(Reference_exports, { referenceToFileChange: () => referenceToFileChange2, sortReferences: () => sortReferences }); module2.exports = __toCommonJS2(Reference_exports); var import_implementations = require_implementations(); function referenceToFileChange2(reference, newContent) { if ((0, import_implementations.isReferenceCache)(reference)) { return { endIndex: reference.position.end.offset, newContent, oldContent: reference.original, startIndex: reference.position.start.offset }; } else if ((0, import_implementations.isFrontmatterLinkCache)(reference)) { return { frontMatterKey: reference.key, newContent, oldContent: reference.original }; } throw new Error("Unknown link type"); } function sortReferences(references) { return references.sort((a, b) => { if ((0, import_implementations.isFrontmatterLinkCache)(a) && (0, import_implementations.isFrontmatterLinkCache)(b)) { return a.key.localeCompare(b.key); } if ((0, import_implementations.isReferenceCache)(a) && (0, import_implementations.isReferenceCache)(b)) { return a.position.start.offset - b.position.start.offset; } return (0, import_implementations.isFrontmatterLinkCache)(a) ? 1 : -1; }); } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/MetadataCache.cjs var require_MetadataCache = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/MetadataCache.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var MetadataCache_exports = {}; __export2(MetadataCache_exports, { ensureMetadataCacheReady: () => ensureMetadataCacheReady, getAllLinks: () => getAllLinks3, getBacklinksForFileOrPath: () => getBacklinksForFileOrPath, getBacklinksForFileSafe: () => getBacklinksForFileSafe2, getBacklinksMap: () => getBacklinksMap, getCacheSafe: () => getCacheSafe3, getFrontMatterSafe: () => getFrontMatterSafe, registerFile: () => registerFile, tempRegisterFileAndRun: () => tempRegisterFileAndRun }); module2.exports = __toCommonJS2(MetadataCache_exports); var import_obsidian5 = require("obsidian"); var import_implementations = require_implementations(); var import_Async = require_Async(); var import_Function2 = require_Function(); var import_Object = require_Object(); var import_FileSystem4 = require_FileSystem(); var import_FrontMatter = require_FrontMatter(); var import_Reference2 = require_Reference(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; async function ensureMetadataCacheReady(app) { for (const [path, cache] of Object.entries(app.metadataCache.fileCache)) { if (!cache.hash) { continue; } if (app.metadataCache.metadataCache[cache.hash]) { continue; } await getCacheSafe3(app, path); } } function getAllLinks3(cache) { let links = []; if (cache.links) { links.push(...cache.links); } if (cache.embeds) { links.push(...cache.embeds); } if (cache.frontmatterLinks) { links.push(...cache.frontmatterLinks); } (0, import_Reference2.sortReferences)(links); links = links.filter((link, index) => { if (index === 0) { return true; } const previousLink = links[index - 1]; if (!previousLink) { return true; } if ((0, import_implementations.isReferenceCache)(link) && (0, import_implementations.isReferenceCache)(previousLink)) { return link.position.start.offset !== previousLink.position.start.offset; } if ((0, import_implementations.isFrontmatterLinkCache)(link) && (0, import_implementations.isFrontmatterLinkCache)(previousLink)) { return link.key !== previousLink.key; } return true; }); return links; } function getBacklinksForFileOrPath(app, pathOrFile) { const file = (0, import_FileSystem4.getFile)(app, pathOrFile, true); return tempRegisterFileAndRun(app, file, () => app.metadataCache.getBacklinksForFile(file)); } async function getBacklinksForFileSafe2(app, pathOrFile, retryOptions = {}) { const safeOverload = app.metadataCache.getBacklinksForFile.safe; if (safeOverload) { return safeOverload(pathOrFile); } const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 }; const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions }; let backlinks = null; await (0, import_Async.retryWithTimeout)(async () => { const file = (0, import_FileSystem4.getFile)(app, pathOrFile); await ensureMetadataCacheReady(app); backlinks = getBacklinksForFileOrPath(app, file); for (const notePath of backlinks.keys()) { const note = (0, import_FileSystem4.getFileOrNull)(app, notePath); if (!note) { return false; } await saveNote(app, note); const content = await app.vault.read(note); const frontMatter = (0, import_FrontMatter.parseFrontMatter)(content); const links = backlinks.get(notePath); if (!links) { return false; } for (const link of links) { let actualLink; if ((0, import_implementations.isReferenceCache)(link)) { actualLink = content.slice(link.position.start.offset, link.position.end.offset); } else if ((0, import_implementations.isFrontmatterLinkCache)(link)) { const linkValue = (0, import_Object.getNestedPropertyValue)(frontMatter, link.key); if (typeof linkValue !== "string") { return false; } actualLink = linkValue; } else { return true; } if (actualLink !== link.original) { return false; } } } return true; }, overriddenOptions); return backlinks; } async function getBacklinksMap(app, pathOrFiles, retryOptions = {}) { const map = /* @__PURE__ */ new Map(); for (const pathOrFile of pathOrFiles) { const customArrayDict = await getBacklinksForFileSafe2(app, pathOrFile, retryOptions); for (const path of customArrayDict.keys()) { const mapLinks = map.get(path) ?? []; const pathLinks = customArrayDict.get(path) ?? []; mapLinks.push(...pathLinks); map.set(path, mapLinks); } } return map; } async function getCacheSafe3(app, fileOrPath, retryOptions = {}) { const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 }; const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions }; let cache = null; await (0, import_Async.retryWithTimeout)(async () => { const file = (0, import_FileSystem4.getFileOrNull)(app, fileOrPath); if (!file || file.deleted) { cache = null; return true; } await saveNote(app, file); const fileInfo = app.metadataCache.getFileInfo(file.path); const stat = await app.vault.adapter.stat(file.path); if (!fileInfo) { console.debug(`File cache info for ${file.path} is missing`); return false; } else if (!stat) { console.debug(`File stat for ${file.path} is missing`); return false; } else if (file.stat.mtime < stat.mtime) { app.vault.onChange("modified", file.path, void 0, stat); console.debug(`Cached timestamp for ${file.path} is from ${new Date(file.stat.mtime).toString()} which is older than the file system modification timestamp ${new Date(stat.mtime).toString()}`); return false; } else if (fileInfo.mtime < stat.mtime) { console.debug(`File cache info for ${file.path} is from ${new Date(fileInfo.mtime).toString()} which is older than the file modification timestamp ${new Date(stat.mtime).toString()}`); return false; } else { cache = app.metadataCache.getFileCache(file); if (!cache) { console.debug(`File cache for ${file.path} is missing`); return false; } else { return true; } } }, overriddenOptions); return cache; } async function getFrontMatterSafe(app, pathOrFile) { const cache = await getCacheSafe3(app, pathOrFile); return cache?.frontmatter ?? {}; } function registerFile(app, file) { if (!file.deleted) { return import_Function2.noop; } const deletedPaths = []; let deletedFile = file; while (deletedFile.deleted) { deletedPaths.push(deletedFile.path); app.vault.fileMap[deletedFile.path] = deletedFile; deletedFile = deletedFile.parent ?? (0, import_FileSystem4.getFolder)(app, (0, import_implementations.parentFolderPath)(deletedFile.path), true); } if ((0, import_FileSystem4.isFile)(file)) { app.metadataCache.uniqueFileLookup.add(file.name.toLowerCase(), file); } return () => { for (const path of deletedPaths) { delete app.vault.fileMap[path]; } if ((0, import_FileSystem4.isFile)(file)) { app.metadataCache.uniqueFileLookup.remove(file.name.toLowerCase(), file); } }; } function tempRegisterFileAndRun(app, file, fn) { const unregister = registerFile(app, file); try { return fn(); } finally { unregister(); } } async function saveNote(app, pathOrFile) { if (!(0, import_FileSystem4.isMarkdownFile)(pathOrFile)) { return; } const path = (0, import_FileSystem4.getPath)(pathOrFile); for (const leaf of app.workspace.getLeavesOfType("markdown")) { if (leaf.view instanceof import_obsidian5.MarkdownView && leaf.view.file?.path === path) { await leaf.view.save(); } } } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Vault.cjs var require_Vault = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Vault.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Vault_exports = {}; __export2(Vault_exports, { copySafe: () => copySafe2, createFolderSafe: () => createFolderSafe3, createTempFile: () => createTempFile, createTempFolder: () => createTempFolder, deleteEmptyFolderHierarchy: () => deleteEmptyFolderHierarchy2, deleteSafe: () => deleteSafe, getAvailablePath: () => getAvailablePath2, getMarkdownFilesSorted: () => getMarkdownFilesSorted2, getNoteFilesSorted: () => getNoteFilesSorted, getSafeRenamePath: () => getSafeRenamePath, isEmptyFolder: () => isEmptyFolder, listSafe: () => listSafe2, process: () => process2, renameSafe: () => renameSafe2 }); module2.exports = __toCommonJS2(Vault_exports); var import_obsidian5 = require("obsidian"); var import_implementations = require_implementations(); var import_Async = require_Async(); var import_Error = require_Error(); var import_Function2 = require_Function(); var import_Path4 = require_Path(); var import_ValueProvider = require_ValueProvider(); var import_FileSystem4 = require_FileSystem(); var import_MetadataCache3 = require_MetadataCache(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; async function copySafe2(app, oldPathOrFile, newPath) { const file = (0, import_FileSystem4.getFile)(app, oldPathOrFile); const newFolderPath = (0, import_implementations.parentFolderPath)(newPath); await createFolderSafe3(app, newFolderPath); const newAvailablePath = getAvailablePath2(app, newPath); try { await app.vault.copy(file, newAvailablePath); } catch (e) { if (!await app.vault.exists(newAvailablePath)) { throw e; } } return newAvailablePath; } async function createFolderSafe3(app, path) { if (await app.vault.adapter.exists(path)) { return false; } try { await app.vault.createFolder(path); return true; } catch (e) { if (!await app.vault.exists(path)) { throw e; } return true; } } async function createTempFile(app, path) { let file = (0, import_FileSystem4.getFileOrNull)(app, path); if (file) { return import_Function2.noopAsync; } const folderCleanup = await createTempFolder(app, (0, import_implementations.parentFolderPath)(path)); try { await app.vault.create(path, ""); } catch (e) { if (!await app.vault.exists(path)) { throw e; } } file = (0, import_FileSystem4.getFile)(app, path); return async () => { if (!file.deleted) { await app.fileManager.trashFile(file); } await folderCleanup(); }; } async function createTempFolder(app, path) { let folder = (0, import_FileSystem4.getFolderOrNull)(app, path); if (folder) { return import_Function2.noopAsync; } const dirPath = (0, import_implementations.parentFolderPath)(path); await createTempFolder(app, dirPath); const folderCleanup = await createTempFolder(app, (0, import_implementations.parentFolderPath)(path)); await createFolderSafe3(app, path); folder = (0, import_FileSystem4.getFolder)(app, path); return async () => { if (!folder.deleted) { await app.fileManager.trashFile(folder); } await folderCleanup(); }; } async function deleteEmptyFolderHierarchy2(app, pathOrFolder) { let folder = (0, import_FileSystem4.getFolderOrNull)(app, pathOrFolder); while (folder) { if (!await isEmptyFolder(app, folder)) { return; } const parent = folder.parent; await deleteSafe(app, folder.path); folder = parent; } } async function deleteSafe(app, pathOrFile, deletedNotePath, shouldReportUsedAttachments, shouldDeleteEmptyFolders) { const file = (0, import_FileSystem4.getAbstractFileOrNull)(app, pathOrFile); if (!file) { return false; } let canDelete = (0, import_FileSystem4.isFile)(file) || (shouldDeleteEmptyFolders ?? true); if ((0, import_FileSystem4.isFile)(file)) { const backlinks = await (0, import_MetadataCache3.getBacklinksForFileSafe)(app, file); if (deletedNotePath) { backlinks.clear(deletedNotePath); } if (backlinks.count() !== 0) { if (shouldReportUsedAttachments) { new import_obsidian5.Notice(`Attachment ${file.path} is still used by other notes. It will not be deleted.`); } canDelete = false; } } else if ((0, import_FileSystem4.isFolder)(file)) { const listedFiles = await listSafe2(app, file); for (const child of [...listedFiles.files, ...listedFiles.folders]) { canDelete &&= await deleteSafe(app, child, deletedNotePath, shouldReportUsedAttachments); } canDelete &&= await isEmptyFolder(app, file); } if (canDelete) { try { await app.fileManager.trashFile(file); } catch (e) { if (await app.vault.exists(file.path)) { (0, import_Error.printError)(new Error(`Failed to delete ${file.path}`, { cause: e })); canDelete = false; } } } return canDelete; } function getAvailablePath2(app, path) { const ext = (0, import_Path4.extname)(path); return app.vault.getAvailablePath((0, import_Path4.join)((0, import_Path4.dirname)(path), (0, import_Path4.basename)(path, ext)), ext.slice(1)); } function getMarkdownFilesSorted2(app) { return app.vault.getMarkdownFiles().sort((a, b) => a.path.localeCompare(b.path)); } function getNoteFilesSorted(app) { return app.vault.getAllLoadedFiles().filter((file) => (0, import_FileSystem4.isFile)(file) && (0, import_FileSystem4.isNote)(file)).sort((a, b) => a.path.localeCompare(b.path)); } function getSafeRenamePath(app, oldPathOrFile, newPath) { const oldPath = (0, import_FileSystem4.getPath)(oldPathOrFile); if (app.vault.adapter.insensitive) { let folderPath = (0, import_Path4.dirname)(newPath); let nonExistingPath = (0, import_Path4.basename)(newPath); let folder = null; for (; ; ) { folder = (0, import_FileSystem4.getFolderOrNull)(app, folderPath, true); if (folder) { break; } nonExistingPath = (0, import_Path4.join)((0, import_Path4.basename)(folderPath), nonExistingPath); folderPath = (0, import_Path4.dirname)(folderPath); } newPath = (0, import_Path4.join)(folder.getParentPrefix(), nonExistingPath); } if (oldPath.toLowerCase() === newPath.toLowerCase()) { return newPath; } return getAvailablePath2(app, newPath); } async function isEmptyFolder(app, pathOrFolder) { const listedFiles = await listSafe2(app, (0, import_FileSystem4.getPath)(pathOrFolder)); return listedFiles.files.length === 0 && listedFiles.folders.length === 0; } async function listSafe2(app, pathOrFolder) { const path = (0, import_FileSystem4.getPath)(pathOrFolder); const EMPTY = { files: [], folders: [] }; if ((await app.vault.adapter.stat(path))?.type !== "folder") { return EMPTY; } try { return await app.vault.adapter.list(path); } catch (e) { if (await app.vault.exists(path)) { throw e; } return EMPTY; } } async function process2(app, pathOrFile, newContentProvider, retryOptions = {}) { const file = (0, import_FileSystem4.getFile)(app, pathOrFile); const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 }; const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions }; await (0, import_Async.retryWithTimeout)(async () => { if (file.deleted) { throw (0, import_Async.marksAsTerminateRetry)(new Error(`File ${file.path} is deleted`)); } const oldContent = await app.vault.read(file); const newContent = await (0, import_ValueProvider.resolveValue)(newContentProvider, oldContent); if (newContent === null) { return false; } let success = true; await app.vault.process(file, (content) => { if (content !== oldContent) { console.warn("Content has changed since it was read. Retrying...", { actualContent: content, expectedContent: oldContent, path: file.path }); success = false; return content; } return newContent; }); return success; }, overriddenOptions); } async function renameSafe2(app, oldPathOrFile, newPath) { const oldFile = (0, import_FileSystem4.getFile)(app, oldPathOrFile, false, true); const newAvailablePath = getSafeRenamePath(app, oldPathOrFile, newPath); if (oldFile.path.toLowerCase() === newAvailablePath.toLowerCase()) { if (oldFile.path !== newPath) { await app.vault.rename(oldFile, newAvailablePath); } return newAvailablePath; } const newFolderPath = (0, import_implementations.parentFolderPath)(newAvailablePath); await createFolderSafe3(app, newFolderPath); try { await app.vault.rename(oldFile, newAvailablePath); } catch (e) { if (!await app.vault.exists(newAvailablePath) || await app.vault.exists(oldFile.path)) { throw e; } } return newAvailablePath; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/FileChange.cjs var require_FileChange = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/FileChange.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var FileChange_exports = {}; __export2(FileChange_exports, { applyFileChanges: () => applyFileChanges2, isContentChange: () => isContentChange, isFrontmatterChange: () => isFrontmatterChange }); module2.exports = __toCommonJS2(FileChange_exports); var import_Object = require_Object(); var import_ValueProvider = require_ValueProvider(); var import_FileSystem4 = require_FileSystem(); var import_FrontMatter = require_FrontMatter(); var import_Vault3 = require_Vault(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; async function applyFileChanges2(app, pathOrFile, changesProvider, retryOptions = {}) { const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 }; const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions }; await (0, import_Vault3.process)(app, pathOrFile, async (content) => { let changes = await (0, import_ValueProvider.resolveValue)(changesProvider); const frontMatter = (0, import_FrontMatter.parseFrontMatter)(content); for (const change of changes) { if (isContentChange(change)) { const actualContent = content.slice(change.startIndex, change.endIndex); if (actualContent !== change.oldContent) { console.warn("Content mismatch", { actualContent, endIndex: change.endIndex, expectedContent: change.oldContent, path: (0, import_FileSystem4.getPath)(pathOrFile), startIndex: change.startIndex }); return null; } } else if (isFrontmatterChange(change)) { const actualContent = (0, import_Object.getNestedPropertyValue)(frontMatter, change.frontMatterKey); if (actualContent !== change.oldContent) { console.warn("Content mismatch", { actualContent, expectedContent: change.oldContent, frontMatterKey: change.frontMatterKey, path: (0, import_FileSystem4.getPath)(pathOrFile) }); return null; } } } changes.sort((a, b) => { if (isContentChange(a) && isContentChange(b)) { return a.startIndex - b.startIndex; } if (isFrontmatterChange(a) && isFrontmatterChange(b)) { return a.frontMatterKey.localeCompare(b.frontMatterKey); } return isContentChange(a) ? -1 : 1; }); changes = changes.filter((change, index) => { if (change.oldContent === change.newContent) { return false; } if (index === 0) { return true; } return !(0, import_Object.deepEqual)(change, changes[index - 1]); }); for (let i = 1; i < changes.length; i++) { const change = changes[i]; if (!change) { continue; } const previousChange = changes[i - 1]; if (!previousChange) { continue; } if (isContentChange(previousChange) && isContentChange(change) && previousChange.endIndex && change.startIndex && previousChange.endIndex > change.startIndex) { console.warn("Overlapping changes", { change, previousChange }); return null; } } let newContent = ""; let lastIndex = 0; let frontMatterChanged = false; for (const change of changes) { if (isContentChange(change)) { newContent += content.slice(lastIndex, change.startIndex); newContent += change.newContent; lastIndex = change.endIndex; } else if (isFrontmatterChange(change)) { (0, import_Object.setNestedPropertyValue)(frontMatter, change.frontMatterKey, change.newContent); frontMatterChanged = true; } } newContent += content.slice(lastIndex); if (frontMatterChanged) { newContent = (0, import_FrontMatter.setFrontMatter)(newContent, frontMatter); } return newContent; }, overriddenOptions); } function isContentChange(fileChange) { return fileChange.startIndex !== void 0; } function isFrontmatterChange(fileChange) { return fileChange.frontMatterKey !== void 0; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/ObsidianSettings.cjs var require_ObsidianSettings = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/ObsidianSettings.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var ObsidianSettings_exports = {}; __export2(ObsidianSettings_exports, { shouldUseRelativeLinks: () => shouldUseRelativeLinks, shouldUseWikilinks: () => shouldUseWikilinks }); module2.exports = __toCommonJS2(ObsidianSettings_exports); function shouldUseRelativeLinks(app) { return app.vault.getConfig("newLinkFormat") === "relative"; } function shouldUseWikilinks(app) { return !app.vault.getConfig("useMarkdownLinks"); } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Link.cjs var require_Link = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Link.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var Link_exports = {}; __export2(Link_exports, { convertLink: () => convertLink, editBacklinks: () => editBacklinks, editLinks: () => editLinks, extractLinkFile: () => extractLinkFile3, generateMarkdownLink: () => generateMarkdownLink2, shouldResetAlias: () => shouldResetAlias, splitSubpath: () => splitSubpath3, testAngleBrackets: () => testAngleBrackets, testEmbed: () => testEmbed2, testLeadingDot: () => testLeadingDot, testWikilink: () => testWikilink2, updateLink: () => updateLink, updateLinksInFile: () => updateLinksInFile2 }); module2.exports = __toCommonJS2(Link_exports); var import_obsidian5 = require("obsidian"); var import_Object = require_Object(); var import_Path4 = require_Path(); var import_String = require_String(); var import_FileChange2 = require_FileChange(); var import_FileSystem4 = require_FileSystem(); var import_MetadataCache3 = require_MetadataCache(); var import_ObsidianSettings = require_ObsidianSettings(); var import_Reference2 = require_Reference(); var SPECIAL_LINK_SYMBOLS_REGEXP = /[\\\x00\x08\x0B\x0C\x0E-\x1F ]/g; var SPECIAL_MARKDOWN_LINK_SYMBOLS_REGEX = /[\\[\]<>_*~=`$]/g; function convertLink(options) { return updateLink({ app: options.app, forceMarkdownLinks: options.forceMarkdownLinks, link: options.link, oldPathOrFile: options.oldPathOrFile, pathOrFile: extractLinkFile3(options.app, options.link, options.sourcePathOrFile), renameMap: options.renameMap, shouldUpdateFilenameAlias: options.shouldUpdateFilenameAlias, sourcePathOrFile: options.sourcePathOrFile }); } async function editBacklinks(app, pathOrFile, linkConverter, retryOptions = {}) { const backlinks = await (0, import_MetadataCache3.getBacklinksForFileSafe)(app, pathOrFile, retryOptions); for (const backlinkNotePath of backlinks.keys()) { const currentLinks = backlinks.get(backlinkNotePath) ?? []; const linkJsons = new Set(currentLinks.map((link) => (0, import_Object.toJson)(link))); await editLinks(app, backlinkNotePath, (link) => { const linkJson = (0, import_Object.toJson)(link); if (!linkJsons.has(linkJson)) { return; } return linkConverter(link); }, retryOptions); } } async function editLinks(app, pathOrFile, linkConverter, retryOptions = {}) { await (0, import_FileChange2.applyFileChanges)(app, pathOrFile, async () => { const cache = await (0, import_MetadataCache3.getCacheSafe)(app, pathOrFile); if (!cache) { return []; } const changes = []; for (const link of (0, import_MetadataCache3.getAllLinks)(cache)) { const newContent = await linkConverter(link); if (newContent === void 0) { continue; } changes.push((0, import_Reference2.referenceToFileChange)(link, newContent)); } return changes; }, retryOptions); } function extractLinkFile3(app, link, notePathOrFile) { const { linkPath } = splitSubpath3(link.link); return app.metadataCache.getFirstLinkpathDest(linkPath, (0, import_FileSystem4.getPath)(notePathOrFile)); } function generateMarkdownLink2(options) { const { app } = options; const configurableDefaultOptionsFn = app.fileManager.generateMarkdownLink.defaultOptionsFn ?? (() => ({})); const configurableDefaultOptions = configurableDefaultOptionsFn(); const DEFAULT_OPTIONS = { allowEmptyEmbedAlias: true }; options = { ...DEFAULT_OPTIONS, ...configurableDefaultOptions, ...options }; const file = (0, import_FileSystem4.getFile)(app, options.pathOrFile, options.allowNonExistingFile); return (0, import_MetadataCache3.tempRegisterFileAndRun)(app, file, () => { const sourcePath = (0, import_FileSystem4.getPath)(options.sourcePathOrFile); const subpath = options.subpath ?? ""; let alias = options.alias ?? ""; const isEmbed = options.isEmbed ?? (options.originalLink ? testEmbed2(options.originalLink) : void 0) ?? !(0, import_FileSystem4.isMarkdownFile)(file); const isWikilink = options.isWikilink ?? (options.originalLink ? testWikilink2(options.originalLink) : void 0) ?? (0, import_ObsidianSettings.shouldUseWikilinks)(app); const forceRelativePath = options.forceRelativePath ?? (0, import_ObsidianSettings.shouldUseRelativeLinks)(app); const useLeadingDot = options.useLeadingDot ?? (options.originalLink ? testLeadingDot(options.originalLink) : void 0) ?? false; const useAngleBrackets = options.useAngleBrackets ?? (options.originalLink ? testAngleBrackets(options.originalLink) : void 0) ?? false; let linkText = file.path === sourcePath && subpath ? subpath : forceRelativePath ? (0, import_Path4.relative)((0, import_Path4.dirname)(sourcePath), isWikilink ? (0, import_FileSystem4.trimMarkdownExtension)(file) : file.path) + subpath : app.metadataCache.fileToLinktext(file, sourcePath, isWikilink) + subpath; if (forceRelativePath && useLeadingDot && !linkText.startsWith(".") && !linkText.startsWith("#")) { linkText = "./" + linkText; } const embedPrefix = isEmbed ? "!" : ""; if (!isWikilink) { if (useAngleBrackets) { linkText = `<${linkText}>`; } else { linkText = linkText.replace(SPECIAL_LINK_SYMBOLS_REGEXP, function(specialLinkSymbol) { return encodeURIComponent(specialLinkSymbol); }); } if (!alias && (!isEmbed || !options.allowEmptyEmbedAlias)) { alias = !options.includeAttachmentExtensionToEmbedAlias || (0, import_FileSystem4.isMarkdownFile)(file) ? file.basename : file.name; } alias = alias.replace(SPECIAL_MARKDOWN_LINK_SYMBOLS_REGEX, "\\$&"); return `${embedPrefix}[${alias}](${linkText})`; } else { if (alias && alias.toLowerCase() === linkText.toLowerCase()) { linkText = alias; alias = ""; } const aliasPart = alias ? `|${alias}` : ""; return `${embedPrefix}[[${linkText}${aliasPart}]]`; } }); } function shouldResetAlias(options) { const { app, displayText, isWikilink, otherPathOrFiles, pathOrFile, sourcePathOrFile } = options; if (isWikilink === false) { return false; } const file = (0, import_FileSystem4.getFile)(app, pathOrFile); if (!displayText) { return true; } const sourcePath = (0, import_FileSystem4.getPath)(sourcePathOrFile); const sourceDir = (0, import_Path4.dirname)(sourcePath); const aliasesToReset = /* @__PURE__ */ new Set(); for (const pathOrFile2 of [file.path, ...otherPathOrFiles]) { if (!pathOrFile2) { continue; } const path = (0, import_FileSystem4.getPath)(pathOrFile2); aliasesToReset.add(path); aliasesToReset.add((0, import_Path4.basename)(path)); aliasesToReset.add((0, import_Path4.relative)(sourceDir, path)); } aliasesToReset.add(app.metadataCache.fileToLinktext(file, sourcePath, false)); const cleanDisplayText = (0, import_obsidian5.normalizePath)(displayText.split(" > ")[0] ?? "").replace(/^\.\//, "").toLowerCase(); for (const alias of aliasesToReset) { if (alias.toLowerCase() === cleanDisplayText) { return true; } const dir = (0, import_Path4.dirname)(alias); const base = (0, import_Path4.basename)(alias, (0, import_Path4.extname)(alias)); if ((0, import_Path4.join)(dir, base).toLowerCase() === cleanDisplayText) { return true; } } return false; } function splitSubpath3(link) { const parsed = (0, import_obsidian5.parseLinktext)((0, import_String.normalize)(link)); return { linkPath: parsed.path, subpath: parsed.subpath }; } function testAngleBrackets(link) { return link.includes("](<"); } function testEmbed2(link) { return link.startsWith("!["); } function testLeadingDot(link) { return link.includes("[[./") || link.includes("](./") || link.includes("](<./"); } function testWikilink2(link) { return link.includes("[["); } function updateLink(options) { const { app, forceMarkdownLinks, link, oldPathOrFile, pathOrFile, renameMap, shouldUpdateFilenameAlias, sourcePathOrFile } = options; if (!pathOrFile) { return link.original; } let file = (0, import_FileSystem4.getFile)(app, pathOrFile); const oldPath = (0, import_FileSystem4.getPath)(oldPathOrFile ?? sourcePathOrFile); const isWikilink = testWikilink2(link.original) && forceMarkdownLinks !== true; const { subpath } = splitSubpath3(link.link); const newPath = renameMap?.get(file.path); let alias = shouldResetAlias({ app, displayText: link.displayText, isWikilink, otherPathOrFiles: [oldPath, newPath], pathOrFile, sourcePathOrFile }) ? void 0 : link.displayText; if (shouldUpdateFilenameAlias ?? true) { if (alias?.toLowerCase() === (0, import_Path4.basename)(oldPath, (0, import_Path4.extname)(oldPath)).toLowerCase()) { alias = file.basename; } else if (alias?.toLowerCase() === (0, import_Path4.basename)(oldPath).toLowerCase()) { alias = file.name; } } if (newPath) { file = (0, import_FileSystem4.getFile)(app, newPath, true); } const newLink = generateMarkdownLink2({ alias, app, isWikilink: forceMarkdownLinks ? false : void 0, originalLink: link.original, pathOrFile: file, sourcePathOrFile, subpath }); return newLink; } async function updateLinksInFile2(options) { const { app, embedOnlyLinks, forceMarkdownLinks, oldPathOrFile, pathOrFile, renameMap, shouldUpdateFilenameAlias } = options; await editLinks(app, pathOrFile, (link) => { const isEmbedLink = testEmbed2(link.original); if (embedOnlyLinks !== void 0 && embedOnlyLinks !== isEmbedLink) { return; } return convertLink({ app, forceMarkdownLinks, link, oldPathOrFile, renameMap, shouldUpdateFilenameAlias, sourcePathOrFile: pathOrFile }); }); } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/RenameDeleteHandler.cjs var require_RenameDeleteHandler = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/RenameDeleteHandler.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var RenameDeleteHandler_exports = {}; __export2(RenameDeleteHandler_exports, { registerRenameDeleteHandlers: () => registerRenameDeleteHandlers2 }); module2.exports = __toCommonJS2(RenameDeleteHandler_exports); var import_monkey_around = require_dist(); var import_obsidian5 = require("obsidian"); var import_Error = require_Error(); var import_Function2 = require_Function(); var import_Object = require_Object(); var import_Path4 = require_Path(); var import_App = require_App(); var import_AttachmentPath2 = require_AttachmentPath(); var import_FileSystem4 = require_FileSystem(); var import_Link3 = require_Link(); var import_MetadataCache3 = require_MetadataCache(); var import_Queue2 = require_Queue(); var import_Vault3 = require_Vault(); var __process2 = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; var deletedMetadataCacheMap = /* @__PURE__ */ new Map(); var handledRenames = /* @__PURE__ */ new Set(); function registerRenameDeleteHandlers2(plugin, settingsBuilder) { const renameDeleteHandlersMap = getRenameDeleteHandlersMap(plugin.app); const pluginId = plugin.manifest.id; renameDeleteHandlersMap.set(pluginId, settingsBuilder); logRegisteredHandlers(plugin.app); plugin.register(() => { renameDeleteHandlersMap.delete(pluginId); logRegisteredHandlers(plugin.app); }); const app = plugin.app; plugin.registerEvent( app.vault.on("delete", (file) => { if (!shouldInvokeHandler(app, pluginId)) { return; } const path = file.path; (0, import_Queue2.addToQueue)(app, () => handleDelete(app, path)); }) ); plugin.registerEvent( app.vault.on("rename", (file, oldPath) => { if (!shouldInvokeHandler(app, pluginId)) { return; } if (!(0, import_FileSystem4.isFile)(file)) { return; } const newPath = file.path; handleRename(app, oldPath, newPath); }) ); plugin.registerEvent( app.metadataCache.on("deleted", (file, prevCache) => { handleMetadataDeleted(app, file, prevCache); }) ); } async function fillRenameMap(app, oldPath, newPath, renameMap) { renameMap.set(oldPath, newPath); if (!(0, import_FileSystem4.isNote)(oldPath)) { return; } const settings = getSettings(app); const oldAttachmentFolderPath = await (0, import_AttachmentPath2.getAttachmentFolderPath)(app, oldPath); const newAttachmentFolderPath = settings.shouldRenameAttachmentFolder ? await (0, import_AttachmentPath2.getAttachmentFolderPath)(app, newPath) : oldAttachmentFolderPath; const oldAttachmentFolder = (0, import_FileSystem4.getFolderOrNull)(app, oldAttachmentFolderPath); if (!oldAttachmentFolder) { return; } if (oldAttachmentFolderPath === newAttachmentFolderPath && !settings.shouldRenameAttachmentFiles) { return; } const oldAttachmentFiles = []; if (!await (0, import_AttachmentPath2.hasOwnAttachmentFolder)(app, oldPath)) { const oldCache = await (0, import_MetadataCache3.getCacheSafe)(app, newPath); if (!oldCache) { return; } for (const oldLink of (0, import_MetadataCache3.getAllLinks)(oldCache)) { const oldAttachmentFile = (0, import_Link3.extractLinkFile)(app, oldLink, oldPath); if (!oldAttachmentFile) { continue; } if (oldAttachmentFile.path.startsWith(oldAttachmentFolderPath)) { const oldAttachmentBacklinks = await (0, import_MetadataCache3.getBacklinksForFileSafe)(app, oldAttachmentFile); if (oldAttachmentBacklinks.keys().length === 1) { oldAttachmentFiles.push(oldAttachmentFile); } } } } else { import_obsidian5.Vault.recurseChildren(oldAttachmentFolder, (oldAttachmentFile) => { if ((0, import_FileSystem4.isFile)(oldAttachmentFile)) { oldAttachmentFiles.push(oldAttachmentFile); } }); } const oldBasename = (0, import_Path4.basename)(oldPath, (0, import_Path4.extname)(oldPath)); const newBasename = (0, import_Path4.basename)(newPath, (0, import_Path4.extname)(newPath)); for (const oldAttachmentFile of oldAttachmentFiles) { if ((0, import_FileSystem4.isNote)(oldAttachmentFile)) { continue; } const relativePath = (0, import_Path4.relative)(oldAttachmentFolderPath, oldAttachmentFile.path); const newDir = (0, import_Path4.join)(newAttachmentFolderPath, (0, import_Path4.dirname)(relativePath)); const newChildBasename = settings.shouldRenameAttachmentFiles ? oldAttachmentFile.basename.replaceAll(oldBasename, newBasename) : oldAttachmentFile.basename; let newChildPath = (0, import_Path4.join)(newDir, (0, import_Path4.makeFileName)(newChildBasename, oldAttachmentFile.extension)); if (oldAttachmentFile.path === newChildPath) { continue; } if (settings.shouldDeleteConflictingAttachments) { const newChildFile = (0, import_FileSystem4.getFileOrNull)(app, newChildPath); if (newChildFile) { await app.fileManager.trashFile(newChildFile); } } else { newChildPath = app.vault.getAvailablePath((0, import_Path4.join)(newDir, newChildBasename), oldAttachmentFile.extension); } renameMap.set(oldAttachmentFile.path, newChildPath); } } function getRenameDeleteHandlersMap(app) { return (0, import_App.getObsidianDevUtilsState)(app, "renameDeleteHandlersMap", /* @__PURE__ */ new Map()).value; } function getSettings(app) { const renameDeleteHandlersMap = getRenameDeleteHandlersMap(app); const settingsBuilders = Array.from(renameDeleteHandlersMap.values()).reverse(); const settings = {}; for (const settingsBuilder of settingsBuilders) { const newSettings = settingsBuilder(); for (const [key, value] of Object.entries(newSettings)) { settings[key] ||= value; } } return settings; } async function handleDelete(app, path) { console.debug(`Handle Delete ${path}`); if (!(0, import_FileSystem4.isNote)(path)) { return; } const settings = getSettings(app); if (!settings.shouldDeleteOrphanAttachments) { return; } const cache = deletedMetadataCacheMap.get(path); deletedMetadataCacheMap.delete(path); if (cache) { const links = (0, import_MetadataCache3.getAllLinks)(cache); for (const link of links) { const attachmentFile = (0, import_Link3.extractLinkFile)(app, link, path); if (!attachmentFile) { continue; } if ((0, import_FileSystem4.isNote)(attachmentFile)) { continue; } await (0, import_Vault3.deleteSafe)(app, attachmentFile, path, settings.shouldDeleteEmptyFolders); } } const attachmentFolderPath = await (0, import_AttachmentPath2.getAttachmentFolderPath)(app, path); const attachmentFolder = (0, import_FileSystem4.getFolderOrNull)(app, attachmentFolderPath); if (!attachmentFolder) { return; } if (!await (0, import_AttachmentPath2.hasOwnAttachmentFolder)(app, path)) { return; } await (0, import_Vault3.deleteSafe)(app, attachmentFolder, path, false, settings.shouldDeleteEmptyFolders); } function handleMetadataDeleted(app, file, prevCache) { const settings = getSettings(app); if (!settings.shouldDeleteOrphanAttachments) { return; } if ((0, import_FileSystem4.isMarkdownFile)(file) && prevCache) { deletedMetadataCacheMap.set(file.path, prevCache); } } function handleRename(app, oldPath, newPath) { const key = makeKey(oldPath, newPath); console.debug(`Handle Rename ${key}`); if (handledRenames.has(key)) { handledRenames.delete(key); return; } const backlinks = (0, import_MetadataCache3.getBacklinksForFileOrPath)(app, oldPath); (0, import_Queue2.addToQueue)(app, () => handleRenameAsync(app, oldPath, newPath, backlinks)); } async function handleRenameAsync(app, oldPath, newPath, backlinks) { if (app.vault.adapter.insensitive && oldPath.toLowerCase() === newPath.toLowerCase()) { const tempPath = (0, import_Path4.join)((0, import_Path4.dirname)(newPath), "__temp__" + (0, import_Path4.basename)(newPath)); await renameHandled(app, newPath, tempPath); await handleRenameAsync(app, oldPath, tempPath, backlinks); await app.vault.rename((0, import_FileSystem4.getFile)(app, tempPath), newPath); return; } const restoreUpdateAllLinks = (0, import_monkey_around.around)(app.fileManager, { updateAllLinks: () => import_Function2.noopAsync }); try { const renameMap = /* @__PURE__ */ new Map(); await fillRenameMap(app, oldPath, newPath, renameMap); const backlinksMap = /* @__PURE__ */ new Map(); initBacklinksMap(backlinks.data, renameMap, backlinksMap, oldPath); for (const attachmentOldPath of renameMap.keys()) { if (attachmentOldPath === oldPath) { continue; } const currentBacklinksMap = await (0, import_MetadataCache3.getBacklinksMap)(app, [attachmentOldPath]); initBacklinksMap(currentBacklinksMap, renameMap, backlinksMap, attachmentOldPath); } const parentFolders = /* @__PURE__ */ new Set(); for (const [oldRelatedPath, newRelatedPath] of renameMap.entries()) { if (oldRelatedPath === oldPath) { continue; } const fixedNewRelatedPath = await renameHandled(app, oldRelatedPath, newRelatedPath); renameMap.set(oldRelatedPath, fixedNewRelatedPath); parentFolders.add((0, import_Path4.dirname)(oldRelatedPath)); } const settings = getSettings(app); if (settings.shouldDeleteEmptyFolders) { for (const parentFolder of parentFolders) { await (0, import_Vault3.deleteEmptyFolderHierarchy)(app, parentFolder); } } for (const [newBacklinkPath, linkJsonToPathMap] of backlinksMap.entries()) { await (0, import_Link3.editLinks)(app, newBacklinkPath, (link) => { const oldRelatedPath = linkJsonToPathMap.get((0, import_Object.toJson)(link)); if (!oldRelatedPath) { return; } const newRelatedPath = renameMap.get(oldRelatedPath); if (!newRelatedPath) { return; } return (0, import_Link3.updateLink)({ app, link, oldPathOrFile: oldRelatedPath, pathOrFile: newRelatedPath, renameMap, shouldUpdateFilenameAlias: settings.shouldUpdateFilenameAliases, sourcePathOrFile: newBacklinkPath }); }); } if ((0, import_FileSystem4.isCanvasFile)(newPath)) { await (0, import_Vault3.process)(app, newPath, (content) => { let canvasData; try { canvasData = JSON.parse(content); } catch (e) { (0, import_Error.printError)(new Error(`Failed to parse canvas data for ${newPath}`, { cause: e })); return content; } for (const node of canvasData.nodes) { if (node.type !== "file") { continue; } const newPath2 = renameMap.get(node.file); if (!newPath2) { continue; } node.file = newPath2; } return (0, import_Object.toJson)(canvasData); }); } else if ((0, import_FileSystem4.isMarkdownFile)(newPath)) { await (0, import_Link3.updateLinksInFile)({ app, oldPathOrFile: oldPath, pathOrFile: newPath, renameMap, shouldUpdateFilenameAlias: settings.shouldUpdateFilenameAliases }); } } finally { restoreUpdateAllLinks(); const orphanKeys = Array.from(handledRenames); (0, import_Queue2.addToQueue)(app, () => { for (const key of orphanKeys) { handledRenames.delete(key); } }); } } function initBacklinksMap(currentBacklinksMap, renameMap, backlinksMap, path) { for (const [backlinkPath, links] of currentBacklinksMap.entries()) { const newBacklinkPath = renameMap.get(backlinkPath) ?? backlinkPath; const linkJsonToPathMap = backlinksMap.get(newBacklinkPath) ?? /* @__PURE__ */ new Map(); backlinksMap.set(newBacklinkPath, linkJsonToPathMap); for (const link of links) { linkJsonToPathMap.set((0, import_Object.toJson)(link), path); } } } function logRegisteredHandlers(app) { const renameDeleteHandlersMap = getRenameDeleteHandlersMap(app); console.debug(`Plugins with registered rename/delete handlers: ${Array.from(renameDeleteHandlersMap.keys()).join(", ")}`); } function makeKey(oldPath, newPath) { return `${oldPath} -> ${newPath}`; } async function renameHandled(app, oldPath, newPath) { newPath = (0, import_Vault3.getSafeRenamePath)(app, oldPath, newPath); if (oldPath === newPath) { return newPath; } const key = makeKey(oldPath, newPath); handledRenames.add(key); newPath = await (0, import_Vault3.renameSafe)(app, oldPath, newPath); return newPath; } function shouldInvokeHandler(app, pluginId) { const renameDeleteHandlerPluginIds = getRenameDeleteHandlersMap(app); const mainPluginId = Array.from(renameDeleteHandlerPluginIds.keys())[0]; if (mainPluginId !== pluginId) { return false; } return true; } } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettingsTabBase.cjs var require_PluginSettingsTabBase = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettingsTabBase.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var PluginSettingsTabBase_exports = {}; __export2(PluginSettingsTabBase_exports, { PluginSettingsTabBase: () => PluginSettingsTabBase2 }); module2.exports = __toCommonJS2(PluginSettingsTabBase_exports); var import_obsidian5 = require("obsidian"); var import_PluginBase2 = require_PluginBase(); var PluginSettingsTabBase2 = class extends import_obsidian5.PluginSettingTab { constructor(plugin) { super(plugin.app, plugin); this.plugin = plugin; } }; } }); // node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/ValueComponent.cjs var require_ValueComponent = __commonJS({ "node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/ValueComponent.cjs"(exports2, module2) { (function patchRequireEsmDefault() { const __require = require; require = Object.assign((id) => { const module22 = __require(id) ?? {}; return module22.__esModule && module22.default ? module22.default : module22; }, __require); })(); var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __export2 = (target, all) => { for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); }; var __copyProps2 = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames2(from)) if (!__hasOwnProp2.call(to, key) && key !== except) __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var ValueComponent_exports = {}; __export2(ValueComponent_exports, { extend: () => extend2 }); module2.exports = __toCommonJS2(ValueComponent_exports); var import_obsidian5 = require("obsidian"); var import_Object = require_Object(); var ValueComponentEx = class { constructor(valueComponent) { this.valueComponent = valueComponent; } /** * Returns the ValueComponent with extended functionality. */ asExtended() { return (0, import_Object.assignWithNonEnumerableProperties)({}, this.valueComponent, this); } /** * Binds the ValueComponent to a property in the plugin settings. * * @typeParam Plugin - The type of the plugin that extends `PluginBase`. * @typeParam Property - The key of the plugin setting that the component is bound to. * @typeParam PluginSettings - The type of the plugin settings object. * @param plugin - The plugin. * @param property - The property key in `PluginSettings` to bind to the UI component. * @param options - Configuration options. * @returns The `ValueComponent` instance that was bound to the property. */ bind(plugin, property, options) { const DEFAULT_OPTIONS = { autoSave: true, componentToPluginSettingsValueConverter: (value) => value, pluginSettingsToComponentValueConverter: (value) => value }; const optionsExt = { ...DEFAULT_OPTIONS, ...options }; const pluginExt = plugin; const pluginSettingsFn = () => optionsExt.pluginSettings ?? pluginExt.settingsCopy; const validate = (uiValue) => { if (!optionsExt.valueValidator) { return true; } uiValue ??= this.valueComponent.getValue(); const errorMessage = optionsExt.valueValidator(uiValue); const validatorElement2 = getValidatorElement(this.valueComponent); if (validatorElement2) { validatorElement2.setCustomValidity(errorMessage ?? ""); validatorElement2.reportValidity(); } return !errorMessage; }; this.valueComponent.setValue(optionsExt.pluginSettingsToComponentValueConverter(pluginSettingsFn()[property])).onChange(async (uiValue) => { if (!validate(uiValue)) { return; } const pluginSettings = pluginSettingsFn(); pluginSettings[property] = optionsExt.componentToPluginSettingsValueConverter(uiValue); if (optionsExt.autoSave) { await pluginExt.saveSettings(pluginSettings); } await optionsExt.onChanged?.(); }); validate(); const validatorElement = getValidatorElement(this.valueComponent); if (validatorElement) { validatorElement.addEventListener("focus", () => validate()); validatorElement.addEventListener("blur", () => validate()); } return this.asExtended(); } }; function extend2(valueComponent) { return new ValueComponentEx(valueComponent).asExtended(); } function getValidatorElement(valueComponent) { if (valueComponent instanceof import_obsidian5.DropdownComponent) { return valueComponent.selectEl; } if (valueComponent instanceof import_obsidian5.SliderComponent) { return valueComponent.sliderEl; } if (valueComponent instanceof import_obsidian5.TextAreaComponent) { return valueComponent.inputEl; } if (valueComponent instanceof import_obsidian5.TextComponent) { return valueComponent.inputEl; } return null; } } }); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => main_default }); module.exports = __toCommonJS(main_exports); // src/ConsistentAttachmentsAndLinksPlugin.ts var import_obsidian4 = require("obsidian"); var import_Function = __toESM(require_Function(), 1); var import_FileSystem3 = __toESM(require_FileSystem(), 1); var import_PluginBase = __toESM(require_PluginBase(), 1); var import_Queue = __toESM(require_Queue(), 1); var import_RenameDeleteHandler = __toESM(require_RenameDeleteHandler(), 1); var import_Vault2 = __toESM(require_Vault(), 1); var import_Path3 = __toESM(require_Path(), 1); // src/ConsistentAttachmentsAndLinksPluginSettings.ts var ConsistentAttachmentsAndLinksPluginSettings = class { autoCollectAttachments = false; changeNoteBacklinksAlt = true; consistencyReportFile = "consistency-report.md"; deleteAttachmentsWithNote = true; deleteEmptyFolders = true; deleteExistFilesWhenMoveNote = true; ignoreFiles = ["consistency\\-report\\.md"]; ignoreFolders = [".git/", ".obsidian/"]; moveAttachmentsWithNote = true; showWarning = true; updateLinks = true; getIgnoreFilesRegex() { return this.ignoreFiles.map((file) => RegExp(file)); } }; // src/ConsistentAttachmentsAndLinksPluginSettingsTab.ts var import_obsidian = require("obsidian"); var import_PluginSettingsTabBase = __toESM(require_PluginSettingsTabBase(), 1); var import_ValueComponent = __toESM(require_ValueComponent(), 1); var ConsistentAttachmentsAndLinksPluginSettingsTab = class extends import_PluginSettingsTabBase.PluginSettingsTabBase { display() { this.containerEl.empty(); new import_obsidian.Setting(this.containerEl).setName("Move Attachments with Note").setDesc("Automatically move attachments when a note is relocated. This includes attachments located in the same folder or any of its subfolders.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "moveAttachmentsWithNote")); new import_obsidian.Setting(this.containerEl).setName("Delete Unused Attachments with Note").setDesc("Automatically remove attachments that are no longer referenced in other notes when the note is deleted.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "deleteAttachmentsWithNote")); new import_obsidian.Setting(this.containerEl).setName("Update Links").setDesc("Automatically update links to attachments and other notes when moving notes or attachments.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "updateLinks")); new import_obsidian.Setting(this.containerEl).setName("Delete Empty Folders").setDesc("Automatically remove empty folders after moving notes with attachments.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "deleteEmptyFolders")); new import_obsidian.Setting(this.containerEl).setName("Delete Duplicate Attachments on Note Move").setDesc("Automatically delete attachments when moving a note if a file with the same name exists in the destination folder. If disabled, the file will be renamed and moved.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "deleteExistFilesWhenMoveNote")); new import_obsidian.Setting(this.containerEl).setName("Update Backlink Text on Note Rename").setDesc("When a note is renamed, its linked references are automatically updated. If this option is enabled, the text of backlinks to this note will also be modified.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "changeNoteBacklinksAlt")); new import_obsidian.Setting(this.containerEl).setName("Ignore Folders").setDesc("Specify a list of folders to ignore. Enter each folder on a new line.").addTextArea( (textArea) => (0, import_ValueComponent.extend)(textArea).bind(this.plugin, "ignoreFolders", { componentToPluginSettingsValueConverter: (value) => value.trim().split("\n").map((value2) => this.getNormalizedPath(value2) + "/"), pluginSettingsToComponentValueConverter: (value) => value.join("\n") }).setPlaceholder("Example: .git, .obsidian") ); new import_obsidian.Setting(this.containerEl).setName("Ignore Files").setDesc("Specify a list of files to ignore. Enter each file on a new line.").addTextArea( (textArea) => (0, import_ValueComponent.extend)(textArea).bind(this.plugin, "ignoreFiles", { componentToPluginSettingsValueConverter: (value) => value.trim().split("\n"), pluginSettingsToComponentValueConverter: (value) => value.join("\n") }).setPlaceholder("Example: consistent-report.md") ); new import_obsidian.Setting(this.containerEl).setName("Consistency Report Filename").setDesc("Specify the name of the file for the consistency report.").addText( (text) => (0, import_ValueComponent.extend)(text).bind(this.plugin, "consistencyReportFile").setPlaceholder("Example: consistency-report.md") ); new import_obsidian.Setting(this.containerEl).setName("Auto Collect Attachments").setDesc("Automatically collect attachments when the note is edited.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "autoCollectAttachments")); } getNormalizedPath(path) { return path.length == 0 ? path : (0, import_obsidian.normalizePath)(path); } }; // src/files-handler.ts var import_obsidian3 = require("obsidian"); var import_AttachmentPath = __toESM(require_AttachmentPath(), 1); var import_FileSystem2 = __toESM(require_FileSystem(), 1); var import_Link2 = __toESM(require_Link(), 1); var import_MetadataCache2 = __toESM(require_MetadataCache(), 1); var import_Vault = __toESM(require_Vault(), 1); var import_Path2 = __toESM(require_Path(), 1); // src/links-handler.ts var import_obsidian2 = require("obsidian"); var import_FileChange = __toESM(require_FileChange(), 1); var import_FileSystem = __toESM(require_FileSystem(), 1); var import_Link = __toESM(require_Link(), 1); var import_MetadataCache = __toESM(require_MetadataCache(), 1); var import_Reference = __toESM(require_Reference(), 1); var import_Path = __toESM(require_Path(), 1); var ConsistencyCheckResult = class extends Map { constructor(title) { super(); this.title = title; } add(notePath, link) { if (!this.has(notePath)) { this.set(notePath, []); } const arr = this.get(notePath); if (arr) { arr.push(link); } } toString(app, reportPath) { if (this.size > 0) { let str = `# ${this.title} (${this.size.toString()} files) `; for (const notePath of this.keys()) { const note = (0, import_FileSystem.getFileOrNull)(app, notePath); if (!note) { continue; } const linkStr = (0, import_Link.generateMarkdownLink)({ app, pathOrFile: note, sourcePathOrFile: reportPath }); str += `${linkStr}: `; for (const link of this.get(notePath) ?? []) { str += `- (line ${(link.position.start.line + 1).toString()}): \`${link.link}\` `; } str += "\n\n"; } return str; } else { return `# ${this.title} No problems found `; } } }; var LinksHandler = class { constructor(app, consoleLogPrefix = "", ignoreFolders = [], ignoreFilesRegex = []) { this.app = app; this.consoleLogPrefix = consoleLogPrefix; this.ignoreFolders = ignoreFolders; this.ignoreFilesRegex = ignoreFilesRegex; } async checkConsistency(note, badLinks, badEmbeds, wikiLinks, wikiEmbeds) { if (this.isPathIgnored(note.path)) { return; } const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, note.path); if (!cache) { return; } const links = cache.links ?? []; const embeds = cache.embeds ?? []; for (const link of links) { if (!await this.isValidLink(link, note.path)) { badLinks.add(note.path, link); } if ((0, import_Link.testWikilink)(link.original)) { wikiLinks.add(note.path, link); } } for (const embed of embeds) { if (!await this.isValidLink(embed, note.path)) { badEmbeds.add(note.path, embed); } if ((0, import_Link.testWikilink)(embed.original)) { wikiEmbeds.add(note.path, embed); } } } async convertAllNoteEmbedsPathsToRelative(notePath) { return this.convertAllNoteRefPathsToRelative(notePath, true); } async convertAllNoteLinksPathsToRelative(notePath) { return this.convertAllNoteRefPathsToRelative(notePath, false); } async getCachedNotesThatHaveLinkToFile(filePath) { const file = (0, import_FileSystem.getFileOrNull)(this.app, filePath); if (!file) { return []; } const backlinks = await (0, import_MetadataCache.getBacklinksForFileSafe)(this.app, file); return backlinks.keys(); } getFullPathForLink(link, owningNotePath) { ({ linkPath: link } = (0, import_Link.splitSubpath)(link)); const parentFolder = (0, import_Path.dirname)(owningNotePath); const fullPath = (0, import_Path.join)(parentFolder, link); return fullPath; } async replaceAllNoteWikilinksWithMarkdownLinks(notePath, embedOnlyLinks) { if (this.isPathIgnored(notePath)) { return 0; } const noteFile = (0, import_FileSystem.getFileOrNull)(this.app, notePath); if (!noteFile) { console.warn(this.consoleLogPrefix + "can't update wikilinks in note, file not found: " + notePath); return 0; } const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, noteFile); if (!cache) { return 0; } const links = (embedOnlyLinks ? cache.embeds : cache.links) ?? []; const result = links.filter((link) => (0, import_Link.testWikilink)(link.original)).length; await (0, import_Link.updateLinksInFile)({ app: this.app, embedOnlyLinks, forceMarkdownLinks: true, oldPathOrFile: noteFile.path, pathOrFile: noteFile, renameMap: /* @__PURE__ */ new Map() }); return result; } async updateChangedPathsInNote(notePath, changedLinks) { if (this.isPathIgnored(notePath)) { return; } const note = (0, import_FileSystem.getFileOrNull)(this.app, notePath); if (!note) { console.warn(this.consoleLogPrefix + "can't update links in note, file not found: " + notePath); return; } const pathChangeMap = /* @__PURE__ */ new Map(); for (const change of changedLinks) { pathChangeMap.set(change.oldPath, change.newPath); } await this.updateLinks(note, note.path, pathChangeMap); } async convertAllNoteRefPathsToRelative(notePath, isEmbed) { if (this.isPathIgnored(notePath)) { return []; } const note = (0, import_FileSystem.getFileOrNull)(this.app, notePath); if (!note) { return []; } const changedRefs = []; await (0, import_FileChange.applyFileChanges)(this.app, note, async () => { const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, note); if (!cache) { return []; } const refs = (isEmbed ? cache.embeds : cache.links) ?? []; const changes = []; for (const ref of refs) { const change = { endIndex: ref.position.end.offset, newContent: this.convertLink({ forceRelativePath: true, link: ref, note, oldNotePath: notePath }), oldContent: ref.original, startIndex: ref.position.start.offset }; changes.push(change); changedRefs.push({ newLink: change.newContent, old: ref }); } return changes; }); return changedRefs; } convertLink({ forceRelativePath, link, note, oldNotePath, pathChangeMap }) { const { linkPath, subpath } = (0, import_Link.splitSubpath)(link.link); const oldLinkPath = (0, import_Link.extractLinkFile)(this.app, link, oldNotePath)?.path ?? (0, import_Path.join)((0, import_Path.dirname)(oldNotePath), linkPath); const newLinkPath = pathChangeMap ? pathChangeMap.get(oldLinkPath) : (0, import_Link.extractLinkFile)(this.app, link, note.path)?.path ?? (0, import_Path.join)((0, import_Path.dirname)(note.path), linkPath); if (!newLinkPath) { return link.original; } const newLinkedNote = (0, import_FileSystem.getFileOrNull)(this.app, oldLinkPath) ?? (0, import_FileSystem.getFileOrNull)(this.app, newLinkPath); if (!newLinkedNote) { return link.original; } return (0, import_Link.generateMarkdownLink)({ alias: link.displayText, app: this.app, forceRelativePath, originalLink: link.original, pathOrFile: newLinkedNote, sourcePathOrFile: note.path, subpath }); } isPathIgnored(path) { if (path.startsWith("./")) { path = path.slice(2); } for (const folder of this.ignoreFolders) { if (path.startsWith(folder)) { return true; } } for (const fileRegex of this.ignoreFilesRegex) { if (fileRegex.test(path)) { return true; } } return false; } async isValidLink(link, notePath) { const { linkPath, subpath } = (0, import_Link.splitSubpath)(link.link); let fullLinkPath; if (!linkPath) { fullLinkPath = notePath; } else if (linkPath.startsWith("/")) { fullLinkPath = (0, import_obsidian2.normalizePath)(linkPath); } else { fullLinkPath = (0, import_Path.join)((0, import_Path.dirname)(notePath), linkPath); } const file = (0, import_FileSystem.getFileOrNull)(this.app, fullLinkPath); if (!file) { return false; } if (!subpath) { return true; } const ext = file.extension.toLocaleLowerCase(); if (ext === "pdf") { return subpath.startsWith("#page="); } if (ext !== import_FileSystem.MARKDOWN_FILE_EXTENSION) { return false; } const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, file); if (!cache) { return false; } if (subpath.startsWith("#^")) { return Object.keys(cache.blocks ?? {}).includes(subpath.slice(2)); } else { return (cache.headings ?? []).map((h) => h.heading.replaceAll("#", " ")).includes(subpath.slice(1)); } } async updateLinks(note, oldNotePath, pathChangeMap) { await (0, import_FileChange.applyFileChanges)(this.app, note, async () => { const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, note); if (!cache) { return []; } const links = (0, import_MetadataCache.getAllLinks)(cache); return links.map((link) => (0, import_Reference.referenceToFileChange)(link, this.convertLink({ link, note, oldNotePath, pathChangeMap }))); }); } }; // src/files-handler.ts var FilesHandler = class { constructor(app, lh, consoleLogPrefix = "", ignoreFolders = [], ignoreFilesRegex = [], shouldDeleteEmptyFolders = false) { this.app = app; this.lh = lh; this.consoleLogPrefix = consoleLogPrefix; this.ignoreFolders = ignoreFolders; this.ignoreFilesRegex = ignoreFilesRegex; this.shouldDeleteEmptyFolders = shouldDeleteEmptyFolders; } async collectAttachmentsForCachedNote(notePath, deleteExistFiles, deleteEmptyFolders) { if (this.isPathIgnored(notePath)) { return { movedAttachments: [], renamedFiles: [] }; } const result = { movedAttachments: [], renamedFiles: [] }; const cache = await (0, import_MetadataCache2.getCacheSafe)(this.app, notePath); if (!cache) { return result; } for (const link of (0, import_MetadataCache2.getAllLinks)(cache)) { const { linkPath } = (0, import_Link2.splitSubpath)(link.link); if (!linkPath) { continue; } const fullPathLink = this.lh.getFullPathForLink(linkPath, notePath); if (result.movedAttachments.findIndex((x) => x.oldPath == fullPathLink) != -1) { continue; } const file = (0, import_Link2.extractLinkFile)(this.app, link, notePath); if (!file) { const type = (0, import_Link2.testEmbed)(link.original) ? "embed" : "link"; console.warn(`${this.consoleLogPrefix}${notePath} has bad ${type} (file does not exist): ${linkPath}`); continue; } if (!this.isAttachment(file)) { continue; } const newPath = await (0, import_AttachmentPath.getAttachmentFilePath)(this.app, file.path, notePath); if ((0, import_Path2.dirname)(newPath) === (0, import_Path2.dirname)(file.path)) { continue; } const res = await this.moveAttachment(file, newPath, [notePath], deleteExistFiles, deleteEmptyFolders); result.movedAttachments = result.movedAttachments.concat(res.movedAttachments); result.renamedFiles = result.renamedFiles.concat(res.renamedFiles); } return result; } async deleteEmptyFolders(dirName) { if (this.isPathIgnored(dirName)) { return; } if (dirName.startsWith("./")) { dirName = dirName.slice(2); } let list = await (0, import_Vault.listSafe)(this.app, dirName); for (const folder of list.folders) { await this.deleteEmptyFolders(folder); } list = await (0, import_Vault.listSafe)(this.app, dirName); if (list.files.length == 0 && list.folders.length == 0) { console.log(this.consoleLogPrefix + "delete empty folder: \n " + dirName); if (await this.app.vault.exists(dirName)) { try { await this.app.vault.adapter.rmdir(dirName, false); } catch (e) { if (await this.app.vault.adapter.exists(dirName)) { throw e; } } } } } async createFolderForAttachmentFromPath(filePath) { await (0, import_Vault.createFolderSafe)(this.app, (0, import_Path2.dirname)(filePath)); } async deleteFile(file, deleteEmptyFolders) { await this.app.fileManager.trashFile(file); if (deleteEmptyFolders) { let dir = file.parent; while (dir && dir.children.length === 0) { await this.app.fileManager.trashFile(dir); dir = dir.parent; } } } isAttachment(file) { return !(0, import_FileSystem2.isNote)(file); } isPathIgnored(path) { if (path.startsWith("./")) { path = path.slice(2); } for (const folder of this.ignoreFolders) { if (path.startsWith(folder)) { return true; } } for (const fileRegex of this.ignoreFilesRegex) { const testResult = fileRegex.test(path); if (testResult) { return true; } } return false; } async moveAttachment(file, newLinkPath, parentNotePaths, deleteExistFiles, deleteEmptyFolders) { const path = file.path; const result = { movedAttachments: [], renamedFiles: [] }; if (this.isPathIgnored(path)) { return result; } if (!this.isAttachment(file)) { return result; } if (path == newLinkPath) { console.warn(this.consoleLogPrefix + "Can't move file. Source and destination path the same."); return result; } await this.createFolderForAttachmentFromPath(newLinkPath); const linkedNotes = await this.lh.getCachedNotesThatHaveLinkToFile(path); for (const notePath of parentNotePaths) { linkedNotes.remove(notePath); } if (path !== file.path) { console.warn(this.consoleLogPrefix + "File was moved already"); return await this.moveAttachment(file, newLinkPath, parentNotePaths, deleteExistFiles, deleteEmptyFolders); } const oldFolder = file.parent; if (linkedNotes.length == 0) { const existFile = (0, import_FileSystem2.getFileOrNull)(this.app, newLinkPath); if (!existFile) { console.log(this.consoleLogPrefix + "move file [from, to]: \n " + path + "\n " + newLinkPath); result.movedAttachments.push({ newPath: newLinkPath, oldPath: path }); await (0, import_Vault.renameSafe)(this.app, file, newLinkPath); } else { if (deleteExistFiles) { console.log(this.consoleLogPrefix + "delete file: \n " + path); result.movedAttachments.push({ newPath: newLinkPath, oldPath: path }); await this.deleteFile(file, deleteEmptyFolders); } else { const newFileCopyName = (0, import_Vault.getAvailablePath)(this.app, newLinkPath); console.log(this.consoleLogPrefix + "copy file with new name [from, to]: \n " + path + "\n " + newFileCopyName); result.movedAttachments.push({ newPath: newFileCopyName, oldPath: path }); await (0, import_Vault.renameSafe)(this.app, file, newFileCopyName); result.renamedFiles.push({ newPath: newFileCopyName, oldPath: newLinkPath }); } } } else { const existFile = (0, import_FileSystem2.getFileOrNull)(this.app, newLinkPath); if (!existFile) { console.log(this.consoleLogPrefix + "copy file [from, to]: \n " + path + "\n " + newLinkPath); result.movedAttachments.push({ newPath: newLinkPath, oldPath: path }); await (0, import_Vault.renameSafe)(this.app, file, newLinkPath); await (0, import_Vault.copySafe)(this.app, file, path); } else if (!deleteExistFiles) { const newFileCopyName = (0, import_Vault.getAvailablePath)(this.app, newLinkPath); console.log(this.consoleLogPrefix + "copy file with new name [from, to]: \n " + path + "\n " + newFileCopyName); result.movedAttachments.push({ newPath: newFileCopyName, oldPath: file.path }); await (0, import_Vault.renameSafe)(this.app, file, newFileCopyName); await (0, import_Vault.copySafe)(this.app, file, path); result.renamedFiles.push({ newPath: newFileCopyName, oldPath: newLinkPath }); } } if (this.shouldDeleteEmptyFolders) { await (0, import_Vault.deleteEmptyFolderHierarchy)(this.app, oldFolder); } return result; } }; // src/ConsistentAttachmentsAndLinksPlugin.ts var __process = globalThis["process"] ?? { "cwd": () => "/", "env": {}, "platform": "android" }; var ConsistentAttachmentsAndLinksPlugin = class extends import_PluginBase.PluginBase { deletedNoteCache = /* @__PURE__ */ new Map(); fh; lh; async saveSettings(newSettings) { await super.saveSettings(newSettings); this.lh = new LinksHandler( this.app, "Consistent Attachments and Links: ", this.settings.ignoreFolders, this.settings.getIgnoreFilesRegex() ); this.fh = new FilesHandler( this.app, this.lh, "Consistent Attachments and Links: ", this.settings.ignoreFolders, this.settings.getIgnoreFilesRegex() ); } createDefaultPluginSettings() { return new ConsistentAttachmentsAndLinksPluginSettings(); } createPluginSettingsTab() { return new ConsistentAttachmentsAndLinksPluginSettingsTab(this); } onloadComplete() { if (this.settings.showWarning) { const notice = new import_obsidian4.Notice(createFragment((f) => { f.appendText("Starting from "); appendCodeBlock(f, "v3.0.0"); f.appendText(", the plugin "); appendCodeBlock(f, "Consistent Attachments and Links"); f.appendText(" has setting "); appendCodeBlock(f, "Attachment Subfolder"); f.appendText(" removed. This is a BREAKING CHANGE."); f.appendChild(createEl("br")); f.appendChild(createEl("a", { href: "https://github.com/dy-sh/obsidian-consistent-attachments-and-links?tab=readme-ov-file#attachment-subfolder-setting", text: "Read more" })); }), 0); notice.noticeEl.onClickEvent((ev) => { (0, import_Queue.addToQueue)(this.app, async () => { if (ev.target instanceof HTMLAnchorElement) { window.open(ev.target.href, "_blank"); } this.settings.showWarning = false; await this.saveSettings(this.settings); }); }); } this.registerEvent( this.app.metadataCache.on("deleted", (file, prevCache) => { if (prevCache) { this.handleDeletedMetadata(file, prevCache); } }) ); (0, import_RenameDeleteHandler.registerRenameDeleteHandlers)(this, () => { const settings = { shouldDeleteConflictingAttachments: this.settings.deleteExistFilesWhenMoveNote, shouldDeleteEmptyFolders: this.settings.deleteEmptyFolders, shouldDeleteOrphanAttachments: this.settings.deleteAttachmentsWithNote, shouldRenameAttachmentFolder: this.settings.moveAttachmentsWithNote, shouldUpdateFilenameAliases: this.settings.changeNoteBacklinksAlt, shouldUpdateLinks: this.settings.updateLinks }; return settings; }); this.addCommand({ callback: () => this.collectAllAttachments(), id: "collect-all-attachments", name: "Collect All Attachments" }); this.addCommand({ checkCallback: this.collectAttachmentsCurrentNote.bind(this), id: "collect-attachments-current-note", name: "Collect Attachments in Current Note" }); this.addCommand({ callback: () => this.deleteEmptyFolders(), id: "delete-empty-folders", name: "Delete Empty Folders" }); this.addCommand({ callback: () => this.convertAllLinkPathsToRelative(), id: "convert-all-link-paths-to-relative", name: "Convert All Link Paths to Relative" }); this.addCommand({ checkCallback: this.convertAllLinkPathsToRelativeCurrentNote.bind(this), id: "convert-all-link-paths-to-relative-current-note", name: "Convert All Link Paths to Relative in Current Note" }); this.addCommand({ callback: () => this.convertAllEmbedsPathsToRelative(), id: "convert-all-embed-paths-to-relative", name: "Convert All Embed Paths to Relative" }); this.addCommand({ checkCallback: this.convertAllEmbedsPathsToRelativeCurrentNote.bind(this), id: "convert-all-embed-paths-to-relative-current-note", name: "Convert All Embed Paths to Relative in Current Note" }); this.addCommand({ callback: () => this.replaceAllWikilinksWithMarkdownLinks(), id: "replace-all-wikilinks-with-markdown-links", name: "Replace All Wiki Links with Markdown Links" }); this.addCommand({ checkCallback: this.replaceAllWikilinksWithMarkdownLinksCurrentNote.bind(this), id: "replace-all-wikilinks-with-markdown-links-current-note", name: "Replace All Wiki Links with Markdown Links in Current Note" }); this.addCommand({ callback: () => this.replaceAllWikiEmbedsWithMarkdownEmbeds(), id: "replace-all-wiki-embeds-with-markdown-embeds", name: "Replace All Wiki Embeds with Markdown Embeds" }); this.addCommand({ checkCallback: this.replaceAllWikiEmbedsWithMarkdownEmbedsCurrentNote.bind(this), id: "replace-all-wiki-embeds-with-markdown-embeds-current-note", name: "Replace All Wiki Embeds with Markdown Embeds in Current Note" }); this.addCommand({ callback: () => this.reorganizeVault(), id: "reorganize-vault", name: "Reorganize Vault" }); this.addCommand({ callback: () => this.checkConsistency(), id: "check-consistency", name: "Check Vault consistency" }); this.registerEvent(this.app.metadataCache.on("changed", (file) => { (0, import_Queue.addToQueue)(this.app, () => this.handleMetadataCacheChanged(file)); })); this.lh = new LinksHandler( this.app, "Consistent Attachments and Links: ", this.settings.ignoreFolders, this.settings.getIgnoreFilesRegex() ); this.fh = new FilesHandler( this.app, this.lh, "Consistent Attachments and Links: ", this.settings.ignoreFolders, this.settings.getIgnoreFilesRegex(), this.settings.deleteEmptyFolders ); } async checkConsistency() { await this.saveAllOpenNotes(); const badLinks = new ConsistencyCheckResult("Bad links"); const badEmbeds = new ConsistencyCheckResult("Bad embeds"); const wikiLinks = new ConsistencyCheckResult("Wiki links"); const wikiEmbeds = new ConsistencyCheckResult("Wiki embeds"); const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app); let i = 0; const notice = new import_obsidian4.Notice("", 0); for (const note2 of notes) { if (this.abortSignal.aborted) { notice.hide(); return; } i++; const message = `Checking note # ${i.toString()} / ${notes.length.toString()} - ${note2.path}`; notice.setMessage(message); console.debug(message); await this.lh.checkConsistency(note2, badLinks, badEmbeds, wikiLinks, wikiEmbeds); } notice.hide(); const notePath = this.settings.consistencyReportFile; const text = badLinks.toString(this.app, notePath) + badEmbeds.toString(this.app, notePath) + wikiLinks.toString(this.app, notePath) + wikiEmbeds.toString(this.app, notePath); await (0, import_Vault2.createFolderSafe)(this.app, (0, import_Path3.dirname)(notePath)); const note = await (0, import_FileSystem3.getOrCreateFile)(this.app, notePath); await this.app.vault.modify(note, text); let fileOpened = false; this.app.workspace.iterateAllLeaves((leaf) => { if (leaf.getDisplayText() != "" && notePath.startsWith(leaf.getDisplayText())) { fileOpened = true; } }); if (!fileOpened) { await this.app.workspace.openLinkText(notePath, "/", false); } } async collectAllAttachments() { let movedAttachmentsCount = 0; let processedNotesCount = 0; await this.saveAllOpenNotes(); const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app); let i = 0; const notice = new import_obsidian4.Notice("", 0); for (const note of notes) { if (this.abortSignal.aborted) { notice.hide(); return; } i++; const message = `Collecting attachments # ${i.toString()} / ${notes.length.toString()} - ${note.path}`; notice.setMessage(message); console.debug(message); if (this.isPathIgnored(note.path)) { continue; } const result = await this.fh.collectAttachmentsForCachedNote( note.path, this.settings.deleteExistFilesWhenMoveNote, this.settings.deleteEmptyFolders ); if (result.movedAttachments.length > 0) { await this.lh.updateChangedPathsInNote(note.path, result.movedAttachments); movedAttachmentsCount += result.movedAttachments.length; processedNotesCount++; } } notice.hide(); if (movedAttachmentsCount == 0) { new import_obsidian4.Notice("No files found that need to be moved"); } else { new import_obsidian4.Notice(`Moved ${movedAttachmentsCount.toString()} attachment${movedAttachmentsCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`); } } async collectAttachments(note, isVerbose = true) { if (this.isPathIgnored(note.path)) { new import_obsidian4.Notice("Note path is ignored"); return; } await this.saveAllOpenNotes(); const result = await this.fh.collectAttachmentsForCachedNote( note.path, this.settings.deleteExistFilesWhenMoveNote, this.settings.deleteEmptyFolders ); if (result.movedAttachments.length > 0) { await this.lh.updateChangedPathsInNote(note.path, result.movedAttachments); } if (result.movedAttachments.length == 0) { if (isVerbose) { new import_obsidian4.Notice("No files found that need to be moved"); } } else { new import_obsidian4.Notice(`Moved ${result.movedAttachments.length.toString()} attachment${result.movedAttachments.length > 1 ? "s" : ""}`); } } collectAttachmentsCurrentNote(checking) { const note = this.app.workspace.getActiveFile(); if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) { return false; } if (!checking) { (0, import_Queue.addToQueue)(this.app, () => this.collectAttachments(note)); } return true; } async convertAllEmbedsPathsToRelative() { await this.saveAllOpenNotes(); let changedEmbedCount = 0; let processedNotesCount = 0; const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app); let i = 0; const notice = new import_obsidian4.Notice("", 0); for (const note of notes) { if (this.abortSignal.aborted) { notice.hide(); return; } i++; const message = `Converting embed paths to relative # ${i.toString()} / ${notes.length.toString()} - ${note.path}`; notice.setMessage(message); console.debug(message); if (this.isPathIgnored(note.path)) { continue; } const result = await this.lh.convertAllNoteEmbedsPathsToRelative(note.path); if (result.length > 0) { changedEmbedCount += result.length; processedNotesCount++; } } notice.hide(); if (changedEmbedCount == 0) { new import_obsidian4.Notice("No embeds found that need to be converted"); } else { new import_obsidian4.Notice(`Converted ${changedEmbedCount.toString()} embed${changedEmbedCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`); } } convertAllEmbedsPathsToRelativeCurrentNote(checking) { const note = this.app.workspace.getActiveFile(); if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) { return false; } if (!checking) { (0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.convertAllNoteEmbedsPathsToRelative(note.path))); } return true; } async convertAllLinkPathsToRelative() { await this.saveAllOpenNotes(); let changedLinksCount = 0; let processedNotesCount = 0; const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app); let i = 0; const notice = new import_obsidian4.Notice("", 0); for (const note of notes) { if (this.abortSignal.aborted) { notice.hide(); return; } i++; const message = `Converting link paths to relative # ${i.toString()} / ${notes.length.toString()} - ${note.path}`; notice.setMessage(message); console.debug(message); if (this.isPathIgnored(note.path)) { continue; } const result = await this.lh.convertAllNoteLinksPathsToRelative(note.path); if (result.length > 0) { changedLinksCount += result.length; processedNotesCount++; } } notice.hide(); if (changedLinksCount == 0) { new import_obsidian4.Notice("No links found that need to be converted"); } else { new import_obsidian4.Notice(`Converted ${changedLinksCount.toString()} link${changedLinksCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`); } } convertAllLinkPathsToRelativeCurrentNote(checking) { const note = this.app.workspace.getActiveFile(); if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) { return false; } if (!checking) { (0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.convertAllNoteLinksPathsToRelative(note.path))); } return true; } async deleteEmptyFolders() { await this.fh.deleteEmptyFolders("/"); } handleDeletedMetadata(file, prevCache) { if (!this.settings.deleteAttachmentsWithNote || this.isPathIgnored(file.path) || !(0, import_FileSystem3.isMarkdownFile)(file)) { return; } this.deletedNoteCache.set(file.path, prevCache); } async handleMetadataCacheChanged(file) { if (!this.settings.autoCollectAttachments) { return; } const suggestionContainer = document.querySelector(".suggestion-container"); if (suggestionContainer && suggestionContainer.style.display !== "none") { return; } await this.collectAttachments(file, false); } isPathIgnored(path) { if (path.startsWith("./")) { path = path.slice(2); } for (const folder of this.settings.ignoreFolders) { if (path.startsWith(folder)) { return true; } } for (const fileRegex of this.settings.getIgnoreFilesRegex()) { if (fileRegex.test(path)) { return true; } } return false; } async reorganizeVault() { await this.saveAllOpenNotes(); await this.replaceAllWikilinksWithMarkdownLinks(); await this.replaceAllWikiEmbedsWithMarkdownEmbeds(); await this.convertAllEmbedsPathsToRelative(); await this.convertAllLinkPathsToRelative(); await this.collectAllAttachments(); await this.deleteEmptyFolders(); new import_obsidian4.Notice("Reorganization of the vault completed"); } async replaceAllWikiEmbedsWithMarkdownEmbeds() { await this.saveAllOpenNotes(); let changedLinksCount = 0; let processedNotesCount = 0; const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app); let i = 0; const notice = new import_obsidian4.Notice("", 0); for (const note of notes) { if (this.abortSignal.aborted) { notice.hide(); return; } i++; const message = `Replacing wiki embeds with markdown embeds # ${i.toString()} / ${notes.length.toString()} - ${note.path}`; notice.setMessage(message); console.debug(message); if (this.isPathIgnored(note.path)) { continue; } const result = await this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, true); changedLinksCount += result; processedNotesCount++; } notice.hide(); if (changedLinksCount == 0) { new import_obsidian4.Notice("No wiki embeds found that need to be replaced"); } else { new import_obsidian4.Notice(`Replaced ${changedLinksCount.toString()} wiki embed${changedLinksCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`); } } replaceAllWikiEmbedsWithMarkdownEmbedsCurrentNote(checking) { const note = this.app.workspace.getActiveFile(); if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) { return false; } if (!checking) { (0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, true))); } return true; } async replaceAllWikilinksWithMarkdownLinks() { await this.saveAllOpenNotes(); let changedLinksCount = 0; let processedNotesCount = 0; const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app); let i = 0; const notice = new import_obsidian4.Notice("", 0); for (const note of notes) { if (this.abortSignal.aborted) { notice.hide(); return; } i++; const message = `Replacing wikilinks with markdown links # ${i.toString()} / ${notes.length.toString()} - ${note.path}`; notice.setMessage(message); console.debug(message); if (this.isPathIgnored(note.path)) { continue; } const result = await this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, false); changedLinksCount += result; processedNotesCount++; } notice.hide(); if (changedLinksCount == 0) { new import_obsidian4.Notice("No wiki links found that need to be replaced"); } else { new import_obsidian4.Notice(`Replaced ${changedLinksCount.toString()} wikilink${changedLinksCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`); } } replaceAllWikilinksWithMarkdownLinksCurrentNote(checking) { const note = this.app.workspace.getActiveFile(); if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) { return false; } if (!checking) { (0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, false))); } return true; } async saveAllOpenNotes() { for (const leaf of this.app.workspace.getLeavesOfType("markdown")) { if (leaf.view instanceof import_obsidian4.MarkdownView) { await leaf.view.save(); } } } }; function appendCodeBlock(fragment, text) { fragment.appendChild(createSpan({ cls: "markdown-rendered code" }, (span) => { span.style.fontWeight = "bold"; span.appendChild(createEl("code", { text })); })); } // src/main.ts var main_default = ConsistentAttachmentsAndLinksPlugin; /* nosourcemap */