@mnaoumov/obsidian-dev-toolkit 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/dist/demo-vault-helper/main.js +179 -1
  2. package/dist/integration-test-plugin/main.js +1232 -1023
  3. package/dist/integration-test-plugin/manifest.json +2 -2
  4. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +3 -22
  5. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.cts +1 -1
  6. package/dist/lib/cjs/bundlers/esbuild-impl/dependency.cjs +2 -21
  7. package/dist/lib/cjs/bundlers/esbuild-impl/dependency.d.cts +1 -1
  8. package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.cjs +2 -21
  9. package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.d.cts +1 -1
  10. package/dist/lib/cjs/bundlers/esbuild-impl/index.cjs +7 -53
  11. package/dist/lib/cjs/bundlers/esbuild-impl/index.d.cts +1 -1
  12. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.cjs +4 -23
  13. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.d.cts +1 -1
  14. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.cjs +2 -21
  15. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.d.cts +1 -1
  16. package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.cjs +2 -21
  17. package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.d.cts +1 -1
  18. package/dist/lib/cjs/bundlers/esbuild.cjs +1 -47
  19. package/dist/lib/cjs/bundlers/esbuild.d.cts +1 -1
  20. package/dist/lib/cjs/bundlers/index.cjs +3 -49
  21. package/dist/lib/cjs/bundlers/index.d.cts +1 -1
  22. package/dist/lib/cjs/demo-vault-app-json.cjs +2 -21
  23. package/dist/lib/cjs/demo-vault-app-json.d.cts +1 -1
  24. package/dist/lib/cjs/demo-vault-buttons.cjs +3 -22
  25. package/dist/lib/cjs/demo-vault-buttons.d.cts +1 -1
  26. package/dist/lib/cjs/demo-vault-coverage.cjs +2 -21
  27. package/dist/lib/cjs/demo-vault-coverage.d.cts +1 -1
  28. package/dist/lib/cjs/demo-vault.cjs +3 -22
  29. package/dist/lib/cjs/demo-vault.d.cts +1 -1
  30. package/dist/lib/cjs/formatters/dprint.cjs +2 -21
  31. package/dist/lib/cjs/formatters/dprint.d.cts +1 -1
  32. package/dist/lib/cjs/formatters/index.cjs +2 -48
  33. package/dist/lib/cjs/formatters/index.d.cts +1 -1
  34. package/dist/lib/cjs/index.cjs +12 -58
  35. package/dist/lib/cjs/integration-test-setup.cjs +1 -47
  36. package/dist/lib/cjs/integration-test-setup.d.cts +5 -5
  37. package/dist/lib/cjs/integration-test-vitest-global-setup.cjs +3 -22
  38. package/dist/lib/cjs/integration-test-vitest-global-setup.d.cts +7 -7
  39. package/dist/lib/cjs/jest-setup.cjs +2 -21
  40. package/dist/lib/cjs/jest-setup.d.cts +1 -1
  41. package/dist/lib/cjs/library-references.d.cts +2 -0
  42. package/dist/lib/cjs/linters/eslint-config.cjs +24 -40
  43. package/dist/lib/cjs/linters/eslint-config.d.cts +1 -1
  44. package/dist/lib/cjs/linters/eslint-rules/index.cjs +16 -62
  45. package/dist/lib/cjs/linters/eslint-rules/index.d.cts +2 -2
  46. package/dist/lib/cjs/linters/eslint-rules/manifest-description.cjs +1 -47
  47. package/dist/lib/cjs/linters/eslint-rules/manifest-description.d.cts +1 -1
  48. package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.cjs +3 -22
  49. package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.d.cts +1 -1
  50. package/dist/lib/cjs/linters/eslint-rules/manifest-id.cjs +1 -47
  51. package/dist/lib/cjs/linters/eslint-rules/manifest-id.d.cts +1 -1
  52. package/dist/lib/cjs/linters/eslint-rules/manifest-name.cjs +1 -47
  53. package/dist/lib/cjs/linters/eslint-rules/manifest-name.d.cts +1 -1
  54. package/dist/lib/cjs/linters/eslint-rules/manifest-schema.cjs +1 -47
  55. package/dist/lib/cjs/linters/eslint-rules/manifest-schema.d.cts +1 -1
  56. package/dist/lib/cjs/linters/eslint-rules/no-local-obsidian-internals.cjs +2 -21
  57. package/dist/lib/cjs/linters/eslint-rules/no-local-obsidian-internals.d.cts +1 -1
  58. package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.cjs +2 -21
  59. package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.cts +1 -1
  60. package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.cjs +2 -21
  61. package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.d.cts +1 -1
  62. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-toolkit-plugin.cjs +136 -0
  63. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-toolkit-plugin.d.cts +16 -0
  64. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code-in-ui.cjs +1 -47
  65. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code-in-ui.d.cts +1 -1
  66. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code.cjs +1 -47
  67. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code.d.cts +1 -1
  68. package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.cjs +2 -21
  69. package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.d.cts +1 -1
  70. package/dist/lib/cjs/linters/eslint-rules/require-plugin-api-contract-schemas.cjs +2 -21
  71. package/dist/lib/cjs/linters/eslint-rules/require-plugin-api-contract-schemas.d.cts +1 -1
  72. package/dist/lib/cjs/linters/eslint.cjs +2 -21
  73. package/dist/lib/cjs/linters/eslint.d.cts +1 -1
  74. package/dist/lib/cjs/linters/index.cjs +9 -55
  75. package/dist/lib/cjs/linters/index.d.cts +1 -1
  76. package/dist/lib/cjs/linters/markdownlint-cli2-config.cjs +2 -21
  77. package/dist/lib/cjs/linters/markdownlint-cli2-config.d.cts +1 -1
  78. package/dist/lib/cjs/linters/markdownlint-rules/index.cjs +2 -48
  79. package/dist/lib/cjs/linters/markdownlint-rules/index.d.cts +1 -1
  80. package/dist/lib/cjs/linters/markdownlint-rules/plugin-name-as-code.cjs +2 -48
  81. package/dist/lib/cjs/linters/markdownlint-rules/plugin-name-as-code.d.cts +1 -1
  82. package/dist/lib/cjs/linters/markdownlint.cjs +2 -21
  83. package/dist/lib/cjs/linters/markdownlint.d.cts +1 -1
  84. package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.cjs +1 -47
  85. package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.d.cts +1 -1
  86. package/dist/lib/cjs/linters/plugin-names.cjs +1 -47
  87. package/dist/lib/cjs/linters/plugin-names.d.cts +1 -1
  88. package/dist/lib/cjs/obsidian-plugin-repo-paths.cjs +1 -47
  89. package/dist/lib/cjs/obsidian-plugin-repo-paths.d.cts +1 -1
  90. package/dist/lib/cjs/setup.cjs +2 -21
  91. package/dist/lib/cjs/setup.d.cts +1 -1
  92. package/dist/lib/cjs/templates.cjs +2 -21
  93. package/dist/lib/cjs/templates.d.cts +1 -1
  94. package/dist/lib/cjs/test-runners/index.cjs +4 -50
  95. package/dist/lib/cjs/test-runners/index.d.cts +1 -1
  96. package/dist/lib/cjs/test-runners/integration-test-plugin.cjs +9 -28
  97. package/dist/lib/cjs/test-runners/integration-test-plugin.d.cts +5 -5
  98. package/dist/lib/cjs/test-runners/performance-eval-cap.cjs +1 -47
  99. package/dist/lib/cjs/test-runners/performance-eval-cap.d.cts +1 -1
  100. package/dist/lib/cjs/test-runners/stale-build-global-setup.cjs +2 -21
  101. package/dist/lib/cjs/test-runners/stale-build-global-setup.d.cts +1 -1
  102. package/dist/lib/cjs/test-runners/vitest-config.cjs +6 -25
  103. package/dist/lib/cjs/test-runners/vitest-config.d.cts +2 -3
  104. package/dist/lib/cjs/version.cjs +2 -21
  105. package/dist/lib/cjs/version.d.cts +1 -1
  106. package/dist/lib/cjs/vitest-setup.cjs +2 -21
  107. package/dist/lib/cjs/vitest-setup.d.cts +1 -1
  108. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.mts +1 -1
  109. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.mjs +2 -11
  110. package/dist/lib/esm/bundlers/esbuild-impl/dependency.d.mts +1 -1
  111. package/dist/lib/esm/bundlers/esbuild-impl/dependency.mjs +2 -11
  112. package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.d.mts +1 -1
  113. package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.mjs +2 -11
  114. package/dist/lib/esm/bundlers/esbuild-impl/index.d.mts +1 -1
  115. package/dist/lib/esm/bundlers/esbuild-impl/index.mjs +1 -37
  116. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.d.mts +1 -1
  117. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.mjs +2 -11
  118. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.d.mts +1 -1
  119. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.mjs +2 -11
  120. package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.d.mts +1 -1
  121. package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.mjs +2 -11
  122. package/dist/lib/esm/bundlers/esbuild.d.mts +1 -1
  123. package/dist/lib/esm/bundlers/esbuild.mjs +1 -37
  124. package/dist/lib/esm/bundlers/index.d.mts +1 -1
  125. package/dist/lib/esm/bundlers/index.mjs +1 -37
  126. package/dist/lib/esm/demo-vault-app-json.d.mts +1 -1
  127. package/dist/lib/esm/demo-vault-app-json.mjs +2 -11
  128. package/dist/lib/esm/demo-vault-buttons.d.mts +1 -1
  129. package/dist/lib/esm/demo-vault-buttons.mjs +2 -11
  130. package/dist/lib/esm/demo-vault-coverage.d.mts +1 -1
  131. package/dist/lib/esm/demo-vault-coverage.mjs +2 -11
  132. package/dist/lib/esm/demo-vault.d.mts +1 -1
  133. package/dist/lib/esm/demo-vault.mjs +3 -12
  134. package/dist/lib/esm/formatters/dprint.d.mts +1 -1
  135. package/dist/lib/esm/formatters/dprint.mjs +2 -11
  136. package/dist/lib/esm/formatters/index.d.mts +1 -1
  137. package/dist/lib/esm/formatters/index.mjs +1 -37
  138. package/dist/lib/esm/index.mjs +1 -37
  139. package/dist/lib/esm/integration-test-setup.d.mts +5 -5
  140. package/dist/lib/esm/integration-test-setup.mjs +1 -37
  141. package/dist/lib/esm/integration-test-vitest-global-setup.d.mts +7 -7
  142. package/dist/lib/esm/integration-test-vitest-global-setup.mjs +4 -13
  143. package/dist/lib/esm/jest-setup.d.mts +1 -1
  144. package/dist/lib/esm/jest-setup.mjs +2 -11
  145. package/dist/lib/esm/library-references.d.mts +2 -0
  146. package/dist/lib/esm/linters/eslint-config.d.mts +1 -1
  147. package/dist/lib/esm/linters/eslint-config.mjs +23 -29
  148. package/dist/lib/esm/linters/eslint-rules/index.d.mts +2 -2
  149. package/dist/lib/esm/linters/eslint-rules/index.mjs +3 -39
  150. package/dist/lib/esm/linters/eslint-rules/manifest-description.d.mts +1 -1
  151. package/dist/lib/esm/linters/eslint-rules/manifest-description.mjs +1 -37
  152. package/dist/lib/esm/linters/eslint-rules/manifest-helpers.d.mts +1 -1
  153. package/dist/lib/esm/linters/eslint-rules/manifest-helpers.mjs +2 -11
  154. package/dist/lib/esm/linters/eslint-rules/manifest-id.d.mts +1 -1
  155. package/dist/lib/esm/linters/eslint-rules/manifest-id.mjs +1 -37
  156. package/dist/lib/esm/linters/eslint-rules/manifest-name.d.mts +1 -1
  157. package/dist/lib/esm/linters/eslint-rules/manifest-name.mjs +1 -37
  158. package/dist/lib/esm/linters/eslint-rules/manifest-schema.d.mts +1 -1
  159. package/dist/lib/esm/linters/eslint-rules/manifest-schema.mjs +1 -37
  160. package/dist/lib/esm/linters/eslint-rules/no-local-obsidian-internals.d.mts +1 -1
  161. package/dist/lib/esm/linters/eslint-rules/no-local-obsidian-internals.mjs +2 -11
  162. package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.mts +1 -1
  163. package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.mjs +2 -11
  164. package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.d.mts +1 -1
  165. package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.mjs +2 -11
  166. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-toolkit-plugin.d.mts +16 -0
  167. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-toolkit-plugin.mjs +37 -0
  168. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code-in-ui.d.mts +1 -1
  169. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code-in-ui.mjs +1 -37
  170. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code.d.mts +1 -1
  171. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code.mjs +1 -37
  172. package/dist/lib/esm/linters/eslint-rules/require-component-suffix.d.mts +1 -1
  173. package/dist/lib/esm/linters/eslint-rules/require-component-suffix.mjs +2 -11
  174. package/dist/lib/esm/linters/eslint-rules/require-plugin-api-contract-schemas.d.mts +1 -1
  175. package/dist/lib/esm/linters/eslint-rules/require-plugin-api-contract-schemas.mjs +2 -11
  176. package/dist/lib/esm/linters/eslint.d.mts +1 -1
  177. package/dist/lib/esm/linters/eslint.mjs +2 -11
  178. package/dist/lib/esm/linters/index.d.mts +1 -1
  179. package/dist/lib/esm/linters/index.mjs +1 -37
  180. package/dist/lib/esm/linters/markdownlint-cli2-config.d.mts +1 -1
  181. package/dist/lib/esm/linters/markdownlint-cli2-config.mjs +2 -11
  182. package/dist/lib/esm/linters/markdownlint-rules/index.d.mts +1 -1
  183. package/dist/lib/esm/linters/markdownlint-rules/index.mjs +1 -37
  184. package/dist/lib/esm/linters/markdownlint-rules/plugin-name-as-code.d.mts +1 -1
  185. package/dist/lib/esm/linters/markdownlint-rules/plugin-name-as-code.mjs +1 -37
  186. package/dist/lib/esm/linters/markdownlint.d.mts +1 -1
  187. package/dist/lib/esm/linters/markdownlint.mjs +2 -11
  188. package/dist/lib/esm/linters/obsidianmd-rule-custom-message.d.mts +1 -1
  189. package/dist/lib/esm/linters/obsidianmd-rule-custom-message.mjs +1 -37
  190. package/dist/lib/esm/linters/plugin-names.d.mts +1 -1
  191. package/dist/lib/esm/linters/plugin-names.mjs +1 -37
  192. package/dist/lib/esm/obsidian-plugin-repo-paths.d.mts +1 -1
  193. package/dist/lib/esm/obsidian-plugin-repo-paths.mjs +1 -37
  194. package/dist/lib/esm/setup.d.mts +1 -1
  195. package/dist/lib/esm/setup.mjs +2 -11
  196. package/dist/lib/esm/templates.d.mts +1 -1
  197. package/dist/lib/esm/templates.mjs +2 -11
  198. package/dist/lib/esm/test-runners/index.d.mts +1 -1
  199. package/dist/lib/esm/test-runners/index.mjs +1 -37
  200. package/dist/lib/esm/test-runners/integration-test-plugin.d.mts +5 -5
  201. package/dist/lib/esm/test-runners/integration-test-plugin.mjs +8 -17
  202. package/dist/lib/esm/test-runners/performance-eval-cap.d.mts +1 -1
  203. package/dist/lib/esm/test-runners/performance-eval-cap.mjs +1 -37
  204. package/dist/lib/esm/test-runners/stale-build-global-setup.d.mts +1 -1
  205. package/dist/lib/esm/test-runners/stale-build-global-setup.mjs +2 -11
  206. package/dist/lib/esm/test-runners/vitest-config.d.mts +2 -3
  207. package/dist/lib/esm/test-runners/vitest-config.mjs +5 -14
  208. package/dist/lib/esm/version.d.mts +1 -1
  209. package/dist/lib/esm/version.mjs +2 -11
  210. package/dist/lib/esm/vitest-setup.d.mts +1 -1
  211. package/dist/lib/esm/vitest-setup.mjs +2 -11
  212. package/linters/eslint-rules/{obsidian-dev-utils-plugin → obsidian-dev-toolkit-plugin}/package.json +3 -3
  213. package/package.json +3 -3
  214. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.cjs +0 -181
  215. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.d.cts +0 -13
  216. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.d.mts +0 -13
  217. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.mjs +0 -73
@@ -4597,8 +4597,8 @@ var init_i18next = __esm({
4597
4597
  if (key == null) return false;
4598
4598
  const resolved = this.resolve(key, opt);
4599
4599
  if (resolved?.res === void 0) return false;
4600
- const isObject = shouldHandleAsObject(resolved.res);
4601
- if (opt.returnObjects === false && isObject) {
4600
+ const isObject2 = shouldHandleAsObject(resolved.res);
4601
+ if (opt.returnObjects === false && isObject2) {
4602
4602
  return false;
4603
4603
  }
4604
4604
  return true;
@@ -7365,6 +7365,131 @@ var init_obsidian_dev_utils_state = __esm({
7365
7365
  }
7366
7366
  });
7367
7367
 
7368
+ // node_modules/compare-versions/lib/umd/index.js
7369
+ var require_umd = __commonJS({
7370
+ "node_modules/compare-versions/lib/umd/index.js"(exports, module2) {
7371
+ (function(global, factory) {
7372
+ typeof exports === "object" && typeof module2 !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.compareVersions = {}));
7373
+ })(exports, (function(exports2) {
7374
+ "use strict";
7375
+ const semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
7376
+ const validateAndParse = (version) => {
7377
+ if (typeof version !== "string") {
7378
+ throw new TypeError("Invalid argument expected string");
7379
+ }
7380
+ const match = version.match(semver);
7381
+ if (!match) {
7382
+ throw new Error(`Invalid argument not valid semver ('${version}' received)`);
7383
+ }
7384
+ match.shift();
7385
+ return match;
7386
+ };
7387
+ const isWildcard = (s2) => s2 === "*" || s2 === "x" || s2 === "X";
7388
+ const tryParse = (v) => {
7389
+ const n2 = parseInt(v, 10);
7390
+ return isNaN(n2) ? v : n2;
7391
+ };
7392
+ const forceType = (a2, b) => typeof a2 !== typeof b ? [String(a2), String(b)] : [a2, b];
7393
+ const compareStrings = (a2, b) => {
7394
+ if (isWildcard(a2) || isWildcard(b))
7395
+ return 0;
7396
+ const [ap, bp] = forceType(tryParse(a2), tryParse(b));
7397
+ if (ap > bp)
7398
+ return 1;
7399
+ if (ap < bp)
7400
+ return -1;
7401
+ return 0;
7402
+ };
7403
+ const compareSegments = (a2, b) => {
7404
+ for (let i2 = 0; i2 < Math.max(a2.length, b.length); i2++) {
7405
+ const r2 = compareStrings(a2[i2] || "0", b[i2] || "0");
7406
+ if (r2 !== 0)
7407
+ return r2;
7408
+ }
7409
+ return 0;
7410
+ };
7411
+ const compareVersions5 = (v1, v2) => {
7412
+ const n1 = validateAndParse(v1);
7413
+ const n2 = validateAndParse(v2);
7414
+ const p1 = n1.pop();
7415
+ const p2 = n2.pop();
7416
+ const r2 = compareSegments(n1, n2);
7417
+ if (r2 !== 0)
7418
+ return r2;
7419
+ if (p1 && p2) {
7420
+ return compareSegments(p1.split("."), p2.split("."));
7421
+ } else if (p1 || p2) {
7422
+ return p1 ? -1 : 1;
7423
+ }
7424
+ return 0;
7425
+ };
7426
+ const compare = (v1, v2, operator) => {
7427
+ assertValidOperator(operator);
7428
+ const res = compareVersions5(v1, v2);
7429
+ return operatorResMap[operator].includes(res);
7430
+ };
7431
+ const operatorResMap = {
7432
+ ">": [1],
7433
+ ">=": [0, 1],
7434
+ "=": [0],
7435
+ "<=": [-1, 0],
7436
+ "<": [-1],
7437
+ "!=": [-1, 1]
7438
+ };
7439
+ const allowedOperators = Object.keys(operatorResMap);
7440
+ const assertValidOperator = (op) => {
7441
+ if (typeof op !== "string") {
7442
+ throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);
7443
+ }
7444
+ if (allowedOperators.indexOf(op) === -1) {
7445
+ throw new Error(`Invalid operator, expected one of ${allowedOperators.join("|")}`);
7446
+ }
7447
+ };
7448
+ const satisfies = (version, range) => {
7449
+ range = range.replace(/([><=]+)\s+/g, "$1");
7450
+ if (range.includes("||")) {
7451
+ return range.split("||").some((r5) => satisfies(version, r5));
7452
+ } else if (range.includes(" - ")) {
7453
+ const [a2, b] = range.split(" - ", 2);
7454
+ return satisfies(version, `>=${a2} <=${b}`);
7455
+ } else if (range.includes(" ")) {
7456
+ return range.trim().replace(/\s{2,}/g, " ").split(" ").every((r5) => satisfies(version, r5));
7457
+ }
7458
+ const m = range.match(/^([<>=~^]+)/);
7459
+ const op = m ? m[1] : "=";
7460
+ if (op !== "^" && op !== "~")
7461
+ return compare(version, range, op);
7462
+ const [v1, v2, v3, , vp] = validateAndParse(version);
7463
+ const [r1, r2, r3, , rp] = validateAndParse(range);
7464
+ const v = [v1, v2, v3];
7465
+ const r4 = [r1, r2 !== null && r2 !== void 0 ? r2 : "x", r3 !== null && r3 !== void 0 ? r3 : "x"];
7466
+ if (rp) {
7467
+ if (!vp)
7468
+ return false;
7469
+ if (compareSegments(v, r4) !== 0)
7470
+ return false;
7471
+ if (compareSegments(vp.split("."), rp.split(".")) === -1)
7472
+ return false;
7473
+ }
7474
+ const nonZero = r4.findIndex((v4) => v4 !== "0") + 1;
7475
+ const i2 = op === "~" ? 2 : nonZero > 1 ? nonZero : 1;
7476
+ if (compareSegments(v.slice(0, i2), r4.slice(0, i2)) !== 0)
7477
+ return false;
7478
+ if (compareSegments(v.slice(i2), r4.slice(i2)) === -1)
7479
+ return false;
7480
+ return true;
7481
+ };
7482
+ const validate = (version) => typeof version === "string" && /^[v\d]/.test(version) && semver.test(version);
7483
+ const validateStrict = (version) => typeof version === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(version);
7484
+ exports2.compare = compare;
7485
+ exports2.compareVersions = compareVersions5;
7486
+ exports2.satisfies = satisfies;
7487
+ exports2.validate = validate;
7488
+ exports2.validateStrict = validateStrict;
7489
+ }));
7490
+ }
7491
+ });
7492
+
7368
7493
  // node_modules/extend/index.js
7369
7494
  var require_extend = __commonJS({
7370
7495
  "node_modules/extend/index.js"(exports, module2) {
@@ -7456,6 +7581,86 @@ var require_extend = __commonJS({
7456
7581
  }
7457
7582
  });
7458
7583
 
7584
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/obsidian-settings.mjs
7585
+ var obsidian_settings_exports = {};
7586
+ __export(obsidian_settings_exports, {
7587
+ SpellcheckMode: () => SpellcheckMode,
7588
+ getNewLinkFormat: () => getNewLinkFormat,
7589
+ isSpellcheckEnabled: () => isSpellcheckEnabled,
7590
+ isSpellcheckEnabledForMode: () => isSpellcheckEnabledForMode,
7591
+ shouldUseWikilinks: () => shouldUseWikilinks
7592
+ });
7593
+ function getNewLinkFormat(app) {
7594
+ return app.vault.getConfig("newLinkFormat");
7595
+ }
7596
+ function isSpellcheckEnabled(app) {
7597
+ return Boolean(app.vault.getConfig("spellcheck"));
7598
+ }
7599
+ function isSpellcheckEnabledForMode(app, spellcheckMode) {
7600
+ switch (spellcheckMode) {
7601
+ case "AlwaysOn": {
7602
+ return true;
7603
+ }
7604
+ case "FollowObsidianSetting": {
7605
+ return isSpellcheckEnabled(app);
7606
+ }
7607
+ case "Off": {
7608
+ return false;
7609
+ }
7610
+ default: {
7611
+ assertNever(spellcheckMode);
7612
+ }
7613
+ }
7614
+ }
7615
+ function shouldUseWikilinks(app) {
7616
+ return !app.vault.getConfig("useMarkdownLinks");
7617
+ }
7618
+ var SpellcheckMode;
7619
+ var init_obsidian_settings = __esm({
7620
+ "node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/obsidian-settings.mjs"() {
7621
+ init_type_guards();
7622
+ (function() {
7623
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
7624
+ symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
7625
+ symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
7626
+ }
7627
+ function ensureBrowserProcess() {
7628
+ const browserProcess = {
7629
+ browser: true,
7630
+ cwd() {
7631
+ return "/";
7632
+ },
7633
+ env: {},
7634
+ platform: "android"
7635
+ };
7636
+ const existingProcess = globalThis.process;
7637
+ if (!existingProcess) {
7638
+ globalThis.process = browserProcess;
7639
+ return;
7640
+ }
7641
+ if (existingProcess.versions?.node) {
7642
+ return;
7643
+ }
7644
+ const existingProcessRecord = existingProcess;
7645
+ for (const [key, value] of Object.entries(browserProcess)) {
7646
+ existingProcessRecord[key] ??= value;
7647
+ }
7648
+ existingProcessRecord["browser"] = true;
7649
+ }
7650
+ (function initEsm() {
7651
+ ensureDisposeSymbols();
7652
+ ensureBrowserProcess();
7653
+ })();
7654
+ })();
7655
+ SpellcheckMode = /* @__PURE__ */ ((SpellcheckMode2) => {
7656
+ SpellcheckMode2["AlwaysOn"] = "AlwaysOn";
7657
+ SpellcheckMode2["FollowObsidianSetting"] = "FollowObsidianSetting";
7658
+ SpellcheckMode2["Off"] = "Off";
7659
+ return SpellcheckMode2;
7660
+ })(SpellcheckMode || {});
7661
+ }
7662
+ });
7663
+
7459
7664
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/components/component-ex.mjs
7460
7665
  var component_ex_exports = {};
7461
7666
  __export(component_ex_exports, {
@@ -8026,131 +8231,6 @@ var init_desktop_zip_extractor = __esm({
8026
8231
  }
8027
8232
  });
8028
8233
 
8029
- // node_modules/compare-versions/lib/umd/index.js
8030
- var require_umd = __commonJS({
8031
- "node_modules/compare-versions/lib/umd/index.js"(exports, module2) {
8032
- (function(global, factory) {
8033
- typeof exports === "object" && typeof module2 !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.compareVersions = {}));
8034
- })(exports, (function(exports2) {
8035
- "use strict";
8036
- const semver = /^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;
8037
- const validateAndParse = (version) => {
8038
- if (typeof version !== "string") {
8039
- throw new TypeError("Invalid argument expected string");
8040
- }
8041
- const match = version.match(semver);
8042
- if (!match) {
8043
- throw new Error(`Invalid argument not valid semver ('${version}' received)`);
8044
- }
8045
- match.shift();
8046
- return match;
8047
- };
8048
- const isWildcard = (s2) => s2 === "*" || s2 === "x" || s2 === "X";
8049
- const tryParse = (v) => {
8050
- const n2 = parseInt(v, 10);
8051
- return isNaN(n2) ? v : n2;
8052
- };
8053
- const forceType = (a2, b) => typeof a2 !== typeof b ? [String(a2), String(b)] : [a2, b];
8054
- const compareStrings = (a2, b) => {
8055
- if (isWildcard(a2) || isWildcard(b))
8056
- return 0;
8057
- const [ap, bp] = forceType(tryParse(a2), tryParse(b));
8058
- if (ap > bp)
8059
- return 1;
8060
- if (ap < bp)
8061
- return -1;
8062
- return 0;
8063
- };
8064
- const compareSegments = (a2, b) => {
8065
- for (let i2 = 0; i2 < Math.max(a2.length, b.length); i2++) {
8066
- const r2 = compareStrings(a2[i2] || "0", b[i2] || "0");
8067
- if (r2 !== 0)
8068
- return r2;
8069
- }
8070
- return 0;
8071
- };
8072
- const compareVersions5 = (v1, v2) => {
8073
- const n1 = validateAndParse(v1);
8074
- const n2 = validateAndParse(v2);
8075
- const p1 = n1.pop();
8076
- const p2 = n2.pop();
8077
- const r2 = compareSegments(n1, n2);
8078
- if (r2 !== 0)
8079
- return r2;
8080
- if (p1 && p2) {
8081
- return compareSegments(p1.split("."), p2.split("."));
8082
- } else if (p1 || p2) {
8083
- return p1 ? -1 : 1;
8084
- }
8085
- return 0;
8086
- };
8087
- const compare = (v1, v2, operator) => {
8088
- assertValidOperator(operator);
8089
- const res = compareVersions5(v1, v2);
8090
- return operatorResMap[operator].includes(res);
8091
- };
8092
- const operatorResMap = {
8093
- ">": [1],
8094
- ">=": [0, 1],
8095
- "=": [0],
8096
- "<=": [-1, 0],
8097
- "<": [-1],
8098
- "!=": [-1, 1]
8099
- };
8100
- const allowedOperators = Object.keys(operatorResMap);
8101
- const assertValidOperator = (op) => {
8102
- if (typeof op !== "string") {
8103
- throw new TypeError(`Invalid operator type, expected string but got ${typeof op}`);
8104
- }
8105
- if (allowedOperators.indexOf(op) === -1) {
8106
- throw new Error(`Invalid operator, expected one of ${allowedOperators.join("|")}`);
8107
- }
8108
- };
8109
- const satisfies = (version, range) => {
8110
- range = range.replace(/([><=]+)\s+/g, "$1");
8111
- if (range.includes("||")) {
8112
- return range.split("||").some((r5) => satisfies(version, r5));
8113
- } else if (range.includes(" - ")) {
8114
- const [a2, b] = range.split(" - ", 2);
8115
- return satisfies(version, `>=${a2} <=${b}`);
8116
- } else if (range.includes(" ")) {
8117
- return range.trim().replace(/\s{2,}/g, " ").split(" ").every((r5) => satisfies(version, r5));
8118
- }
8119
- const m = range.match(/^([<>=~^]+)/);
8120
- const op = m ? m[1] : "=";
8121
- if (op !== "^" && op !== "~")
8122
- return compare(version, range, op);
8123
- const [v1, v2, v3, , vp] = validateAndParse(version);
8124
- const [r1, r2, r3, , rp] = validateAndParse(range);
8125
- const v = [v1, v2, v3];
8126
- const r4 = [r1, r2 !== null && r2 !== void 0 ? r2 : "x", r3 !== null && r3 !== void 0 ? r3 : "x"];
8127
- if (rp) {
8128
- if (!vp)
8129
- return false;
8130
- if (compareSegments(v, r4) !== 0)
8131
- return false;
8132
- if (compareSegments(vp.split("."), rp.split(".")) === -1)
8133
- return false;
8134
- }
8135
- const nonZero = r4.findIndex((v4) => v4 !== "0") + 1;
8136
- const i2 = op === "~" ? 2 : nonZero > 1 ? nonZero : 1;
8137
- if (compareSegments(v.slice(0, i2), r4.slice(0, i2)) !== 0)
8138
- return false;
8139
- if (compareSegments(v.slice(i2), r4.slice(i2)) === -1)
8140
- return false;
8141
- return true;
8142
- };
8143
- const validate = (version) => typeof version === "string" && /^[v\d]/.test(version) && semver.test(version);
8144
- const validateStrict = (version) => typeof version === "string" && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(version);
8145
- exports2.compare = compare;
8146
- exports2.compareVersions = compareVersions5;
8147
- exports2.satisfies = satisfies;
8148
- exports2.validate = validate;
8149
- exports2.validateStrict = validateStrict;
8150
- }));
8151
- }
8152
- });
8153
-
8154
8234
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/community-plugins.mjs
8155
8235
  var community_plugins_exports = {};
8156
8236
  __export(community_plugins_exports, {
@@ -8474,6 +8554,92 @@ var init_css_class = __esm({
8474
8554
  }
8475
8555
  });
8476
8556
 
8557
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/html-element.mjs
8558
+ var html_element_exports = {};
8559
+ __export(html_element_exports, {
8560
+ appendCodeBlock: () => appendCodeBlock,
8561
+ appendTextOrFragmentClone: () => appendTextOrFragmentClone,
8562
+ applySpellcheckMode: () => applySpellcheckMode,
8563
+ asCodeBlock: () => asCodeBlock,
8564
+ createFragmentWithCodeBlocks: () => createFragmentWithCodeBlocks
8565
+ });
8566
+ function appendCodeBlock(element2, code3) {
8567
+ element2.createEl("strong", { cls: `${CssClass.MarkdownRendered} ${CssClass.Code}` }, (strong2) => {
8568
+ strong2.createEl("code", { text: code3 });
8569
+ });
8570
+ }
8571
+ function appendTextOrFragmentClone(element2, content3) {
8572
+ element2.append(typeof content3 === "string" ? content3 : content3.cloneNode(true));
8573
+ }
8574
+ function applySpellcheckMode(params) {
8575
+ const {
8576
+ app,
8577
+ element: element2,
8578
+ spellcheckMode = SpellcheckMode.Off
8579
+ } = params;
8580
+ element2.setAttribute("spellcheck", String(isSpellcheckEnabledForMode(app, spellcheckMode)));
8581
+ }
8582
+ function asCodeBlock(value) {
8583
+ return `${CODE_BLOCK_DELIMITER}${value}${CODE_BLOCK_DELIMITER}`;
8584
+ }
8585
+ function createFragmentWithCodeBlocks(message) {
8586
+ const fragment = createFragment();
8587
+ let isCodeSegment = false;
8588
+ for (const segment of message.split(CODE_BLOCK_DELIMITER)) {
8589
+ if (segment !== "") {
8590
+ if (isCodeSegment) {
8591
+ appendCodeBlock(fragment, segment);
8592
+ } else {
8593
+ fragment.appendText(segment);
8594
+ }
8595
+ }
8596
+ isCodeSegment = !isCodeSegment;
8597
+ }
8598
+ return fragment;
8599
+ }
8600
+ var PRIVATE_USE_AREA_FIRST_CODE_POINT, CODE_BLOCK_DELIMITER;
8601
+ var init_html_element = __esm({
8602
+ "node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/html-element.mjs"() {
8603
+ init_css_class();
8604
+ init_obsidian_settings();
8605
+ (function() {
8606
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
8607
+ symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
8608
+ symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
8609
+ }
8610
+ function ensureBrowserProcess() {
8611
+ const browserProcess = {
8612
+ browser: true,
8613
+ cwd() {
8614
+ return "/";
8615
+ },
8616
+ env: {},
8617
+ platform: "android"
8618
+ };
8619
+ const existingProcess = globalThis.process;
8620
+ if (!existingProcess) {
8621
+ globalThis.process = browserProcess;
8622
+ return;
8623
+ }
8624
+ if (existingProcess.versions?.node) {
8625
+ return;
8626
+ }
8627
+ const existingProcessRecord = existingProcess;
8628
+ for (const [key, value] of Object.entries(browserProcess)) {
8629
+ existingProcessRecord[key] ??= value;
8630
+ }
8631
+ existingProcessRecord["browser"] = true;
8632
+ }
8633
+ (function initEsm() {
8634
+ ensureDisposeSymbols();
8635
+ ensureBrowserProcess();
8636
+ })();
8637
+ })();
8638
+ PRIVATE_USE_AREA_FIRST_CODE_POINT = 57344;
8639
+ CODE_BLOCK_DELIMITER = String.fromCodePoint(PRIVATE_USE_AREA_FIRST_CODE_POINT);
8640
+ }
8641
+ });
8642
+
8477
8643
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/generated-during-build.mjs
8478
8644
  var generated_during_build_exports = {};
8479
8645
  __export(generated_during_build_exports, {
@@ -8516,7 +8682,7 @@ var init_generated_during_build = __esm({
8516
8682
  ensureBrowserProcess();
8517
8683
  })();
8518
8684
  })();
8519
- LIBRARY_VERSION = "1.0.0";
8685
+ LIBRARY_VERSION = "3.1.0";
8520
8686
  LIBRARY_STYLES = `.obsidian-dev-utils.code-highlighter-component textarea, .obsidian-dev-utils.code-highlighter-component pre, .obsidian-dev-utils.code-highlighter-component code {
8521
8687
  font-family: var(--font-monospace);
8522
8688
  line-height: var(--line-height-normal);
@@ -8884,6 +9050,9 @@ progress.obsidian-dev-utils.loop {
8884
9050
  font-weight: var(--font-bold);
8885
9051
  margin-bottom: var(--size-4-2);
8886
9052
  }
9053
+ .obsidian-dev-utils.plugin-notice-name code {
9054
+ color: inherit;
9055
+ }
8887
9056
  .obsidian-dev-utils.plugin-notice-content {
8888
9057
  padding-right: var(--size-4-5);
8889
9058
  position: relative;
@@ -9013,7 +9182,7 @@ progress.obsidian-dev-utils.loop {
9013
9182
  width: max-content;
9014
9183
  }
9015
9184
 
9016
- /*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,%22sourceRoot%22:%22%22,%22sources%22:%5B%22../src/styles/code-highlighter-component.scss%22,%22../src/styles/editor-lock.scss%22,%22../src/styles/input.scss%22,%22../src/styles/input-time.scss%22,%22../src/styles/loop.scss%22,%22../src/styles/minimizable-modal.scss%22,%22../src/styles/modal-commands.scss%22,%22../src/styles/modal-container.scss%22,%22../src/styles/multiple-dropdown-component.scss%22,%22../src/styles/plugin-notice.scss%22,%22../src/styles/plugin-settings-tab.scss%22,%22../src/styles/plugin-suggestion.scss%22,%22../src/styles/popover.scss%22,%22../src/styles/prompt-modal.scss%22,%22../src/styles/tldraw-button-color-workaround.scss%22,%22../src/styles/tri-state-checkbox-component.scss%22,%22../src/styles/validation.scss%22%5D,%22names%22:%5B%5D,%22mappings%22:%22AAEI;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;;ACvCN;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAMJ;EACE;IACE;IACA;;;AAIJ;EACE;;;ACvBA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;AAAA;AAAA;AAAA;AAAA;IACE;IACA,YACE;;;AAMR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;EACA,YACE;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;AAAA;EACE;;AASE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;;AC7DV;AAAA;AAAA;EAGE;EACA;;AAEA;AAAA;AAAA;EACE;EACA;;AAGF;AAAA;AAAA;EACE;EACA;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAIK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGP;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;;AAKF;AAAA;AAAA;EACE;;;AAMJ;EACE;;;AC/CK;EACP;;;ACJJ;EACE;IAEE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AAOA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AASN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAOA;EACE;;AAOF;EACE;;AAGF;EACE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;EACA;;;ACpGN;EACE;EACA;EACA;EACA;EACA;;AAOF;EACE;EACA;;AAMF;EACE;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAIJ;EACE;EACA;;AAGA;EACE;EACA;;;ACpEF;EACE;EACA;;;ACCF;AAAA;AAAA;EAGE;EACA;;AAEA;AAAA;AAAA;EACE;EACA;;;ACZN;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAOJ;EACE;;AAEA;EACE;;;AChCF;EACE;;;ACFJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;ACRJ;EAIE;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AC9BF;EACE;;;ACUN;EACE;;;ACZE;EACE;;;ACKJ;EAPA;;AAuBI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAvBJ;;AA6BA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA%22,%22file%22:%22styles.css%22,%22sourcesContent%22:%5B%22.obsidian-dev-utils%20%7B%5Cn%20%20&.code-highlighter-component%20%7B%5Cn%20%20%20%20textarea,%20pre,%20code%20%7B%5Cn%20%20%20%20%20%20font-family:%20var(--font-monospace);%5Cn%20%20%20%20%20%20line-height:%20var(--line-height-normal);%5Cn%20%20%20%20%20%20margin:%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20textarea,%20code%20%7B%5Cn%20%20%20%20%20%20font-size:%20var(--code-size);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20textarea%20%7B%5Cn%20%20%20%20%20%20background:%20transparent;%5Cn%20%20%20%20%20%20color:%20transparent;%5Cn%20%20%20%20%20%20z-index:%202;%5Cn%20%20%20%20%20%20width:%2020em;%5Cn%20%20%20%20%20%20height:%2010em;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20pre%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20pointer-events:%20none;%5Cn%20%20%20%20%20%20border:%20var(--input-border-width)%20solid%20transparent;%5Cn%20%20%20%20%20%20overflow:%20auto;%5Cn%20%20%20%20%20%20inset:%200;%5Cn%20%20%20%20%20%20padding:%20var(--size-4-1)%20var(--size-4-2);%5Cn%20%20%20%20%20%20z-index:%201;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20pre::after%20%7B%5Cn%20%20%20%20%20%20content:%20%5C%22%5C%22;%5Cn%20%20%20%20%20%20display:%20block;%5Cn%20%20%20%20%20%20height:%20var(--bottom-gap,%200);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20pre.is-placeholder%20%7B%5Cn%20%20%20%20%20%20opacity:%200.6;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20code%20%7B%5Cn%20%20%20%20%20%20display:%20block;%5Cn%20%20%20%20%20%20padding:%200;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22//%20Lock%20indicators%20shown%20in%20the%20tab%20header%20and%20the%20status%20bar%20while%20a%20note%20is%20locked.%20These%20live%20in%5Cn//%20global%20Obsidian%20DOM%20(tab%20header%20/%20status%20bar),%20so%20they%20are%20styled%20with%20a%20global%20class%20rather%20than%5Cn//%20scoped%20under%20%60.obsidian-dev-utils%60.%5Cn.obsidian-dev-utils-lock-indicator%20%7B%5Cn%20%20display:%20inline-flex;%5Cn%20%20align-items:%20center;%5Cn%20%20color:%20var(--text-muted);%5Cn%5Cn%20%20.svg-icon%20%7B%5Cn%20%20%20%20width:%20var(--icon-s);%5Cn%20%20%20%20height:%20var(--icon-s);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn//%20Flashed%20on%20every%20lock%20indicator%20(tab%20header,%20view%20action,%20status%20bar)%20when%20the%20user%20attempts%20to%5Cn//%20type%20in%20a%20locked%20note,%20to%20make%20clear%20the%20note%20is%20read-only.%20Re-added%20per%20rejected%20keystroke.%5Cn@keyframes%20obsidian-dev-utils-lock-indicator-flash%20%7B%5Cn%20%2040%25%20%7B%5Cn%20%20%20%20color:%20var(--text-error);%5Cn%20%20%20%20transform:%20scale(1.4);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn.obsidian-dev-utils-lock-indicator-flash%20%7B%5Cn%20%20animation:%20obsidian-dev-utils-lock-indicator-flash%200.35s%20ease-in-out;%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20input%5Btype='url'%5D%20%7B%5Cn%20%20%20%20height:%20var(--input-height)%5Cn%20%20%7D%5Cn%5Cn%20%20input%5Btype='month'%5D,%5Cn%20%20input%5Btype='tel'%5D,%5Cn%20%20input%5Btype='time'%5D,%5Cn%20%20input%5Btype='url'%5D,%5Cn%20%20input%5Btype='week'%5D%20%7B%5Cn%20%20%20%20-webkit-app-region:%20no-drag;%5Cn%20%20%20%20background:%20var(--background-modifier-form-field);%5Cn%20%20%20%20border:%20var(--input-border-width)%20solid%20var(--background-modifier-border);%5Cn%20%20%20%20color:%20var(--text-normal);%5Cn%20%20%20%20font-family:%20inherit;%5Cn%20%20%20%20padding:%20var(--size-4-1)%20var(--size-4-2);%5Cn%20%20%20%20font-size:%20var(--font-ui-small);%5Cn%20%20%20%20border-radius:%20var(--input-radius);%5Cn%20%20%20%20outline:%20none;%5Cn%5Cn%20%20%20%20@at-root%20%7B%5Cn%20%20%20%20%20%20@media%20(hover:%20hover)%20%7B%5Cn%20%20%20%20%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20border-color:%20var(--background-modifier-border-hover);%5Cn%20%20%20%20%20%20%20%20%20%20transition:%5Cn%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%200.15s%20ease-in-out,%5Cn%20%20%20%20%20%20%20%20%20%20%20%20border%200.15s%20ease-in-out;%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&:active,%5Cn%20%20%20%20&:focus%20%7B%5Cn%20%20%20%20%20%20border-color:%20var(--background-modifier-border-focus);%5Cn%20%20%20%20%20%20transition:%5Cn%20%20%20%20%20%20%20%20box-shadow%200.15s%20ease-in-out,%5Cn%20%20%20%20%20%20%20%20border%200.15s%20ease-in-out;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&:active,%5Cn%20%20%20%20&:focus,%5Cn%20%20%20%20&:focus-visible%20%7B%5Cn%20%20%20%20%20%20box-shadow:%200%200%200%202px%20var(--background-modifier-border-focus);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&::placeholder%20%7B%5Cn%20%20%20%20%20%20color:%20var(--text-faint);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20@at-root%20%7B%5Cn%20%20%20%20.mod-rtl,%5Cn%20%20%20%20.is-rtl,%5Cn%20%20%20%20.rtl%20%7B%5Cn%20%20%20%20%20%20&%20%7B%5Cn%20%20%20%20%20%20%20%20input%5Btype='month'%5D,%5Cn%20%20%20%20%20%20%20%20input%5Btype='time'%5D,%5Cn%20%20%20%20%20%20%20%20input%5Btype='week'%5D%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20direction:%20rtl;%5Cn%5Cn%20%20%20%20%20%20%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20right:%20var(--size-4-1);%5Cn%20%20%20%20%20%20%20%20%20%20%20%20left:%20auto;%5Cn%20%20%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20input%5Btype='month'%5D,%5Cn%20%20input%5Btype='time'%5D,%5Cn%20%20input%5Btype='week'%5D%20%7B%5Cn%20%20%20%20font-variant-numeric:%20tabular-nums;%5Cn%20%20%20%20position:%20relative;%5Cn%5Cn%20%20%20%20&::-webkit-datetime-edit-text%20%7B%5Cn%20%20%20%20%20%20color:%20var(--text-faint);%5Cn%20%20%20%20%20%20padding-inline-end:%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20left:%20var(--size-4-1);%5Cn%20%20%20%20%20%20right:%20auto;%5Cn%20%20%20%20%20%20opacity:%200.5;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&::-webkit-datetime-edit-month-field,%5Cn%20%20%20%20&::-webkit-datetime-edit-day-field,%5Cn%20%20%20%20&::-webkit-datetime-edit-year-field%20%7B%5Cn%20%20%20%20%20%20&:active,%5Cn%20%20%20%20%20%20&:focus%20%7B%5Cn%20%20%20%20%20%20%20%20background-color:%20var(--text-selection);%5Cn%20%20%20%20%20%20%20%20color:%20var(--text-normal);%5Cn%20%20%20%20%20%20%20%20cursor:%20text;%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20@at-root%20.mod-rtl%20&,%5Cn%20%20%20%20%20%20.is-rtl%20&,%5Cn%20%20%20%20%20%20.rtl%20&%20%7B%5Cn%20%20%20%20%20%20direction:%20rtl;%5Cn%5Cn%20%20%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20%20%20left:%20auto;%5Cn%20%20%20%20%20%20%20%20right:%20var(--size-4-1);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20@at-root%20%7B%5Cn%20%20%20%20%20%20body:not(.is-ios):not(.is-android)%20&%20%7B%5Cn%20%20%20%20%20%20%20%20padding-inline-start:%20var(--size-4-6);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20input%5Btype='time'%5D%20%7B%5Cn%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20margin-inline-start:%200;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20//%20Not%20%60&progress%60:%20that%20APPENDS%20the%20element%20name%20to%20the%20parent%20class,%20producing%20one%20long%20class%20that%20matches%5Cn%20%20//%20nothing.%20The%20element%20type%20has%20to%20lead%20the%20compound%20selector%20instead.%5Cn%20%20@at-root%20progress%23%7B&%7D.loop%20%7B%5Cn%20%20%20%20min-width:%20200px;%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22@keyframes%20obsidian-dev-utils-minimized-modal-bar-pulse%20%7B%5Cn%20%200%25,%5Cn%20%20100%25%20%7B%5Cn%20%20%20%20box-shadow:%20var(--shadow-s);%5Cn%20%20%7D%5Cn%5Cn%20%2050%25%20%7B%5Cn%20%20%20%20box-shadow:%200%200%200%202px%20var(--interactive-accent);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn@keyframes%20obsidian-dev-utils-minimized-modal-bar-attention%20%7B%5Cn%20%200%25%20%7B%5Cn%20%20%20%20box-shadow:%200%200%200%200%20var(--interactive-accent);%5Cn%20%20%7D%5Cn%5Cn%20%2040%25%20%7B%5Cn%20%20%20%20box-shadow:%200%200%200%204px%20var(--interactive-accent);%5Cn%20%20%7D%5Cn%5Cn%20%20100%25%20%7B%5Cn%20%20%20%20box-shadow:%20var(--shadow-s);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn.obsidian-dev-utils%20%7B%5Cn%20%20//%20The%20minimize%20button%20lives%20inside%20the%20modal%20container,%20left%20of%20Obsidian's%20close%20button.%5Cn%20%20&.minimizable-modal%20%7B%5Cn%20%20%20%20.minimize-button%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20top:%20var(--size-4-2);%5Cn%20%20%20%20%20%20right:%20calc(var(--size-4-2)%20+%20var(--size-4-9));%5Cn%20%20%20%20%20%20display:%20flex;%5Cn%20%20%20%20%20%20align-items:%20center;%5Cn%20%20%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20%20%20padding:%20var(--size-2-2);%5Cn%20%20%20%20%20%20border:%20none;%5Cn%20%20%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20%20%20background:%20transparent;%5Cn%20%20%20%20%20%20color:%20var(--icon-color);%5Cn%20%20%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20%20%20box-shadow:%20none;%5Cn%5Cn%20%20%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--background-modifier-hover);%5Cn%20%20%20%20%20%20%20%20color:%20var(--icon-color-hover);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20//%20The%20minimized%20bar%20is%20appended%20to%20document.body.%20It%20floats%20at%20the%20bottom-right%20while%20minimized,%5Cn%20%20//%20and%20gently%20pulses%20an%20accent%20ring%20so%20the%20user%20does%20not%20forget%20about%20the%20minimized%20operation.%5Cn%20%20//%20It%20floats%20a%20status-bar's%20height%20above%20the%20bottom%20edge%20so%20it%20never%20covers%20the%20bottom-right%5Cn%20%20//%20status-bar%20items%20(e.g.%20the%20editor-lock%20unlock%20indicator,%20which%20lives%20in%20the%20same%20corner).%5Cn%20%20&.minimized-modal-bar%20%7B%5Cn%20%20%20%20position:%20fixed;%5Cn%20%20%20%20right:%20var(--size-4-4);%5Cn%20%20%20%20bottom:%20calc(var(--size-4-4)%20+%20var(--size-4-8));%5Cn%20%20%20%20z-index:%20var(--layer-modal);%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20gap:%20var(--size-4-2);%5Cn%20%20%20%20padding:%20var(--size-4-2)%20var(--size-4-3);%5Cn%20%20%20%20border:%201px%20solid%20var(--background-modifier-border);%5Cn%20%20%20%20border-radius:%20var(--radius-m);%5Cn%20%20%20%20background:%20var(--background-secondary);%5Cn%20%20%20%20box-shadow:%20var(--shadow-s);%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20animation:%20obsidian-dev-utils-minimized-modal-bar-pulse%202s%20ease-in-out%20infinite;%5Cn%5Cn%20%20%20%20//%20Layer%20the%20translucent%20hover%20tint%20over%20the%20opaque%20%60background%60%20(%60--background-secondary%60)%20via%5Cn%20%20%20%20//%20%60background-image%60%20instead%20of%20replacing%20the%20background-color.%20%60--background-modifier-hover%60%20is%5Cn%20%20%20%20//%20translucent,%20so%20setting%20it%20as%20%60background%60%20would%20let%20the%20editor%20content%20behind%20the%20floating%20bar%5Cn%20%20%20%20//%20bleed%20through%20and%20make%20the%20title%20unreadable.%20A%20gradient%20of%20the%20tint%20composited%20over%20the%20opaque%5Cn%20%20%20%20//%20base%20keeps%20the%20bar%20opaque%20while%20preserving%20the%20subtle%20hover%20highlight.%5Cn%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20background-image:%20linear-gradient(var(--background-modifier-hover),%20var(--background-modifier-hover));%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20A%20one-shot,%20more%20pronounced%20flash%20played%20when%20the%20user%20attempts%20a%20blocked%20action%20(a%20keystroke,%5Cn%20%20%20%20//%20right-click,%20or%20opening%20another%20modal)%20while%20this%20modal%20is%20minimized,%20so%20the%20block%20is%20not%5Cn%20%20%20%20//%20silent.%20Its%20higher%20specificity%20overrides%20the%20gentle%20infinite%20idle%20pulse%20while%20it%20plays;%20the%5Cn%20%20%20%20//%20class%20is%20removed%20on%20%60animationend%60,%20restoring%20the%20idle%20pulse.%5Cn%20%20%20%20&.minimized-modal-bar-attention%20%7B%5Cn%20%20%20%20%20%20animation:%20obsidian-dev-utils-minimized-modal-bar-attention%200.35s%20ease-out;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.minimized-modal-bar-title%20%7B%5Cn%20%20%20%20%20%20font-weight:%20var(--font-medium);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.restore-button,%5Cn%20%20%20%20.cancel-button%20%7B%5Cn%20%20%20%20%20%20display:%20flex;%5Cn%20%20%20%20%20%20align-items:%20center;%5Cn%20%20%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20%20%20padding:%20var(--size-2-2);%5Cn%20%20%20%20%20%20border:%20none;%5Cn%20%20%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20%20%20background:%20transparent;%5Cn%20%20%20%20%20%20color:%20var(--icon-color);%5Cn%20%20%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20%20%20box-shadow:%20none;%5Cn%5Cn%20%20%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--background-modifier-hover);%5Cn%20%20%20%20%20%20%20%20color:%20var(--icon-color-hover);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20//%20The%20strip%20of%20commands%20along%20the%20bottom%20of%20a%20modal.%5Cn%20%20//%5Cn%20%20//%20In%20%60Instructions%60%20render%20mode%20it%20also%20carries%20Obsidian's%20own%20%60.prompt-instructions%60%20%E2%80%94%20whose%20rule%20is%5Cn%20%20//%20unscoped,%20so%20it%20applies%20to%20a%20plain%20%60Modal%60%20too%20%E2%80%94%20and%20this%20one%20only%20re-tunes%20that%20rule's%20%60gap%60%20and%5Cn%20%20//%20%60padding%60%20and%20adds%20the%20separator;%20in%20%60Buttons%60%20mode%20it%20is%20the%20whole%20strip.%5Cn%20%20&.modal-commands%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20flex-wrap:%20wrap;%5Cn%20%20%20%20gap:%20var(--size-2-2);%5Cn%20%20%20%20padding:%20var(--size-4-2)%20var(--size-4-3);%5Cn%20%20%20%20border-top:%201px%20solid%20var(--background-modifier-border);%5Cn%20%20%7D%5Cn%5Cn%20%20//%20A%20control%20the%20%60Instructions%60%20renderer%20injects%20into%20an%20instruction's%20purpose%20text%20%E2%80%94%20a%20checkbox,%20a%5Cn%20%20//%20dropdown.%20Obsidian%20styles%20the%20instruction%20bar%20itself,%20but%20its%20own%20bar%20never%20contains%20a%20control,%20so%5Cn%20%20//%20nothing%20upstream%20separates%20one%20from%20the%20label%20it%20belongs%20to.%20Sits%20on%20the%20control%20rather%20than%20on%20the%5Cn%20%20//%20strip,%20so%20it%20reaches%20a%20%60SuggestModal%60's%20native%20bar%20as%20well%20as%20a%20self-created%20one.%5Cn%20%20&.modal-command-control%20%7B%5Cn%20%20%20%20margin-inline-start:%20var(--size-2-2);%5Cn%20%20%20%20vertical-align:%20middle;%5Cn%20%20%7D%5Cn%5Cn%20%20//%20One%20command%20button.%20Replaces%20the%20instruction%20bar%20rather%20than%20supplementing%20it:%20the%20bar%20can%20only%20ever%5Cn%20%20//%20say%20which%20key%20to%20press,%20and%20on%20a%20phone%20there%20is%20no%20modifier%20key%20to%20press,%20so%20every%20control%20it%20names%5Cn%20%20//%20is%20unreachable%20there.%5Cn%20%20&.modal-command%20%7B%5Cn%20%20%20%20display:%20inline-flex;%5Cn%20%20%20%20align-items:%20baseline;%5Cn%20%20%20%20gap:%20var(--size-2-2);%5Cn%5Cn%20%20%20%20//%20Comfortably%20tappable%20on%20a%20phone,%20where%20this%20strip%20is%20the%20only%20way%20in.%5Cn%20%20%20%20min-height:%20var(--size-4-8);%5Cn%20%20%20%20padding:%20var(--size-2-1)%20var(--size-4-2);%5Cn%20%20%20%20border:%201px%20solid%20var(--background-modifier-border);%5Cn%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20background-color:%20var(--background-secondary);%5Cn%20%20%20%20color:%20var(--text-muted);%5Cn%20%20%20%20font-size:%20var(--font-ui-smaller);%5Cn%20%20%20%20white-space:%20nowrap;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%5Cn%20%20%20%20&:hover:not(:disabled)%20%7B%5Cn%20%20%20%20%20%20background-color:%20var(--background-modifier-hover);%5Cn%20%20%20%20%20%20color:%20var(--text-normal);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20A%20toggle%20that%20is%20ON.%20An%20action%20never%20carries%20it%20%E2%80%94%20it%20does%20something%20and%20is%20done,%20so%20there%20is%20no%5Cn%20%20%20%20//%20state%20for%20it%20to%20show.%5Cn%20%20%20%20&.is-active%20%7B%5Cn%20%20%20%20%20%20border-color:%20var(--interactive-accent);%5Cn%20%20%20%20%20%20background-color:%20var(--interactive-accent);%5Cn%20%20%20%20%20%20color:%20var(--text-on-accent);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20Disabled%20rather%20than%20removed:%20a%20strip%20that%20lost%20buttons%20as%20modes%20change%20would%20reflow%20under%20the%5Cn%20%20%20%20//%20pointer,%20which%20on%20a%20phone%20means%20a%20mis-tap.%5Cn%20%20%20%20&:disabled%20%7B%5Cn%20%20%20%20%20%20opacity:%200.5;%5Cn%20%20%20%20%20%20cursor:%20default;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20&.modal-command-hotkey%20%7B%5Cn%20%20%20%20color:%20var(--text-faint);%5Cn%20%20%20%20font-size:%20var(--font-smallest);%5Cn%5Cn%20%20%20%20//%20Faint%20against%20the%20surface%20is%20right;%20faint%20against%20the%20accent%20fill%20is%20invisible.%5Cn%20%20%20%20.modal-command.is-active%20&%20%7B%5Cn%20%20%20%20%20%20opacity:%200.7;%5Cn%20%20%20%20%20%20color:%20var(--text-on-accent);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.modal-container%20%7B%5Cn%20%20%20%20.ok-button%20%7B%5Cn%20%20%20%20%20%20margin-right:%2010px;%5Cn%20%20%20%20%20%20margin-top:%2020px;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20//%20Compound,%20not%20nested:%20%60addPluginCssClasses%60%20puts%20%60obsidian-dev-utils%60%20and%20%60multiple-dropdown-component%60%20on%20the%5Cn%20%20//%20SAME%20element%20(the%20setting's%20control%20container),%20so%20a%20descendant%20selector%20matched%20nothing%20and%20every%20multiple%5Cn%20%20//%20dropdown%20rendered%20one%20row%20tall%20%E2%80%94%20Obsidian's%20%60.dropdown%60%20height,%20with%20no%20popup%20behind%20it%20to%20pick%20from.%5Cn%20%20&.multiple-dropdown-component%20%7B%5Cn%20%20%20%20select,%5Cn%20%20%20%20select:focus,%5Cn%20%20%20%20.dropdown%20%7B%5Cn%20%20%20%20%20%20height:%20auto;%5Cn%20%20%20%20%20%20padding-top:%203px;%5Cn%5Cn%20%20%20%20%20%20option:checked%20%7B%5Cn%20%20%20%20%20%20%20%20background-color:%20var(--interactive-accent);%5Cn%20%20%20%20%20%20%20%20color:%20var(--text-on-accent);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.plugin-notice-name%20%7B%5Cn%20%20%20%20color:%20var(--text-accent);%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20font-weight:%20var(--font-bold);%5Cn%20%20%20%20margin-bottom:%20var(--size-4-2);%5Cn%20%20%7D%5Cn%5Cn%20%20&.plugin-notice-content%20%7B%5Cn%20%20%20%20padding-right:%20var(--size-4-5);%5Cn%20%20%20%20position:%20relative;%5Cn%5Cn%20%20%20%20.obsidian-dev-utils.cancel-button%20%7B%5Cn%20%20%20%20%20%20display:%20block;%5Cn%20%20%20%20%20%20margin-top:%20var(--size-4-2);%5Cn%20%20%20%20%20%20width:%20fit-content;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20The%20close%20button%20reuses%20Obsidian's%20%60modal-header-button%60%20+%20%60clickable-icon%60%20classes%20so%20it%20matches%5Cn%20%20%20%20//%20The%20native%20modal%20close%20button%20(box%20+%20hover);%20only%20its%20corner%20position%20is%20set%20here.%5Cn%20%20%20%20.obsidian-dev-utils.plugin-notice-close-button%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20right:%20var(--size-4-3);%5Cn%20%20%20%20%20%20top:%20var(--size-4-3);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20//%20Move%20the%20notice's%20own%20padding%20onto%20the%20content%20wrapper%20so%20the%20wrapper%20covers%20the%20whole%20clickable%5Cn%20%20//%20Area%20%E2%80%94%20otherwise%20a%20click%20landing%20on%20the%20notice's%20bare%20padding%20(outside%20the%20wrapper)%20would%20bypass%20the%5Cn%20%20//%20Stop-propagation%20guard%20and%20dismiss%20the%20hard-to-close%20notice.%5Cn%20%20&.plugin-notice-requires-explicit-close.notice%20%7B%5Cn%20%20%20%20padding:%200;%5Cn%5Cn%20%20%20%20.obsidian-dev-utils.plugin-notice-content%20%7B%5Cn%20%20%20%20%20%20padding:%20var(--size-4-3)%20var(--size-4-4);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.plugin-settings-tab%20%7B%5Cn%20%20%20%20a:focus%20%7B%5Cn%20%20%20%20%20%20outline:%202px%20solid%20var(--link-color);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.plugin-suggestion-banner%20%7B%5Cn%20%20%20%20background-color:%20var(--background-secondary);%5Cn%20%20%20%20border-left:%20var(--size-2-1)%20solid%20var(--text-accent);%5Cn%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20flex-direction:%20column;%5Cn%20%20%20%20gap:%20var(--size-4-2);%5Cn%20%20%20%20margin-bottom:%20var(--size-4-4);%5Cn%20%20%20%20padding:%20var(--size-4-3)%20var(--size-4-4);%5Cn%5Cn%20%20%20%20button%20%7B%5Cn%20%20%20%20%20%20width:%20fit-content;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22//%20A%20popover%20is%20anchored%20at%20a%20point%20and%20appended%20to%20the%20document%20body,%20outside%20any%20plugin-scoped%5Cn//%20container,%20so%20it%20is%20positioned%20absolutely%20at%20the%20top%20level.%20It%20borrows%20Obsidian's%20%60.menu%60%20look,%5Cn//%20which%20already%20carries%20the%20popup%20background,%20border%20and%20shadow%20%E2%80%94%20only%20layout%20is%20set%20here.%5Cn.obsidian-dev-utils%20%7B%5Cn%20%20&.popover%20%7B%5Cn%20%20%20%20//%20Deliberately%20not%20%60calc(100vw%20-%2016px)%60:%20the%20SCSS%20compiler%20strips%20the%20%60calc(%60%20wrapper%20inside%5Cn%20%20%20%20//%20%60min()%60,%20which%20yields%20invalid%20CSS.%20A%20viewport%20percentage%20keeps%20a%20narrow%20window's%20popover%20on%5Cn%20%20%20%20//%20screen.%5Cn%20%20%20%20max-width:%20min(420px,%2090vw);%5Cn%20%20%20%20min-width:%20320px;%5Cn%20%20%20%20padding:%20var(--size-4-2)%20var(--size-4-3);%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20z-index:%20var(--layer-menu);%5Cn%5Cn%20%20%20%20//%20Setting%20rows%20are%20built%20for%20a%20full-width%20settings%20tab;%20compact%20them%20for%20a%20popover.%5Cn%20%20%20%20.setting-item%20%7B%5Cn%20%20%20%20%20%20align-items:%20center;%5Cn%20%20%20%20%20%20border-top:%20none;%5Cn%20%20%20%20%20%20gap:%20var(--size-4-2);%5Cn%20%20%20%20%20%20padding:%20var(--size-2-1)%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.setting-item-info%20%7B%5Cn%20%20%20%20%20%20margin-right:%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.setting-item-control%20%7B%5Cn%20%20%20%20%20%20flex-grow:%201;%5Cn%20%20%20%20%20%20justify-content:%20flex-end;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20input%5Btype='text'%5D%20%7B%5Cn%20%20%20%20%20%20width:%20100%25;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.prompt-modal%20%7B%5Cn%20%20%20%20.text-box%20%7B%5Cn%20%20%20%20%20%20width:%20100%25;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22//%20The%20tldraw%20Obsidian%20plugin%20(tldraw/obsidian-plugin)%20ships%20an%20unscoped%20global%20rule%5Cn//%20%60button:not(.clickable-icon)%20%7B%20color:%20currentColor%20%7D%60%20that%20overrides%20Obsidian's%20own%5Cn//%20%60button:not(.clickable-icon)%20%7B%20color:%20var(--text-color)%20%7D%60%20app-wide.%20Obsidian%20sets%5Cn//%20%60--text-color%60%20contextually%20per%20button%20variant%20(%60--text-normal%60%20by%20default,%5Cn//%20%60--text-on-accent%60%20for%20%60.mod-cta%60,%20%60--text-error%60%20for%20%60.mod-warning%60),%20so%20tldraw's%5Cn//%20%60currentColor%60%20discards%20that%20and%20breaks%20button%20contrast%20outside%20tldraw%20%E2%80%94%20e.g.%5Cn//%20White-on-white%20action%20buttons%20inside%20a%20Notice.%20Re-assert%20Obsidian's%20own%20value%20inside%20the%5Cn//%20Library's%20own%20UI%20(specificity%200,2,1),%20which%20wins%20over%20tldraw's%20(0,1,1)%20while%20staying%20correct%5Cn//%20For%20every%20button%20variant%20(it%20reuses%20the%20same%20contextual%20%60--text-color%60).%5Cn//%20It%20MUST%20stay%20scoped%20to%20%60.obsidian-dev-utils%60:%20an%20unscoped%20re-assert%20(it%20was%20%60body%20button%E2%80%A6%60,%5Cn//%200,1,2)%20lands%20on%20every%20button%20in%20the%20app%20and%20beats%20any%20other%20plugin's%20own%20button%20color%5Cn//%20Written%20at%200,1,1,%20which%20Obsidian's%20own%20rule%20used%20to%20lose%20to%20(obsidian-custom-attachment-location%2395).%5Cn//%20Defensive%20workaround%20%E2%80%94%20remove%20once%20the%20upstream%20fix%20ships%20(tldraw/obsidian-plugin%23210).%5Cn.obsidian-dev-utils%20button:not(.clickable-icon)%20%7B%5Cn%20%20color:%20var(--text-color);%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.tri-state-checkbox-component%20%7B%5Cn%20%20%20%20input%5Btype='checkbox'%5D:indeterminate%20%7B%5Cn%20%20%20%20%20%20appearance:%20checkbox;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22@mixin%20invalid%20%7B%5Cn%20%20box-shadow:%200%200%200%202px%20var(--text-error);%5Cn%7D%5Cn%5Cn//%20An%20input%20the%20user%20has%20not%20interacted%20with%20yet%20carries%20%60.untouched%60%20(set%20by%20%60PromptModal%60),%20so%20a%20modal%20that%5Cn//%20opens%20invalid%20by%20design%20does%20not%20greet%20the%20user%20in%20red.%20Both%20blocks%20below%20must%20be%20gated:%20the%20input%20is%5Cn//%20focused%20on%20open,%20so%20the%20focus%20block%20alone%20would%20keep%20painting%20it.%5Cn.obsidian-dev-utils%20%7B%5Cn%20%20:invalid:not(.untouched)%20%7B%5Cn%20%20%20%20@include%20invalid;%5Cn%20%20%7D%5Cn%5Cn%20%20input.metadata-input-text,%5Cn%20%20input%5Btype='date'%5D,%5Cn%20%20input%5Btype='datetime-local'%5D,%5Cn%20%20input%5Btype='email'%5D,%5Cn%20%20input%5Btype='number'%5D,%5Cn%20%20input%5Btype='password'%5D,%5Cn%20%20input%5Btype='search'%5D,%5Cn%20%20input%5Btype='text'%5D,%5Cn%20%20textarea%20%7B%5Cn%20%20%20%20&:active,%5Cn%20%20%20%20&:focus-visible,%5Cn%20%20%20%20&:focus%20%7B%5Cn%20%20%20%20%20%20&:invalid:not(.untouched)%20%7B%5Cn%20%20%20%20%20%20%20%20@include%20invalid;%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20&.setting-component-wrapper%20%7B%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20display:%20inline-flex;%5Cn%20%20%7D%5Cn%5Cn%20%20&.overlay-validator%20%7B%5Cn%20%20%20%20caret-color:%20transparent;%5Cn%20%20%20%20cursor:%20default;%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20outline:%20none;%5Cn%20%20%20%20pointer-events:%20none;%5Cn%20%20%20%20z-index:%209999;%5Cn%20%20%20%20left:%200;%5Cn%20%20%20%20top:%200;%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20height:%20100%25;%5Cn%20%20%7D%5Cn%5Cn%20%20&.tooltip.tooltip-validator%20%7B%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20top:%20calc(100%25%20+%208px);%5Cn%20%20%20%20width:%20max-content;%5Cn%20%20%7D%5Cn%7D%5Cn%22%5D%7D */
9185
+ /*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,%22sourceRoot%22:%22%22,%22sources%22:%5B%22../src/styles/code-highlighter-component.scss%22,%22../src/styles/editor-lock.scss%22,%22../src/styles/input.scss%22,%22../src/styles/input-time.scss%22,%22../src/styles/loop.scss%22,%22../src/styles/minimizable-modal.scss%22,%22../src/styles/modal-commands.scss%22,%22../src/styles/modal-container.scss%22,%22../src/styles/multiple-dropdown-component.scss%22,%22../src/styles/plugin-notice.scss%22,%22../src/styles/plugin-settings-tab.scss%22,%22../src/styles/plugin-suggestion.scss%22,%22../src/styles/popover.scss%22,%22../src/styles/prompt-modal.scss%22,%22../src/styles/tldraw-button-color-workaround.scss%22,%22../src/styles/tri-state-checkbox-component.scss%22,%22../src/styles/validation.scss%22%5D,%22names%22:%5B%5D,%22mappings%22:%22AAEI;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;;ACvCN;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAMJ;EACE;IACE;IACA;;;AAIJ;EACE;;;ACvBA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EAKE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;AAAA;AAAA;AAAA;AAAA;IACE;IACA,YACE;;;AAMR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;EACA,YACE;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;AAAA;EACE;;AASE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;;AC7DV;AAAA;AAAA;EAGE;EACA;;AAEA;AAAA;AAAA;EACE;EACA;;AAGF;AAAA;AAAA;EACE;EACA;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAIK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGP;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;;AAKF;AAAA;AAAA;EACE;;;AAMJ;EACE;;;AC/CK;EACP;;;ACJJ;EACE;IAEE;;EAGF;IACE;;;AAIJ;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AAOA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AASN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAOA;EACE;;AAOF;EACE;;AAGF;EACE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;EACA;;;ACpGN;EACE;EACA;EACA;EACA;EACA;;AAOF;EACE;EACA;;AAMF;EACE;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAIJ;EACE;EACA;;AAGA;EACE;EACA;;;ACpEF;EACE;EACA;;;ACCF;AAAA;AAAA;EAGE;EACA;;AAEA;AAAA;AAAA;EACE;EACA;;;ACZN;EACE;EACA;EACA;EACA;;AAGA;EACE;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAOJ;EACE;;AAEA;EACE;;;ACrCF;EACE;;;ACFJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;ACRJ;EAIE;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AC9BF;EACE;;;ACUN;EACE;;;ACZE;EACE;;;ACKJ;EAPA;;AAuBI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAvBJ;;AA6BA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA%22,%22file%22:%22styles.css%22,%22sourcesContent%22:%5B%22.obsidian-dev-utils%20%7B%5Cn%20%20&.code-highlighter-component%20%7B%5Cn%20%20%20%20textarea,%20pre,%20code%20%7B%5Cn%20%20%20%20%20%20font-family:%20var(--font-monospace);%5Cn%20%20%20%20%20%20line-height:%20var(--line-height-normal);%5Cn%20%20%20%20%20%20margin:%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20textarea,%20code%20%7B%5Cn%20%20%20%20%20%20font-size:%20var(--code-size);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20textarea%20%7B%5Cn%20%20%20%20%20%20background:%20transparent;%5Cn%20%20%20%20%20%20color:%20transparent;%5Cn%20%20%20%20%20%20z-index:%202;%5Cn%20%20%20%20%20%20width:%2020em;%5Cn%20%20%20%20%20%20height:%2010em;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20pre%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20pointer-events:%20none;%5Cn%20%20%20%20%20%20border:%20var(--input-border-width)%20solid%20transparent;%5Cn%20%20%20%20%20%20overflow:%20auto;%5Cn%20%20%20%20%20%20inset:%200;%5Cn%20%20%20%20%20%20padding:%20var(--size-4-1)%20var(--size-4-2);%5Cn%20%20%20%20%20%20z-index:%201;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20pre::after%20%7B%5Cn%20%20%20%20%20%20content:%20%5C%22%5C%22;%5Cn%20%20%20%20%20%20display:%20block;%5Cn%20%20%20%20%20%20height:%20var(--bottom-gap,%200);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20pre.is-placeholder%20%7B%5Cn%20%20%20%20%20%20opacity:%200.6;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20code%20%7B%5Cn%20%20%20%20%20%20display:%20block;%5Cn%20%20%20%20%20%20padding:%200;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22//%20Lock%20indicators%20shown%20in%20the%20tab%20header%20and%20the%20status%20bar%20while%20a%20note%20is%20locked.%20These%20live%20in%5Cn//%20global%20Obsidian%20DOM%20(tab%20header%20/%20status%20bar),%20so%20they%20are%20styled%20with%20a%20global%20class%20rather%20than%5Cn//%20scoped%20under%20%60.obsidian-dev-utils%60.%5Cn.obsidian-dev-utils-lock-indicator%20%7B%5Cn%20%20display:%20inline-flex;%5Cn%20%20align-items:%20center;%5Cn%20%20color:%20var(--text-muted);%5Cn%5Cn%20%20.svg-icon%20%7B%5Cn%20%20%20%20width:%20var(--icon-s);%5Cn%20%20%20%20height:%20var(--icon-s);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn//%20Flashed%20on%20every%20lock%20indicator%20(tab%20header,%20view%20action,%20status%20bar)%20when%20the%20user%20attempts%20to%5Cn//%20type%20in%20a%20locked%20note,%20to%20make%20clear%20the%20note%20is%20read-only.%20Re-added%20per%20rejected%20keystroke.%5Cn@keyframes%20obsidian-dev-utils-lock-indicator-flash%20%7B%5Cn%20%2040%25%20%7B%5Cn%20%20%20%20color:%20var(--text-error);%5Cn%20%20%20%20transform:%20scale(1.4);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn.obsidian-dev-utils-lock-indicator-flash%20%7B%5Cn%20%20animation:%20obsidian-dev-utils-lock-indicator-flash%200.35s%20ease-in-out;%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20input%5Btype='url'%5D%20%7B%5Cn%20%20%20%20height:%20var(--input-height)%5Cn%20%20%7D%5Cn%5Cn%20%20input%5Btype='month'%5D,%5Cn%20%20input%5Btype='tel'%5D,%5Cn%20%20input%5Btype='time'%5D,%5Cn%20%20input%5Btype='url'%5D,%5Cn%20%20input%5Btype='week'%5D%20%7B%5Cn%20%20%20%20-webkit-app-region:%20no-drag;%5Cn%20%20%20%20background:%20var(--background-modifier-form-field);%5Cn%20%20%20%20border:%20var(--input-border-width)%20solid%20var(--background-modifier-border);%5Cn%20%20%20%20color:%20var(--text-normal);%5Cn%20%20%20%20font-family:%20inherit;%5Cn%20%20%20%20padding:%20var(--size-4-1)%20var(--size-4-2);%5Cn%20%20%20%20font-size:%20var(--font-ui-small);%5Cn%20%20%20%20border-radius:%20var(--input-radius);%5Cn%20%20%20%20outline:%20none;%5Cn%5Cn%20%20%20%20@at-root%20%7B%5Cn%20%20%20%20%20%20@media%20(hover:%20hover)%20%7B%5Cn%20%20%20%20%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20border-color:%20var(--background-modifier-border-hover);%5Cn%20%20%20%20%20%20%20%20%20%20transition:%5Cn%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%200.15s%20ease-in-out,%5Cn%20%20%20%20%20%20%20%20%20%20%20%20border%200.15s%20ease-in-out;%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&:active,%5Cn%20%20%20%20&:focus%20%7B%5Cn%20%20%20%20%20%20border-color:%20var(--background-modifier-border-focus);%5Cn%20%20%20%20%20%20transition:%5Cn%20%20%20%20%20%20%20%20box-shadow%200.15s%20ease-in-out,%5Cn%20%20%20%20%20%20%20%20border%200.15s%20ease-in-out;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&:active,%5Cn%20%20%20%20&:focus,%5Cn%20%20%20%20&:focus-visible%20%7B%5Cn%20%20%20%20%20%20box-shadow:%200%200%200%202px%20var(--background-modifier-border-focus);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&::placeholder%20%7B%5Cn%20%20%20%20%20%20color:%20var(--text-faint);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20@at-root%20%7B%5Cn%20%20%20%20.mod-rtl,%5Cn%20%20%20%20.is-rtl,%5Cn%20%20%20%20.rtl%20%7B%5Cn%20%20%20%20%20%20&%20%7B%5Cn%20%20%20%20%20%20%20%20input%5Btype='month'%5D,%5Cn%20%20%20%20%20%20%20%20input%5Btype='time'%5D,%5Cn%20%20%20%20%20%20%20%20input%5Btype='week'%5D%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20direction:%20rtl;%5Cn%5Cn%20%20%20%20%20%20%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20%20%20%20%20%20%20right:%20var(--size-4-1);%5Cn%20%20%20%20%20%20%20%20%20%20%20%20left:%20auto;%5Cn%20%20%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%20%20%7D%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20input%5Btype='month'%5D,%5Cn%20%20input%5Btype='time'%5D,%5Cn%20%20input%5Btype='week'%5D%20%7B%5Cn%20%20%20%20font-variant-numeric:%20tabular-nums;%5Cn%20%20%20%20position:%20relative;%5Cn%5Cn%20%20%20%20&::-webkit-datetime-edit-text%20%7B%5Cn%20%20%20%20%20%20color:%20var(--text-faint);%5Cn%20%20%20%20%20%20padding-inline-end:%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20left:%20var(--size-4-1);%5Cn%20%20%20%20%20%20right:%20auto;%5Cn%20%20%20%20%20%20opacity:%200.5;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20&::-webkit-datetime-edit-month-field,%5Cn%20%20%20%20&::-webkit-datetime-edit-day-field,%5Cn%20%20%20%20&::-webkit-datetime-edit-year-field%20%7B%5Cn%20%20%20%20%20%20&:active,%5Cn%20%20%20%20%20%20&:focus%20%7B%5Cn%20%20%20%20%20%20%20%20background-color:%20var(--text-selection);%5Cn%20%20%20%20%20%20%20%20color:%20var(--text-normal);%5Cn%20%20%20%20%20%20%20%20cursor:%20text;%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20@at-root%20.mod-rtl%20&,%5Cn%20%20%20%20%20%20.is-rtl%20&,%5Cn%20%20%20%20%20%20.rtl%20&%20%7B%5Cn%20%20%20%20%20%20direction:%20rtl;%5Cn%5Cn%20%20%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20%20%20left:%20auto;%5Cn%20%20%20%20%20%20%20%20right:%20var(--size-4-1);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20@at-root%20%7B%5Cn%20%20%20%20%20%20body:not(.is-ios):not(.is-android)%20&%20%7B%5Cn%20%20%20%20%20%20%20%20padding-inline-start:%20var(--size-4-6);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20input%5Btype='time'%5D%20%7B%5Cn%20%20%20%20&::-webkit-calendar-picker-indicator%20%7B%5Cn%20%20%20%20%20%20margin-inline-start:%200;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20//%20Not%20%60&progress%60:%20that%20APPENDS%20the%20element%20name%20to%20the%20parent%20class,%20producing%20one%20long%20class%20that%20matches%5Cn%20%20//%20nothing.%20The%20element%20type%20has%20to%20lead%20the%20compound%20selector%20instead.%5Cn%20%20@at-root%20progress%23%7B&%7D.loop%20%7B%5Cn%20%20%20%20min-width:%20200px;%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22@keyframes%20obsidian-dev-utils-minimized-modal-bar-pulse%20%7B%5Cn%20%200%25,%5Cn%20%20100%25%20%7B%5Cn%20%20%20%20box-shadow:%20var(--shadow-s);%5Cn%20%20%7D%5Cn%5Cn%20%2050%25%20%7B%5Cn%20%20%20%20box-shadow:%200%200%200%202px%20var(--interactive-accent);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn@keyframes%20obsidian-dev-utils-minimized-modal-bar-attention%20%7B%5Cn%20%200%25%20%7B%5Cn%20%20%20%20box-shadow:%200%200%200%200%20var(--interactive-accent);%5Cn%20%20%7D%5Cn%5Cn%20%2040%25%20%7B%5Cn%20%20%20%20box-shadow:%200%200%200%204px%20var(--interactive-accent);%5Cn%20%20%7D%5Cn%5Cn%20%20100%25%20%7B%5Cn%20%20%20%20box-shadow:%20var(--shadow-s);%5Cn%20%20%7D%5Cn%7D%5Cn%5Cn.obsidian-dev-utils%20%7B%5Cn%20%20//%20The%20minimize%20button%20lives%20inside%20the%20modal%20container,%20left%20of%20Obsidian's%20close%20button.%5Cn%20%20&.minimizable-modal%20%7B%5Cn%20%20%20%20.minimize-button%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20top:%20var(--size-4-2);%5Cn%20%20%20%20%20%20right:%20calc(var(--size-4-2)%20+%20var(--size-4-9));%5Cn%20%20%20%20%20%20display:%20flex;%5Cn%20%20%20%20%20%20align-items:%20center;%5Cn%20%20%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20%20%20padding:%20var(--size-2-2);%5Cn%20%20%20%20%20%20border:%20none;%5Cn%20%20%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20%20%20background:%20transparent;%5Cn%20%20%20%20%20%20color:%20var(--icon-color);%5Cn%20%20%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20%20%20box-shadow:%20none;%5Cn%5Cn%20%20%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--background-modifier-hover);%5Cn%20%20%20%20%20%20%20%20color:%20var(--icon-color-hover);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20//%20The%20minimized%20bar%20is%20appended%20to%20document.body.%20It%20floats%20at%20the%20bottom-right%20while%20minimized,%5Cn%20%20//%20and%20gently%20pulses%20an%20accent%20ring%20so%20the%20user%20does%20not%20forget%20about%20the%20minimized%20operation.%5Cn%20%20//%20It%20floats%20a%20status-bar's%20height%20above%20the%20bottom%20edge%20so%20it%20never%20covers%20the%20bottom-right%5Cn%20%20//%20status-bar%20items%20(e.g.%20the%20editor-lock%20unlock%20indicator,%20which%20lives%20in%20the%20same%20corner).%5Cn%20%20&.minimized-modal-bar%20%7B%5Cn%20%20%20%20position:%20fixed;%5Cn%20%20%20%20right:%20var(--size-4-4);%5Cn%20%20%20%20bottom:%20calc(var(--size-4-4)%20+%20var(--size-4-8));%5Cn%20%20%20%20z-index:%20var(--layer-modal);%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20align-items:%20center;%5Cn%20%20%20%20gap:%20var(--size-4-2);%5Cn%20%20%20%20padding:%20var(--size-4-2)%20var(--size-4-3);%5Cn%20%20%20%20border:%201px%20solid%20var(--background-modifier-border);%5Cn%20%20%20%20border-radius:%20var(--radius-m);%5Cn%20%20%20%20background:%20var(--background-secondary);%5Cn%20%20%20%20box-shadow:%20var(--shadow-s);%5Cn%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20animation:%20obsidian-dev-utils-minimized-modal-bar-pulse%202s%20ease-in-out%20infinite;%5Cn%5Cn%20%20%20%20//%20Layer%20the%20translucent%20hover%20tint%20over%20the%20opaque%20%60background%60%20(%60--background-secondary%60)%20via%5Cn%20%20%20%20//%20%60background-image%60%20instead%20of%20replacing%20the%20background-color.%20%60--background-modifier-hover%60%20is%5Cn%20%20%20%20//%20translucent,%20so%20setting%20it%20as%20%60background%60%20would%20let%20the%20editor%20content%20behind%20the%20floating%20bar%5Cn%20%20%20%20//%20bleed%20through%20and%20make%20the%20title%20unreadable.%20A%20gradient%20of%20the%20tint%20composited%20over%20the%20opaque%5Cn%20%20%20%20//%20base%20keeps%20the%20bar%20opaque%20while%20preserving%20the%20subtle%20hover%20highlight.%5Cn%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20background-image:%20linear-gradient(var(--background-modifier-hover),%20var(--background-modifier-hover));%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20A%20one-shot,%20more%20pronounced%20flash%20played%20when%20the%20user%20attempts%20a%20blocked%20action%20(a%20keystroke,%5Cn%20%20%20%20//%20right-click,%20or%20opening%20another%20modal)%20while%20this%20modal%20is%20minimized,%20so%20the%20block%20is%20not%5Cn%20%20%20%20//%20silent.%20Its%20higher%20specificity%20overrides%20the%20gentle%20infinite%20idle%20pulse%20while%20it%20plays;%20the%5Cn%20%20%20%20//%20class%20is%20removed%20on%20%60animationend%60,%20restoring%20the%20idle%20pulse.%5Cn%20%20%20%20&.minimized-modal-bar-attention%20%7B%5Cn%20%20%20%20%20%20animation:%20obsidian-dev-utils-minimized-modal-bar-attention%200.35s%20ease-out;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.minimized-modal-bar-title%20%7B%5Cn%20%20%20%20%20%20font-weight:%20var(--font-medium);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.restore-button,%5Cn%20%20%20%20.cancel-button%20%7B%5Cn%20%20%20%20%20%20display:%20flex;%5Cn%20%20%20%20%20%20align-items:%20center;%5Cn%20%20%20%20%20%20justify-content:%20center;%5Cn%20%20%20%20%20%20padding:%20var(--size-2-2);%5Cn%20%20%20%20%20%20border:%20none;%5Cn%20%20%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20%20%20background:%20transparent;%5Cn%20%20%20%20%20%20color:%20var(--icon-color);%5Cn%20%20%20%20%20%20cursor:%20pointer;%5Cn%20%20%20%20%20%20box-shadow:%20none;%5Cn%5Cn%20%20%20%20%20%20&:hover%20%7B%5Cn%20%20%20%20%20%20%20%20background:%20var(--background-modifier-hover);%5Cn%20%20%20%20%20%20%20%20color:%20var(--icon-color-hover);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20//%20The%20strip%20of%20commands%20along%20the%20bottom%20of%20a%20modal.%5Cn%20%20//%5Cn%20%20//%20In%20%60Instructions%60%20render%20mode%20it%20also%20carries%20Obsidian's%20own%20%60.prompt-instructions%60%20%E2%80%94%20whose%20rule%20is%5Cn%20%20//%20unscoped,%20so%20it%20applies%20to%20a%20plain%20%60Modal%60%20too%20%E2%80%94%20and%20this%20one%20only%20re-tunes%20that%20rule's%20%60gap%60%20and%5Cn%20%20//%20%60padding%60%20and%20adds%20the%20separator;%20in%20%60Buttons%60%20mode%20it%20is%20the%20whole%20strip.%5Cn%20%20&.modal-commands%20%7B%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20flex-wrap:%20wrap;%5Cn%20%20%20%20gap:%20var(--size-2-2);%5Cn%20%20%20%20padding:%20var(--size-4-2)%20var(--size-4-3);%5Cn%20%20%20%20border-top:%201px%20solid%20var(--background-modifier-border);%5Cn%20%20%7D%5Cn%5Cn%20%20//%20A%20control%20the%20%60Instructions%60%20renderer%20injects%20into%20an%20instruction's%20purpose%20text%20%E2%80%94%20a%20checkbox,%20a%5Cn%20%20//%20dropdown.%20Obsidian%20styles%20the%20instruction%20bar%20itself,%20but%20its%20own%20bar%20never%20contains%20a%20control,%20so%5Cn%20%20//%20nothing%20upstream%20separates%20one%20from%20the%20label%20it%20belongs%20to.%20Sits%20on%20the%20control%20rather%20than%20on%20the%5Cn%20%20//%20strip,%20so%20it%20reaches%20a%20%60SuggestModal%60's%20native%20bar%20as%20well%20as%20a%20self-created%20one.%5Cn%20%20&.modal-command-control%20%7B%5Cn%20%20%20%20margin-inline-start:%20var(--size-2-2);%5Cn%20%20%20%20vertical-align:%20middle;%5Cn%20%20%7D%5Cn%5Cn%20%20//%20One%20command%20button.%20Replaces%20the%20instruction%20bar%20rather%20than%20supplementing%20it:%20the%20bar%20can%20only%20ever%5Cn%20%20//%20say%20which%20key%20to%20press,%20and%20on%20a%20phone%20there%20is%20no%20modifier%20key%20to%20press,%20so%20every%20control%20it%20names%5Cn%20%20//%20is%20unreachable%20there.%5Cn%20%20&.modal-command%20%7B%5Cn%20%20%20%20display:%20inline-flex;%5Cn%20%20%20%20align-items:%20baseline;%5Cn%20%20%20%20gap:%20var(--size-2-2);%5Cn%5Cn%20%20%20%20//%20Comfortably%20tappable%20on%20a%20phone,%20where%20this%20strip%20is%20the%20only%20way%20in.%5Cn%20%20%20%20min-height:%20var(--size-4-8);%5Cn%20%20%20%20padding:%20var(--size-2-1)%20var(--size-4-2);%5Cn%20%20%20%20border:%201px%20solid%20var(--background-modifier-border);%5Cn%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20background-color:%20var(--background-secondary);%5Cn%20%20%20%20color:%20var(--text-muted);%5Cn%20%20%20%20font-size:%20var(--font-ui-smaller);%5Cn%20%20%20%20white-space:%20nowrap;%5Cn%20%20%20%20cursor:%20pointer;%5Cn%5Cn%20%20%20%20&:hover:not(:disabled)%20%7B%5Cn%20%20%20%20%20%20background-color:%20var(--background-modifier-hover);%5Cn%20%20%20%20%20%20color:%20var(--text-normal);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20A%20toggle%20that%20is%20ON.%20An%20action%20never%20carries%20it%20%E2%80%94%20it%20does%20something%20and%20is%20done,%20so%20there%20is%20no%5Cn%20%20%20%20//%20state%20for%20it%20to%20show.%5Cn%20%20%20%20&.is-active%20%7B%5Cn%20%20%20%20%20%20border-color:%20var(--interactive-accent);%5Cn%20%20%20%20%20%20background-color:%20var(--interactive-accent);%5Cn%20%20%20%20%20%20color:%20var(--text-on-accent);%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20Disabled%20rather%20than%20removed:%20a%20strip%20that%20lost%20buttons%20as%20modes%20change%20would%20reflow%20under%20the%5Cn%20%20%20%20//%20pointer,%20which%20on%20a%20phone%20means%20a%20mis-tap.%5Cn%20%20%20%20&:disabled%20%7B%5Cn%20%20%20%20%20%20opacity:%200.5;%5Cn%20%20%20%20%20%20cursor:%20default;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20&.modal-command-hotkey%20%7B%5Cn%20%20%20%20color:%20var(--text-faint);%5Cn%20%20%20%20font-size:%20var(--font-smallest);%5Cn%5Cn%20%20%20%20//%20Faint%20against%20the%20surface%20is%20right;%20faint%20against%20the%20accent%20fill%20is%20invisible.%5Cn%20%20%20%20.modal-command.is-active%20&%20%7B%5Cn%20%20%20%20%20%20opacity:%200.7;%5Cn%20%20%20%20%20%20color:%20var(--text-on-accent);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.modal-container%20%7B%5Cn%20%20%20%20.ok-button%20%7B%5Cn%20%20%20%20%20%20margin-right:%2010px;%5Cn%20%20%20%20%20%20margin-top:%2020px;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20//%20Compound,%20not%20nested:%20%60addPluginCssClasses%60%20puts%20%60obsidian-dev-utils%60%20and%20%60multiple-dropdown-component%60%20on%20the%5Cn%20%20//%20SAME%20element%20(the%20setting's%20control%20container),%20so%20a%20descendant%20selector%20matched%20nothing%20and%20every%20multiple%5Cn%20%20//%20dropdown%20rendered%20one%20row%20tall%20%E2%80%94%20Obsidian's%20%60.dropdown%60%20height,%20with%20no%20popup%20behind%20it%20to%20pick%20from.%5Cn%20%20&.multiple-dropdown-component%20%7B%5Cn%20%20%20%20select,%5Cn%20%20%20%20select:focus,%5Cn%20%20%20%20.dropdown%20%7B%5Cn%20%20%20%20%20%20height:%20auto;%5Cn%20%20%20%20%20%20padding-top:%203px;%5Cn%5Cn%20%20%20%20%20%20option:checked%20%7B%5Cn%20%20%20%20%20%20%20%20background-color:%20var(--interactive-accent);%5Cn%20%20%20%20%20%20%20%20color:%20var(--text-on-accent);%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.plugin-notice-name%20%7B%5Cn%20%20%20%20color:%20var(--text-accent);%5Cn%20%20%20%20display:%20inline-block;%5Cn%20%20%20%20font-weight:%20var(--font-bold);%5Cn%20%20%20%20margin-bottom:%20var(--size-4-2);%5Cn%5Cn%20%20%20%20//%20The%20name%20is%20inline%20code;%20it%20keeps%20the%20code%20background%20and%20font%20but%20takes%20the%20prefix's%20accent%20color.%5Cn%20%20%20%20code%20%7B%5Cn%20%20%20%20%20%20color:%20inherit;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20&.plugin-notice-content%20%7B%5Cn%20%20%20%20padding-right:%20var(--size-4-5);%5Cn%20%20%20%20position:%20relative;%5Cn%5Cn%20%20%20%20.obsidian-dev-utils.cancel-button%20%7B%5Cn%20%20%20%20%20%20display:%20block;%5Cn%20%20%20%20%20%20margin-top:%20var(--size-4-2);%5Cn%20%20%20%20%20%20width:%20fit-content;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20//%20The%20close%20button%20reuses%20Obsidian's%20%60modal-header-button%60%20+%20%60clickable-icon%60%20classes%20so%20it%20matches%5Cn%20%20%20%20//%20The%20native%20modal%20close%20button%20(box%20+%20hover);%20only%20its%20corner%20position%20is%20set%20here.%5Cn%20%20%20%20.obsidian-dev-utils.plugin-notice-close-button%20%7B%5Cn%20%20%20%20%20%20position:%20absolute;%5Cn%20%20%20%20%20%20right:%20var(--size-4-3);%5Cn%20%20%20%20%20%20top:%20var(--size-4-3);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20//%20Move%20the%20notice's%20own%20padding%20onto%20the%20content%20wrapper%20so%20the%20wrapper%20covers%20the%20whole%20clickable%5Cn%20%20//%20Area%20%E2%80%94%20otherwise%20a%20click%20landing%20on%20the%20notice's%20bare%20padding%20(outside%20the%20wrapper)%20would%20bypass%20the%5Cn%20%20//%20Stop-propagation%20guard%20and%20dismiss%20the%20hard-to-close%20notice.%5Cn%20%20&.plugin-notice-requires-explicit-close.notice%20%7B%5Cn%20%20%20%20padding:%200;%5Cn%5Cn%20%20%20%20.obsidian-dev-utils.plugin-notice-content%20%7B%5Cn%20%20%20%20%20%20padding:%20var(--size-4-3)%20var(--size-4-4);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.plugin-settings-tab%20%7B%5Cn%20%20%20%20a:focus%20%7B%5Cn%20%20%20%20%20%20outline:%202px%20solid%20var(--link-color);%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.plugin-suggestion-banner%20%7B%5Cn%20%20%20%20background-color:%20var(--background-secondary);%5Cn%20%20%20%20border-left:%20var(--size-2-1)%20solid%20var(--text-accent);%5Cn%20%20%20%20border-radius:%20var(--radius-s);%5Cn%20%20%20%20display:%20flex;%5Cn%20%20%20%20flex-direction:%20column;%5Cn%20%20%20%20gap:%20var(--size-4-2);%5Cn%20%20%20%20margin-bottom:%20var(--size-4-4);%5Cn%20%20%20%20padding:%20var(--size-4-3)%20var(--size-4-4);%5Cn%5Cn%20%20%20%20button%20%7B%5Cn%20%20%20%20%20%20width:%20fit-content;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22//%20A%20popover%20is%20anchored%20at%20a%20point%20and%20appended%20to%20the%20document%20body,%20outside%20any%20plugin-scoped%5Cn//%20container,%20so%20it%20is%20positioned%20absolutely%20at%20the%20top%20level.%20It%20borrows%20Obsidian's%20%60.menu%60%20look,%5Cn//%20which%20already%20carries%20the%20popup%20background,%20border%20and%20shadow%20%E2%80%94%20only%20layout%20is%20set%20here.%5Cn.obsidian-dev-utils%20%7B%5Cn%20%20&.popover%20%7B%5Cn%20%20%20%20//%20Deliberately%20not%20%60calc(100vw%20-%2016px)%60:%20the%20SCSS%20compiler%20strips%20the%20%60calc(%60%20wrapper%20inside%5Cn%20%20%20%20//%20%60min()%60,%20which%20yields%20invalid%20CSS.%20A%20viewport%20percentage%20keeps%20a%20narrow%20window's%20popover%20on%5Cn%20%20%20%20//%20screen.%5Cn%20%20%20%20max-width:%20min(420px,%2090vw);%5Cn%20%20%20%20min-width:%20320px;%5Cn%20%20%20%20padding:%20var(--size-4-2)%20var(--size-4-3);%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20z-index:%20var(--layer-menu);%5Cn%5Cn%20%20%20%20//%20Setting%20rows%20are%20built%20for%20a%20full-width%20settings%20tab;%20compact%20them%20for%20a%20popover.%5Cn%20%20%20%20.setting-item%20%7B%5Cn%20%20%20%20%20%20align-items:%20center;%5Cn%20%20%20%20%20%20border-top:%20none;%5Cn%20%20%20%20%20%20gap:%20var(--size-4-2);%5Cn%20%20%20%20%20%20padding:%20var(--size-2-1)%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.setting-item-info%20%7B%5Cn%20%20%20%20%20%20margin-right:%200;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20.setting-item-control%20%7B%5Cn%20%20%20%20%20%20flex-grow:%201;%5Cn%20%20%20%20%20%20justify-content:%20flex-end;%5Cn%20%20%20%20%7D%5Cn%5Cn%20%20%20%20input%5Btype='text'%5D%20%7B%5Cn%20%20%20%20%20%20width:%20100%25;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.prompt-modal%20%7B%5Cn%20%20%20%20.text-box%20%7B%5Cn%20%20%20%20%20%20width:%20100%25;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22//%20The%20tldraw%20Obsidian%20plugin%20(tldraw/obsidian-plugin)%20ships%20an%20unscoped%20global%20rule%5Cn//%20%60button:not(.clickable-icon)%20%7B%20color:%20currentColor%20%7D%60%20that%20overrides%20Obsidian's%20own%5Cn//%20%60button:not(.clickable-icon)%20%7B%20color:%20var(--text-color)%20%7D%60%20app-wide.%20Obsidian%20sets%5Cn//%20%60--text-color%60%20contextually%20per%20button%20variant%20(%60--text-normal%60%20by%20default,%5Cn//%20%60--text-on-accent%60%20for%20%60.mod-cta%60,%20%60--text-error%60%20for%20%60.mod-warning%60),%20so%20tldraw's%5Cn//%20%60currentColor%60%20discards%20that%20and%20breaks%20button%20contrast%20outside%20tldraw%20%E2%80%94%20e.g.%5Cn//%20White-on-white%20action%20buttons%20inside%20a%20Notice.%20Re-assert%20Obsidian's%20own%20value%20inside%20the%5Cn//%20Library's%20own%20UI%20(specificity%200,2,1),%20which%20wins%20over%20tldraw's%20(0,1,1)%20while%20staying%20correct%5Cn//%20For%20every%20button%20variant%20(it%20reuses%20the%20same%20contextual%20%60--text-color%60).%5Cn//%20It%20MUST%20stay%20scoped%20to%20%60.obsidian-dev-utils%60:%20an%20unscoped%20re-assert%20(it%20was%20%60body%20button%E2%80%A6%60,%5Cn//%200,1,2)%20lands%20on%20every%20button%20in%20the%20app%20and%20beats%20any%20other%20plugin's%20own%20button%20color%5Cn//%20Written%20at%200,1,1,%20which%20Obsidian's%20own%20rule%20used%20to%20lose%20to%20(obsidian-custom-attachment-location%2395).%5Cn//%20Defensive%20workaround%20%E2%80%94%20remove%20once%20the%20upstream%20fix%20ships%20(tldraw/obsidian-plugin%23210).%5Cn.obsidian-dev-utils%20button:not(.clickable-icon)%20%7B%5Cn%20%20color:%20var(--text-color);%5Cn%7D%5Cn%22,%22.obsidian-dev-utils%20%7B%5Cn%20%20&.tri-state-checkbox-component%20%7B%5Cn%20%20%20%20input%5Btype='checkbox'%5D:indeterminate%20%7B%5Cn%20%20%20%20%20%20appearance:%20checkbox;%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%7D%5Cn%22,%22@mixin%20invalid%20%7B%5Cn%20%20box-shadow:%200%200%200%202px%20var(--text-error);%5Cn%7D%5Cn%5Cn//%20An%20input%20the%20user%20has%20not%20interacted%20with%20yet%20carries%20%60.untouched%60%20(set%20by%20%60PromptModal%60),%20so%20a%20modal%20that%5Cn//%20opens%20invalid%20by%20design%20does%20not%20greet%20the%20user%20in%20red.%20Both%20blocks%20below%20must%20be%20gated:%20the%20input%20is%5Cn//%20focused%20on%20open,%20so%20the%20focus%20block%20alone%20would%20keep%20painting%20it.%5Cn.obsidian-dev-utils%20%7B%5Cn%20%20:invalid:not(.untouched)%20%7B%5Cn%20%20%20%20@include%20invalid;%5Cn%20%20%7D%5Cn%5Cn%20%20input.metadata-input-text,%5Cn%20%20input%5Btype='date'%5D,%5Cn%20%20input%5Btype='datetime-local'%5D,%5Cn%20%20input%5Btype='email'%5D,%5Cn%20%20input%5Btype='number'%5D,%5Cn%20%20input%5Btype='password'%5D,%5Cn%20%20input%5Btype='search'%5D,%5Cn%20%20input%5Btype='text'%5D,%5Cn%20%20textarea%20%7B%5Cn%20%20%20%20&:active,%5Cn%20%20%20%20&:focus-visible,%5Cn%20%20%20%20&:focus%20%7B%5Cn%20%20%20%20%20%20&:invalid:not(.untouched)%20%7B%5Cn%20%20%20%20%20%20%20%20@include%20invalid;%5Cn%20%20%20%20%20%20%7D%5Cn%20%20%20%20%7D%5Cn%20%20%7D%5Cn%5Cn%20%20&.setting-component-wrapper%20%7B%5Cn%20%20%20%20position:%20relative;%5Cn%20%20%20%20display:%20inline-flex;%5Cn%20%20%7D%5Cn%5Cn%20%20&.overlay-validator%20%7B%5Cn%20%20%20%20caret-color:%20transparent;%5Cn%20%20%20%20cursor:%20default;%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20background-color:%20transparent;%5Cn%20%20%20%20border:%20none;%5Cn%20%20%20%20outline:%20none;%5Cn%20%20%20%20pointer-events:%20none;%5Cn%20%20%20%20z-index:%209999;%5Cn%20%20%20%20left:%200;%5Cn%20%20%20%20top:%200;%5Cn%20%20%20%20width:%20100%25;%5Cn%20%20%20%20height:%20100%25;%5Cn%20%20%7D%5Cn%5Cn%20%20&.tooltip.tooltip-validator%20%7B%5Cn%20%20%20%20position:%20absolute;%5Cn%20%20%20%20top:%20calc(100%25%20+%208px);%5Cn%20%20%20%20width:%20max-content;%5Cn%20%20%7D%5Cn%7D%5Cn%22%5D%7D */
9017
9186
  `;
9018
9187
  }
9019
9188
  });
@@ -9031,7 +9200,7 @@ function injectLibraryStyles(params) {
9031
9200
  const { doc, libraryStyles, libraryVersion } = params;
9032
9201
  getObsidianDevUtilsState(LEGACY_LAST_LIBRARY_VERSION_KEY, "0.0.0").value = LEGACY_LAST_LIBRARY_VERSION_SENTINEL;
9033
9202
  const lastVersionWrapper = getObsidianDevUtilsState(LAST_OBSIDIAN_LIB_VERSION_KEY, null);
9034
- if (lastVersionWrapper.value !== null && (0, import_compare_versions.compareVersions)(libraryVersion, lastVersionWrapper.value) <= 0) {
9203
+ if (lastVersionWrapper.value !== null && (0, import_compare_versions2.compareVersions)(libraryVersion, lastVersionWrapper.value) <= 0) {
9035
9204
  return;
9036
9205
  }
9037
9206
  lastVersionWrapper.value = libraryVersion;
@@ -9043,10 +9212,10 @@ function injectLibraryStyles(params) {
9043
9212
  text: libraryStyles
9044
9213
  });
9045
9214
  }
9046
- var import_compare_versions, LIBRARY_STYLES_ELEMENT_ID, LAST_OBSIDIAN_LIB_VERSION_KEY, LEGACY_LAST_LIBRARY_VERSION_KEY, LEGACY_LAST_LIBRARY_VERSION_SENTINEL;
9215
+ var import_compare_versions2, LIBRARY_STYLES_ELEMENT_ID, LAST_OBSIDIAN_LIB_VERSION_KEY, LEGACY_LAST_LIBRARY_VERSION_KEY, LEGACY_LAST_LIBRARY_VERSION_SENTINEL;
9047
9216
  var init_library_styles = __esm({
9048
9217
  "node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/library-styles.mjs"() {
9049
- import_compare_versions = __toESM(require_umd(), 1);
9218
+ import_compare_versions2 = __toESM(require_umd(), 1);
9050
9219
  init_library2();
9051
9220
  init_obsidian_dev_utils_state();
9052
9221
  (function() {
@@ -9381,6 +9550,7 @@ var init_plugin_notice_component = __esm({
9381
9550
  init_value_provider();
9382
9551
  import_obsidian106 = require("obsidian");
9383
9552
  init_css_class();
9553
+ init_html_element();
9384
9554
  init_i18n();
9385
9555
  init_obsidian_dev_utils_state();
9386
9556
  init_plugin_context();
@@ -9737,12 +9907,16 @@ var init_plugin_notice_component = __esm({
9737
9907
  * Builds the notice content, prefixing the message with the plugin name in a styled element so it is
9738
9908
  * visually distinguished from the message body.
9739
9909
  *
9910
+ * The name is rendered as inline code, the way every plugin name in the UI is, inside a span that keeps
9911
+ * the prefix's own layout and accent color.
9912
+ *
9740
9913
  * @param message - The message to display after the plugin name prefix.
9741
9914
  * @returns A {@link DocumentFragment} with the styled plugin name prefix followed by the message.
9742
9915
  */
9743
9916
  buildPrefixedMessage(message) {
9744
9917
  const fragment = createFragment();
9745
- const nameEl = createSpan({ text: this.pluginName });
9918
+ const nameEl = createSpan();
9919
+ appendCodeBlock(nameEl, this.pluginName);
9746
9920
  addPluginCssClasses(nameEl, CssClass.PluginNoticeName);
9747
9921
  fragment.append(nameEl);
9748
9922
  if (!this._loaded) {
@@ -10136,24 +10310,24 @@ async function openDemoVault(params) {
10136
10310
  pluginVersion
10137
10311
  } = params;
10138
10312
  const progressNotice = __using4(_stack, pluginNoticeComponent.showNoticeAfterDelay({
10139
- content: `Opening demo vault for ${pluginName}\u2026`,
10313
+ content: createFragmentWithCodeBlocks(`Opening demo vault for ${asCodeBlock(pluginName)}\u2026`),
10140
10314
  delayInMilliseconds: 0,
10141
10315
  mode: PluginNoticeMode.Separate
10142
10316
  }));
10143
10317
  const repo = await getCommunityPluginRepo(pluginId);
10144
10318
  if (!repo) {
10145
- pluginNoticeComponent.showNotice(`Could not find plugin ${pluginName} in the community plugins registry.`);
10319
+ pluginNoticeComponent.showNotice(createFragmentWithCodeBlocks(`Could not find plugin ${asCodeBlock(pluginName)} in the community plugins registry.`));
10146
10320
  return;
10147
10321
  }
10148
10322
  const currentVersion = pluginVersion;
10149
10323
  const latestVersion = await getLatestReleaseVersion(repo);
10150
10324
  let versionToOpen;
10151
- if ((0, import_compare_versions2.compareVersions)(currentVersion, latestVersion) >= 0) {
10325
+ if ((0, import_compare_versions3.compareVersions)(currentVersion, latestVersion) >= 0) {
10152
10326
  versionToOpen = currentVersion;
10153
10327
  } else {
10154
10328
  const chosenVersion = await selectOption({
10155
10329
  app,
10156
- message: `Current version of plugin ${pluginName} v${currentVersion} is not the latest (v${latestVersion})`,
10330
+ message: createFragmentWithCodeBlocks(`Current version of plugin ${asCodeBlock(pluginName)} v${currentVersion} is not the latest (v${latestVersion})`),
10157
10331
  options: [
10158
10332
  {
10159
10333
  isCta: true,
@@ -10169,7 +10343,7 @@ async function openDemoVault(params) {
10169
10343
  value: null
10170
10344
  }
10171
10345
  ],
10172
- title: pluginName
10346
+ title: createFragmentWithCodeBlocks(asCodeBlock(pluginName))
10173
10347
  });
10174
10348
  if (chosenVersion === null) {
10175
10349
  return;
@@ -10187,7 +10361,7 @@ async function openDemoVault(params) {
10187
10361
  if (!archive) {
10188
10362
  return;
10189
10363
  }
10190
- progressNotice.setContent(`Extracting demo vault for ${pluginName} v${versionToOpen}\u2026`);
10364
+ progressNotice.setContent(createFragmentWithCodeBlocks(`Extracting demo vault for ${asCodeBlock(pluginName)} v${versionToOpen}\u2026`));
10191
10365
  cleanupOrphanedExtractedVaults();
10192
10366
  const vaultDirectory = extractDemoVaultToFreshFolder({
10193
10367
  archive,
@@ -10255,14 +10429,14 @@ async function resolveDemoVaultArchive(params) {
10255
10429
  if ((0, import_node_fs.existsSync)(archivePath)) {
10256
10430
  return (0, import_node_fs.readFileSync)(archivePath);
10257
10431
  }
10258
- progressNotice.setContent(`Downloading demo vault for ${pluginName} v${version}\u2026`);
10432
+ progressNotice.setContent(createFragmentWithCodeBlocks(`Downloading demo vault for ${asCodeBlock(pluginName)} v${version}\u2026`));
10259
10433
  const assetUrl = `https://github.com/${repo}/releases/download/${version}/${getDemoVaultArchiveFileName(pluginId)}`;
10260
10434
  const response = await (0, import_obsidian109.requestUrl)({
10261
10435
  throw: false,
10262
10436
  url: assetUrl
10263
10437
  });
10264
10438
  if (response.status !== HTTP_STATUS_OK) {
10265
- pluginNoticeComponent.showNotice(`No demo vault is available for plugin ${pluginName} v${version}.`);
10439
+ pluginNoticeComponent.showNotice(createFragmentWithCodeBlocks(`No demo vault is available for plugin ${asCodeBlock(pluginName)} v${version}.`));
10266
10440
  return null;
10267
10441
  }
10268
10442
  const archive = import_node_buffer.Buffer.from(response.arrayBuffer);
@@ -10270,12 +10444,12 @@ async function resolveDemoVaultArchive(params) {
10270
10444
  (0, import_node_fs.writeFileSync)(archivePath, archive);
10271
10445
  return archive;
10272
10446
  }
10273
- var import_compare_versions2, import_node_buffer, import_node_fs, import_node_os, import_obsidian109, __knownSymbol4, __typeError4, __using4, __callDispose4, DEMO_VAULTS_CACHE_FOLDER, ARCHIVES_SUBFOLDER, EXTRACTED_VAULTS_SUBFOLDER, HTTP_STATUS_OK, ORPHANED_EXTRACTED_VAULT_MAX_AGE_IN_MILLISECONDS;
10447
+ var import_compare_versions3, import_node_buffer, import_node_fs, import_node_os, import_obsidian109, __knownSymbol4, __typeError4, __using4, __callDispose4, DEMO_VAULTS_CACHE_FOLDER, ARCHIVES_SUBFOLDER, EXTRACTED_VAULTS_SUBFOLDER, HTTP_STATUS_OK, ORPHANED_EXTRACTED_VAULT_MAX_AGE_IN_MILLISECONDS;
10274
10448
  var init_desktop_demo_vault_opener = __esm({
10275
10449
  "node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/desktop-demo-vault-opener.mjs"() {
10276
10450
  init_desktop_zip_extractor();
10277
10451
  init_path();
10278
- import_compare_versions2 = __toESM(require_umd(), 1);
10452
+ import_compare_versions3 = __toESM(require_umd(), 1);
10279
10453
  import_node_buffer = require("node:buffer");
10280
10454
  import_node_fs = require("node:fs");
10281
10455
  import_node_os = require("node:os");
@@ -10283,6 +10457,7 @@ var init_desktop_demo_vault_opener = __esm({
10283
10457
  init_community_plugins();
10284
10458
  init_plugin_notice_component();
10285
10459
  init_demo_vault_naming();
10460
+ init_html_element();
10286
10461
  init_select_option();
10287
10462
  (function() {
10288
10463
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
@@ -12239,6 +12414,7 @@ __export(merged_exports, {
12239
12414
  BASE_FILE_EXTENSION: () => BASE_FILE_EXTENSION,
12240
12415
  Beeper: () => Beeper,
12241
12416
  CANVAS_FILE_EXTENSION: () => CANVAS_FILE_EXTENSION,
12417
+ CUSTOM_ATTACHMENT_LOCATION_PLUGIN_ID: () => CUSTOM_ATTACHMENT_LOCATION_PLUGIN_ID,
12242
12418
  CachedMetadataExFeature: () => CachedMetadataExFeature,
12243
12419
  CallbackDisposable: () => CallbackDisposable,
12244
12420
  CallbackLayoutReadyComponent: () => CallbackLayoutReadyComponent,
@@ -12422,6 +12598,7 @@ __export(merged_exports, {
12422
12598
  adoptSettingEx: () => adoptSettingEx,
12423
12599
  alert: () => alert,
12424
12600
  appendCodeBlock: () => appendCodeBlock,
12601
+ appendTextOrFragmentClone: () => appendTextOrFragmentClone,
12425
12602
  applyContentChanges: () => applyContentChanges,
12426
12603
  applyFileChanges: () => applyFileChanges,
12427
12604
  applySpellcheckMode: () => applySpellcheckMode,
@@ -12470,6 +12647,7 @@ __export(merged_exports, {
12470
12647
  createAnchorFromElement: () => createAnchorFromElement,
12471
12648
  createAnchorFromPoint: () => createAnchorFromPoint,
12472
12649
  createAnchorFromSelection: () => createAnchorFromSelection,
12650
+ createArgumentsSchema: () => createArgumentsSchema,
12473
12651
  createCodeBlockRegExp: () => createCodeBlockRegExp,
12474
12652
  createDivAsync: () => createDivAsync,
12475
12653
  createElAsync: () => createElAsync,
@@ -12481,6 +12659,7 @@ __export(merged_exports, {
12481
12659
  createSvgAsync: () => createSvgAsync,
12482
12660
  createTemporaryFile: () => createTemporaryFile,
12483
12661
  createTemporaryFolder: () => createTemporaryFolder,
12662
+ createTypeGuardSchema: () => createTypeGuardSchema,
12484
12663
  dataUrlToArrayBuffer: () => dataUrlToArrayBuffer,
12485
12664
  defaultTranslationsMap: () => defaultTranslationsMap,
12486
12665
  deleteAlias: () => deleteAlias,
@@ -12530,6 +12709,7 @@ __export(merged_exports, {
12530
12709
  findAttachmentUnitFolderPath: () => findAttachmentUnitFolderPath,
12531
12710
  findNoPriorityWinnerReason: () => findNoPriorityWinnerReason,
12532
12711
  findNotePriorityRank: () => findNotePriorityRank,
12712
+ findPluginApi: () => findPluginApi,
12533
12713
  fixTitle: () => fixTitle,
12534
12714
  flushQueue: () => flushQueue,
12535
12715
  format: () => format,
@@ -12610,6 +12790,7 @@ __export(merged_exports, {
12610
12790
  getPrototypeOf: () => getPrototypeOf,
12611
12791
  getRenderedContainer: () => getRenderedContainer,
12612
12792
  getSafeRenamePath: () => getSafeRenamePath,
12793
+ getSettingsMigrationApiContract: () => getSettingsMigrationApiContract,
12613
12794
  getSharedAbortController: () => getSharedAbortController,
12614
12795
  getSharedAbortSignal: () => getSharedAbortSignal,
12615
12796
  getStackTrace: () => getStackTrace,
@@ -12686,6 +12867,7 @@ __export(merged_exports, {
12686
12867
  isNote: () => isNote,
12687
12868
  isParseLinkFrontmatterReference: () => isParseLinkFrontmatterReference,
12688
12869
  isParseLinkReference: () => isParseLinkReference,
12870
+ isPathOrFile: () => isPathOrFile,
12689
12871
  isPropertyEntry: () => isPropertyEntry,
12690
12872
  isReferenceInOffsetRange: () => isReferenceInOffsetRange,
12691
12873
  isResourceLockedForPath: () => isResourceLockedForPath,
@@ -13119,6 +13301,7 @@ function showCustomContentNotice(context, pluginNoticeComponent, content3) {
13119
13301
  var attachment_path_exports = {};
13120
13302
  __export(attachment_path_exports, {
13121
13303
  AttachmentPathContext: () => AttachmentPathContext,
13304
+ CUSTOM_ATTACHMENT_LOCATION_PLUGIN_ID: () => CUSTOM_ATTACHMENT_LOCATION_PLUGIN_ID,
13122
13305
  DUMMY_PATH: () => DUMMY_PATH,
13123
13306
  getAttachmentFilePath: () => getAttachmentFilePath,
13124
13307
  getAttachmentFolderPath: () => getAttachmentFolderPath,
@@ -13548,6 +13731,7 @@ __export(file_system_exports, {
13548
13731
  isFolder: () => isFolder,
13549
13732
  isMarkdownFile: () => isMarkdownFile,
13550
13733
  isNote: () => isNote,
13734
+ isPathOrFile: () => isPathOrFile,
13551
13735
  isTreatedAsAttachment: () => isTreatedAsAttachment,
13552
13736
  trimMarkdownExtension: () => trimMarkdownExtension
13553
13737
  });
@@ -14098,6 +14282,9 @@ function isMarkdownFile(pathOrFile) {
14098
14282
  function isNote(pathOrFile) {
14099
14283
  return isMarkdownFile(pathOrFile) || isCanvasFile(pathOrFile) || isBaseFile(pathOrFile);
14100
14284
  }
14285
+ function isPathOrFile(value) {
14286
+ return typeof value === "string" || isFile(value);
14287
+ }
14101
14288
  function isTreatedAsAttachment(params) {
14102
14289
  const {
14103
14290
  app,
@@ -14150,7 +14337,14 @@ function getResolvedPath(path) {
14150
14337
  return (0, import_obsidian98.normalizePath)(resolve("/", path));
14151
14338
  }
14152
14339
 
14153
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/attachment-path.mjs
14340
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/plugin-api-schema.mjs
14341
+ var plugin_api_schema_exports = {};
14342
+ __export(plugin_api_schema_exports, {
14343
+ createArgumentsSchema: () => createArgumentsSchema,
14344
+ createTypeGuardSchema: () => createTypeGuardSchema
14345
+ });
14346
+ init_object_utils();
14347
+ init_library2();
14154
14348
  (function() {
14155
14349
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
14156
14350
  symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
@@ -14184,231 +14378,759 @@ function getResolvedPath(path) {
14184
14378
  ensureBrowserProcess();
14185
14379
  })();
14186
14380
  })();
14187
- var AttachmentPathContext = /* @__PURE__ */ ((AttachmentPathContext2) => {
14188
- AttachmentPathContext2["DeleteNote"] = "DeleteNote";
14189
- AttachmentPathContext2["RenameNote"] = "RenameNote";
14190
- AttachmentPathContext2["Unknown"] = "Unknown";
14191
- return AttachmentPathContext2;
14192
- })(AttachmentPathContext || {});
14193
- var DUMMY_PATH = "__DUMMY__";
14194
- async function getAttachmentFilePath(params) {
14195
- const {
14196
- app,
14197
- notePathOrFile,
14198
- oldAttachmentPathOrFile,
14199
- shouldSkipDuplicateCheck
14200
- } = params;
14201
- const extendedFunction = getExtendedFunction(app);
14202
- if (!extendedFunction) {
14203
- return getAttachmentFilePathSync({
14204
- app,
14205
- notePathOrFile,
14206
- oldAttachmentPathOrFile,
14207
- shouldSkipDuplicateCheck
14208
- });
14209
- }
14210
- const attachmentPath = getPath2(app, oldAttachmentPathOrFile);
14211
- const attachmentFileExtension = extname(attachmentPath);
14212
- const attachmentFileBaseName = basename(attachmentPath, attachmentFileExtension);
14213
- const attachmentFile = getFileOrNull({ app, pathOrFile: attachmentPath });
14214
- return await extendedFunction({
14215
- attachmentFileBaseName,
14216
- attachmentFileExtension: attachmentFileExtension.slice(1),
14217
- attachmentFileStats: attachmentFile?.stat,
14218
- context: params.context,
14219
- notePathOrFile,
14220
- oldAttachmentPathOrFile,
14221
- oldNotePathOrFile: params.oldNotePathOrFile,
14222
- readAttachmentFileContent: attachmentFile ? () => app.vault.readBinary(attachmentFile) : null,
14223
- shouldSkipDuplicateCheck,
14224
- shouldSkipMissingAttachmentFolderCreation: true
14225
- });
14226
- }
14227
- async function getAttachmentFolderPath(params) {
14228
- const {
14229
- app,
14230
- context = "Unknown",
14231
- notePathOrFile
14232
- } = params;
14233
- return parentFolderPath(
14234
- await getAttachmentFilePath({
14235
- app,
14236
- context,
14237
- notePathOrFile,
14238
- oldAttachmentPathOrFile: DUMMY_PATH,
14239
- shouldSkipDuplicateCheck: true
14240
- })
14241
- );
14242
- }
14243
- function getAttachmentFolderPathSyncOrNull(params) {
14244
- const {
14245
- app,
14246
- notePathOrFile
14247
- } = params;
14248
- return getExtendedFunction(app) ? null : parentFolderPath(getAttachmentFilePathSync({
14249
- app,
14250
- notePathOrFile,
14251
- oldAttachmentPathOrFile: DUMMY_PATH,
14252
- shouldSkipDuplicateCheck: true
14253
- }));
14254
- }
14255
- async function getAvailablePathForAttachments(params) {
14256
- const {
14257
- app,
14258
- notePathOrFile,
14259
- shouldSkipMissingAttachmentFolderCreation
14260
- } = params;
14261
- const attachmentFolder = resolveAttachmentFolder({ app, notePathOrFile });
14262
- if (!attachmentFolder.folder && attachmentFolder.relativePath && !shouldSkipMissingAttachmentFolderCreation) {
14263
- await app.vault.createFolder(attachmentFolder.path);
14264
- }
14265
- return getAvailablePathForAttachmentsSync(params);
14266
- }
14267
- function getCheckIsAttachmentUnitFolderFunction(app) {
14268
- return app.vault.getAvailablePathForAttachments.checkIsAttachmentUnitFolder;
14269
- }
14270
- async function hasOwnAttachmentFolder(params) {
14271
- const {
14272
- app,
14273
- context = "Unknown",
14274
- path
14275
- } = params;
14276
- const attachmentFolderPath = await getAttachmentFolderPath({
14277
- app,
14278
- context,
14279
- notePathOrFile: path
14280
- });
14281
- const dummyAttachmentFolderPath = await getAttachmentFolderPath({
14282
- app,
14283
- context,
14284
- notePathOrFile: join(dirname(path), `${DUMMY_PATH}.${MARKDOWN_FILE_EXTENSION}`)
14285
- });
14286
- return attachmentFolderPath !== dummyAttachmentFolderPath;
14287
- }
14288
- async function isAtProperAttachmentPath(params) {
14289
- const {
14290
- app,
14291
- attachmentPathOrFile,
14292
- context = "Unknown",
14293
- notePathOrFile
14294
- } = params;
14295
- const currentPath = getPath2(app, attachmentPathOrFile);
14296
- const properPath = await getAttachmentFilePath({
14297
- app,
14298
- context,
14299
- notePathOrFile,
14300
- oldAttachmentPathOrFile: attachmentPathOrFile,
14301
- shouldSkipDuplicateCheck: true
14302
- });
14303
- const isInsensitive = getDataAdapterEx(app).insensitive;
14304
- function fold(value) {
14305
- return isInsensitive ? value.toLowerCase() : value;
14306
- }
14307
- if (fold(dirname(currentPath)) !== fold(dirname(properPath))) {
14308
- return false;
14309
- }
14310
- const currentExtension = extname(currentPath);
14311
- const properExtension = extname(properPath);
14312
- if (fold(currentExtension) !== fold(properExtension)) {
14313
- return false;
14314
- }
14315
- const currentBaseName = basename(currentPath, currentExtension);
14316
- const properBaseName = basename(properPath, properExtension);
14317
- if (fold(currentBaseName) === fold(properBaseName)) {
14318
- return true;
14319
- }
14320
- const deduplicationPrefix = `${properBaseName} `;
14321
- if (!fold(currentBaseName).startsWith(fold(deduplicationPrefix))) {
14322
- return false;
14323
- }
14324
- const deduplicationSuffix = currentBaseName.slice(deduplicationPrefix.length);
14325
- return /^\d+$/.test(deduplicationSuffix);
14326
- }
14327
- function getAttachmentFilePathSync(params) {
14328
- const {
14329
- app,
14330
- notePathOrFile,
14331
- oldAttachmentPathOrFile,
14332
- shouldSkipDuplicateCheck
14333
- } = params;
14334
- const attachmentPath = getPath2(app, oldAttachmentPathOrFile);
14335
- const attachmentFileExtension = extname(attachmentPath);
14336
- return getAvailablePathForAttachmentsSync({
14337
- app,
14338
- attachmentFileBaseName: basename(attachmentPath, attachmentFileExtension),
14339
- attachmentFileExtension: attachmentFileExtension.slice(1),
14340
- notePathOrFile,
14341
- shouldSkipDuplicateCheck
14381
+ function createArgumentsSchema(parameters) {
14382
+ const parameterList = castTo(parameters);
14383
+ return createSchema((value) => {
14384
+ if (!Array.isArray(value)) {
14385
+ return { issues: [{ message: "Expected an argument list." }] };
14386
+ }
14387
+ if (value.length > parameterList.length) {
14388
+ return { issues: [{ message: `Expected at most ${String(parameterList.length)} argument(s), got ${String(value.length)}.` }] };
14389
+ }
14390
+ const issues = parameterList.flatMap((parameter, index2) => parameter.typeGuard(value[index2]) ? [] : [{ message: `Expected ${parameter.expected}.`, path: [index2] }]);
14391
+ return issues.length === 0 ? { value: castTo(value) } : { issues };
14342
14392
  });
14343
14393
  }
14344
- function getAvailablePathForAttachmentsSync(params) {
14345
- const {
14346
- app,
14347
- attachmentFileExtension,
14348
- notePathOrFile,
14349
- shouldSkipDuplicateCheck
14350
- } = params;
14351
- const attachmentFolder = resolveAttachmentFolder({ app, notePathOrFile });
14352
- const attachmentFileBaseName = normalizeString(normalizeSlashes(params.attachmentFileBaseName));
14353
- const folder = attachmentFolder.folder ?? getFolder({ app, pathOrFolder: attachmentFolder.path, shouldIncludeNonExisting: true });
14354
- const prefix = folder.getParentPrefix();
14355
- return shouldSkipDuplicateCheck ? makeFileName({
14356
- fileBaseName: prefix + attachmentFileBaseName,
14357
- fileExtension: attachmentFileExtension
14358
- }) : app.vault.getAvailablePath(prefix + attachmentFileBaseName, attachmentFileExtension);
14359
- }
14360
- function getExtendedFunction(app) {
14361
- return app.vault.getAvailablePathForAttachments.extended;
14394
+ function createTypeGuardSchema(params) {
14395
+ return createSchema((value) => params.typeGuard(value) ? { value } : { issues: [{ message: `Expected ${params.expected}.` }] });
14362
14396
  }
14363
- function normalizeSlashes(path) {
14364
- path = replaceAll({
14365
- $string: path,
14366
- replacer: "/",
14367
- searchValue: /(?:[\\/])+/g
14368
- });
14369
- path = replaceAll({
14370
- $string: path,
14371
- replacer: "",
14372
- searchValue: /^\/+|\/+$/g
14373
- });
14374
- return path || "/";
14375
- }
14376
- function resolveAttachmentFolder(params) {
14377
- const {
14378
- app,
14379
- notePathOrFile
14380
- } = params;
14381
- let attachmentFolderPath = app.vault.getConfig("attachmentFolderPath");
14382
- const isCurrentFolder = attachmentFolderPath === "." || attachmentFolderPath === "./";
14383
- const relativePath = attachmentFolderPath.startsWith("./") ? trimStart({
14384
- $string: attachmentFolderPath,
14385
- prefix: "./"
14386
- }) : null;
14387
- const noteFileOrNull = notePathOrFile === null ? null : getFile({
14388
- app,
14389
- pathOrFile: notePathOrFile,
14390
- shouldIncludeNonExisting: true
14391
- });
14392
- if (isCurrentFolder) {
14393
- attachmentFolderPath = noteFileOrNull ? noteFileOrNull.parent?.path ?? "" : "";
14394
- } else if (relativePath) {
14395
- attachmentFolderPath = (noteFileOrNull ? noteFileOrNull.parent?.getParentPrefix() ?? "" : "") + relativePath;
14396
- }
14397
- attachmentFolderPath = normalizeString(normalizeSlashes(attachmentFolderPath));
14397
+ function createSchema(validate) {
14398
14398
  return {
14399
- folder: getFolderOrNull({ app, isCaseInsensitive: true, pathOrFolder: attachmentFolderPath }),
14400
- path: attachmentFolderPath,
14401
- relativePath
14399
+ "~standard": {
14400
+ validate,
14401
+ vendor: OBSIDIAN_LIBRARY_NAME,
14402
+ version: 1
14403
+ }
14402
14404
  };
14403
14405
  }
14404
14406
 
14405
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/attachment-unit-folder.mjs
14406
- var attachment_unit_folder_exports = {};
14407
- __export(attachment_unit_folder_exports, {
14408
- findAttachmentUnitFolderPath: () => findAttachmentUnitFolderPath,
14409
- rebasePathOntoFolder: () => rebasePathOntoFolder
14407
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/plugin-api.mjs
14408
+ var plugin_api_exports = {};
14409
+ __export(plugin_api_exports, {
14410
+ PluginApiPayloadKind: () => PluginApiPayloadKind,
14411
+ PluginApiRevokedError: () => PluginApiRevokedError,
14412
+ PluginApiUnavailabilityReason: () => PluginApiUnavailabilityReason,
14413
+ PluginApiUnavailableError: () => PluginApiUnavailableError,
14414
+ PluginApiValidationError: () => PluginApiValidationError,
14415
+ findPluginApi: () => findPluginApi,
14416
+ publishPluginApi: () => publishPluginApi,
14417
+ watchPluginApi: () => watchPluginApi
14410
14418
  });
14411
- init_path();
14419
+ init_array();
14420
+ init_async();
14421
+ init_async_events();
14422
+ init_object_utils();
14423
+ var import_compare_versions = __toESM(require_umd(), 1);
14424
+ init_debug2();
14425
+ init_obsidian_dev_utils_state();
14426
+ (function() {
14427
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
14428
+ symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
14429
+ symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
14430
+ }
14431
+ function ensureBrowserProcess() {
14432
+ const browserProcess = {
14433
+ browser: true,
14434
+ cwd() {
14435
+ return "/";
14436
+ },
14437
+ env: {},
14438
+ platform: "android"
14439
+ };
14440
+ const existingProcess = globalThis.process;
14441
+ if (!existingProcess) {
14442
+ globalThis.process = browserProcess;
14443
+ return;
14444
+ }
14445
+ if (existingProcess.versions?.node) {
14446
+ return;
14447
+ }
14448
+ const existingProcessRecord = existingProcess;
14449
+ for (const [key, value] of Object.entries(browserProcess)) {
14450
+ existingProcessRecord[key] ??= value;
14451
+ }
14452
+ existingProcessRecord["browser"] = true;
14453
+ }
14454
+ (function initEsm() {
14455
+ ensureDisposeSymbols();
14456
+ ensureBrowserProcess();
14457
+ })();
14458
+ })();
14459
+ var PLUGIN_API_DEBUGGER_NAMESPACE = "PluginApi";
14460
+ var PLUGIN_API_REGISTRY_STATE_KEY = "pluginApiRegistry";
14461
+ var DEFAULT_WHEN_AVAILABLE_TIMEOUT_IN_MILLISECONDS = 1e4;
14462
+ var PluginApiPayloadKind = /* @__PURE__ */ ((PluginApiPayloadKind2) => {
14463
+ PluginApiPayloadKind2["Input"] = "input";
14464
+ PluginApiPayloadKind2["Output"] = "output";
14465
+ return PluginApiPayloadKind2;
14466
+ })(PluginApiPayloadKind || {});
14467
+ var PluginApiUnavailabilityReason = /* @__PURE__ */ ((PluginApiUnavailabilityReason2) => {
14468
+ PluginApiUnavailabilityReason2["NotEnabled"] = "notEnabled";
14469
+ PluginApiUnavailabilityReason2["NotInstalled"] = "notInstalled";
14470
+ PluginApiUnavailabilityReason2["NotPublished"] = "notPublished";
14471
+ PluginApiUnavailabilityReason2["Revoked"] = "revoked";
14472
+ PluginApiUnavailabilityReason2["ShapeMismatch"] = "shapeMismatch";
14473
+ PluginApiUnavailabilityReason2["VersionMismatch"] = "versionMismatch";
14474
+ return PluginApiUnavailabilityReason2;
14475
+ })(PluginApiUnavailabilityReason || {});
14476
+ var PluginApiWatchBase = class {
14477
+ // A `protected` constructor is not assignable to `AbstractConstructor<object>`, which is what
14478
+ // `mixinAsyncEvents` accepts, so this stays public even though only the subclass below calls it.
14479
+ constructor(params) {
14480
+ this.params = params;
14481
+ }
14482
+ params;
14483
+ handle = null;
14484
+ record = null;
14485
+ /**
14486
+ * Builds the error describing why the API is not available right now.
14487
+ *
14488
+ * @returns The classified error.
14489
+ */
14490
+ createUnavailableError() {
14491
+ return new PluginApiUnavailableError({
14492
+ pluginId: this.params.pluginId,
14493
+ reason: resolveUnavailabilityReason(this.params)
14494
+ });
14495
+ }
14496
+ };
14497
+ var PluginApiRefImpl = class extends mixinAsyncEvents()(PluginApiWatchBase) {
14498
+ get value() {
14499
+ return castTo(this.handle);
14500
+ }
14501
+ constructor(params) {
14502
+ super(params);
14503
+ }
14504
+ /**
14505
+ * Recomputes the current value from the registry, firing `change` only when it actually changed.
14506
+ */
14507
+ refresh() {
14508
+ const record = selectRecord(this.params);
14509
+ if (record === this.record) {
14510
+ return;
14511
+ }
14512
+ this.record = record;
14513
+ this.handle = record === null ? null : createRevocableHandle(record, this.params.contract);
14514
+ this.trigger("change");
14515
+ }
14516
+ async whenAvailable(options) {
14517
+ const currentValue = this.value;
14518
+ if (currentValue !== null) {
14519
+ return currentValue;
14520
+ }
14521
+ try {
14522
+ return await runWithTimeout({
14523
+ operationFunction: async (abortSignal) => await this.waitForValue(abortSignal),
14524
+ operationName: `watchPluginApi("${this.params.pluginId}").whenAvailable`,
14525
+ timeoutInMilliseconds: options?.timeoutInMilliseconds ?? DEFAULT_WHEN_AVAILABLE_TIMEOUT_IN_MILLISECONDS
14526
+ });
14527
+ } catch {
14528
+ throw this.createUnavailableError();
14529
+ }
14530
+ }
14531
+ async waitForValue(abortSignal) {
14532
+ return await new Promise((resolve2, reject) => {
14533
+ const eventRef = this.on("change", () => {
14534
+ handleChange();
14535
+ });
14536
+ function cleanUp() {
14537
+ eventRef.asyncEventSource.offref(eventRef);
14538
+ abortSignal.removeEventListener("abort", handleAbort);
14539
+ }
14540
+ function handleAbort() {
14541
+ cleanUp();
14542
+ reject(abortSignal.reason);
14543
+ }
14544
+ const handleChange = () => {
14545
+ const value = this.value;
14546
+ if (value === null) {
14547
+ return;
14548
+ }
14549
+ cleanUp();
14550
+ resolve2(value);
14551
+ };
14552
+ abortSignal.addEventListener("abort", handleAbort);
14553
+ handleChange();
14554
+ });
14555
+ }
14556
+ };
14557
+ var PluginApiUnavailableError = class extends Error {
14558
+ /**
14559
+ * The `manifest.id` of the plugin whose API was requested.
14560
+ */
14561
+ pluginId;
14562
+ /**
14563
+ * Which of the five failures occurred.
14564
+ */
14565
+ reason;
14566
+ /**
14567
+ * Creates a {@link PluginApiUnavailableError}.
14568
+ *
14569
+ * @param params - The parameters for the error.
14570
+ */
14571
+ constructor(params) {
14572
+ super(params.message ?? `The API of the plugin "${params.pluginId}" is unavailable: ${params.reason}.`);
14573
+ this.name = "PluginApiUnavailableError";
14574
+ this.pluginId = params.pluginId;
14575
+ this.reason = params.reason;
14576
+ }
14577
+ };
14578
+ var PluginApiRevokedError = class extends PluginApiUnavailableError {
14579
+ /**
14580
+ * Creates a {@link PluginApiRevokedError}.
14581
+ *
14582
+ * @param pluginId - The `manifest.id` of the plugin whose API was revoked.
14583
+ */
14584
+ constructor(pluginId) {
14585
+ super({
14586
+ message: `The API of the plugin "${pluginId}" has been revoked, because the plugin was unloaded.`,
14587
+ pluginId,
14588
+ reason: "revoked"
14589
+ /* Revoked */
14590
+ });
14591
+ this.name = "PluginApiRevokedError";
14592
+ }
14593
+ };
14594
+ var PluginApiValidationError = class extends Error {
14595
+ /**
14596
+ * The issues the schema reported.
14597
+ */
14598
+ issues;
14599
+ /**
14600
+ * The name of the method whose payload failed validation.
14601
+ */
14602
+ methodName;
14603
+ /**
14604
+ * The `manifest.id` of the providing plugin.
14605
+ */
14606
+ pluginId;
14607
+ /**
14608
+ * Creates a {@link PluginApiValidationError}.
14609
+ *
14610
+ * @param params - The parameters for the error.
14611
+ */
14612
+ constructor(params) {
14613
+ super(
14614
+ `The ${params.payloadKind} of "${params.pluginId}" API method "${params.methodName}" failed validation: ${formatIssues(params.issues)}`
14615
+ );
14616
+ this.name = "PluginApiValidationError";
14617
+ this.issues = params.issues;
14618
+ this.methodName = params.methodName;
14619
+ this.pluginId = params.pluginId;
14620
+ }
14621
+ };
14622
+ function findPluginApi(params) {
14623
+ const record = selectRecord(params);
14624
+ return record === null ? null : castTo(createRevocableHandle(record, params.contract));
14625
+ }
14626
+ function publishPluginApi(params) {
14627
+ const pluginId = params.plugin.manifest.id;
14628
+ const registry = getRegistry();
14629
+ const records = registry.records[pluginId] ?? [];
14630
+ registry.records[pluginId] = records;
14631
+ if (records.some((record2) => record2.apiVersion === params.apiVersion)) {
14632
+ throw new Error(`The plugin "${pluginId}" has already published the API version "${params.apiVersion}".`);
14633
+ }
14634
+ const record = {
14635
+ api: params.api,
14636
+ apiVersion: params.apiVersion,
14637
+ contract: params.contract ?? {},
14638
+ isRevoked: false,
14639
+ pluginId
14640
+ };
14641
+ records.push(record);
14642
+ notifySubscribers();
14643
+ (params.component ?? params.plugin).register(() => {
14644
+ revokeRecord(record);
14645
+ });
14646
+ }
14647
+ function watchPluginApi(params) {
14648
+ const ref = new PluginApiRefImpl(params);
14649
+ const unsubscribe = subscribe(() => {
14650
+ ref.refresh();
14651
+ });
14652
+ params.component.register(unsubscribe);
14653
+ ref.refresh();
14654
+ return ref;
14655
+ }
14656
+ function checkIsPromiseLike(value) {
14657
+ return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
14658
+ }
14659
+ function checkMatchesContractShape(record, consumerContract) {
14660
+ const contract = consumerContract ?? record.contract;
14661
+ return Object.keys(contract).every((methodName) => typeof getMember(record.api, methodName) === "function");
14662
+ }
14663
+ function createMethodWrapper(params) {
14664
+ return function pluginApiMethod(...$arguments) {
14665
+ const method = castTo(getMember(params.target, params.propertyKey));
14666
+ const methodContract = params.methodContract;
14667
+ if (methodContract === void 0 || !getPluginApiDebugger().enabled) {
14668
+ return method.apply(params.target, $arguments);
14669
+ }
14670
+ if (methodContract.input) {
14671
+ validatePayload({
14672
+ methodName: params.methodName,
14673
+ payloadKind: "input",
14674
+ pluginId: params.pluginId,
14675
+ schema: methodContract.input,
14676
+ value: $arguments
14677
+ });
14678
+ }
14679
+ const returnValue = method.apply(params.target, $arguments);
14680
+ const outputSchema = methodContract.output;
14681
+ if (!outputSchema) {
14682
+ return returnValue;
14683
+ }
14684
+ if (checkIsPromiseLike(returnValue)) {
14685
+ return returnValue.then((resolvedValue) => {
14686
+ validatePayload({
14687
+ methodName: params.methodName,
14688
+ payloadKind: "output",
14689
+ pluginId: params.pluginId,
14690
+ schema: outputSchema,
14691
+ value: resolvedValue
14692
+ });
14693
+ return resolvedValue;
14694
+ });
14695
+ }
14696
+ validatePayload({
14697
+ methodName: params.methodName,
14698
+ payloadKind: "output",
14699
+ pluginId: params.pluginId,
14700
+ schema: outputSchema,
14701
+ value: returnValue
14702
+ });
14703
+ return returnValue;
14704
+ };
14705
+ }
14706
+ function createRevocableHandle(record, consumerContract) {
14707
+ const contract = consumerContract ?? record.contract;
14708
+ const methodCache = /* @__PURE__ */ new Map();
14709
+ return new Proxy(record.api, {
14710
+ get(target, propertyKey) {
14711
+ if (record.isRevoked) {
14712
+ throw new PluginApiRevokedError(record.pluginId);
14713
+ }
14714
+ const value = getMember(target, propertyKey);
14715
+ if (typeof value !== "function") {
14716
+ return value;
14717
+ }
14718
+ let method = methodCache.get(propertyKey);
14719
+ if (method === void 0) {
14720
+ method = createMethodWrapper({
14721
+ methodContract: typeof propertyKey === "string" ? contract[propertyKey] : void 0,
14722
+ methodName: String(propertyKey),
14723
+ pluginId: record.pluginId,
14724
+ propertyKey,
14725
+ target
14726
+ });
14727
+ methodCache.set(propertyKey, method);
14728
+ }
14729
+ return method;
14730
+ }
14731
+ });
14732
+ }
14733
+ function formatIssues(issues) {
14734
+ return issues.map((issue) => {
14735
+ const path = issue.path?.map((segment) => String(typeof segment === "object" ? segment.key : segment)).join(".");
14736
+ return path ? `${path}: ${issue.message}` : issue.message;
14737
+ }).join("; ");
14738
+ }
14739
+ function getLiveRecords(pluginId) {
14740
+ return (getRegistry().records[pluginId] ?? []).filter((record) => !record.isRevoked);
14741
+ }
14742
+ function getMember(api, methodName) {
14743
+ return Reflect.get(api, methodName);
14744
+ }
14745
+ function getPluginApiDebugger() {
14746
+ return getObsidianLibDebugger(PLUGIN_API_DEBUGGER_NAMESPACE);
14747
+ }
14748
+ function getRegistry() {
14749
+ const wrapper = getObsidianDevUtilsState(PLUGIN_API_REGISTRY_STATE_KEY, {});
14750
+ const registry = wrapper.value;
14751
+ registry.records ??= {};
14752
+ registry.subscribers ??= [];
14753
+ return castTo(registry);
14754
+ }
14755
+ function notifySubscribers() {
14756
+ for (const subscriber of snapshot(getRegistry().subscribers)) {
14757
+ subscriber();
14758
+ }
14759
+ }
14760
+ function resolveUnavailabilityReason(params) {
14761
+ if (!Object.hasOwn(params.app.plugins.manifests, params.pluginId)) {
14762
+ return "notInstalled";
14763
+ }
14764
+ if (!params.app.plugins.enabledPlugins.has(params.pluginId)) {
14765
+ return "notEnabled";
14766
+ }
14767
+ const records = getLiveRecords(params.pluginId);
14768
+ if (records.length === 0) {
14769
+ return "notPublished";
14770
+ }
14771
+ return records.every((record) => !(0, import_compare_versions.satisfies)(record.apiVersion, params.apiVersionRange)) ? "versionMismatch" : "shapeMismatch";
14772
+ }
14773
+ function revokeRecord(record) {
14774
+ record.isRevoked = true;
14775
+ const registry = getRegistry();
14776
+ const records = registry.records[record.pluginId];
14777
+ if (records) {
14778
+ registry.records[record.pluginId] = records.filter((candidate) => candidate !== record);
14779
+ }
14780
+ notifySubscribers();
14781
+ }
14782
+ function selectRecord(params) {
14783
+ const candidates2 = getLiveRecords(params.pluginId).filter((record) => (0, import_compare_versions.satisfies)(record.apiVersion, params.apiVersionRange)).filter((record) => checkMatchesContractShape(record, params.contract)).sort((a2, b) => (0, import_compare_versions.compareVersions)(b.apiVersion, a2.apiVersion));
14784
+ return candidates2[0] ?? null;
14785
+ }
14786
+ function subscribe(subscriber) {
14787
+ const registry = getRegistry();
14788
+ registry.subscribers.push(subscriber);
14789
+ return () => {
14790
+ const index2 = registry.subscribers.indexOf(subscriber);
14791
+ if (index2 !== -1) {
14792
+ registry.subscribers.splice(index2, 1);
14793
+ }
14794
+ };
14795
+ }
14796
+ function validatePayload(params) {
14797
+ const result = params.schema["~standard"].validate(params.value);
14798
+ if (checkIsPromiseLike(result)) {
14799
+ invokeAsyncSafely(async () => {
14800
+ const asyncResult = await result;
14801
+ if (asyncResult.issues) {
14802
+ getPluginApiDebugger()(
14803
+ 'Asynchronous validation of the %s of "%s" API method "%s" failed: %s',
14804
+ params.payloadKind,
14805
+ params.pluginId,
14806
+ params.methodName,
14807
+ formatIssues(asyncResult.issues)
14808
+ );
14809
+ }
14810
+ });
14811
+ return;
14812
+ }
14813
+ if (result.issues) {
14814
+ throw new PluginApiValidationError({
14815
+ issues: result.issues,
14816
+ methodName: params.methodName,
14817
+ payloadKind: params.payloadKind,
14818
+ pluginId: params.pluginId
14819
+ });
14820
+ }
14821
+ }
14822
+
14823
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/attachment-path.mjs
14824
+ (function() {
14825
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
14826
+ symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
14827
+ symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
14828
+ }
14829
+ function ensureBrowserProcess() {
14830
+ const browserProcess = {
14831
+ browser: true,
14832
+ cwd() {
14833
+ return "/";
14834
+ },
14835
+ env: {},
14836
+ platform: "android"
14837
+ };
14838
+ const existingProcess = globalThis.process;
14839
+ if (!existingProcess) {
14840
+ globalThis.process = browserProcess;
14841
+ return;
14842
+ }
14843
+ if (existingProcess.versions?.node) {
14844
+ return;
14845
+ }
14846
+ const existingProcessRecord = existingProcess;
14847
+ for (const [key, value] of Object.entries(browserProcess)) {
14848
+ existingProcessRecord[key] ??= value;
14849
+ }
14850
+ existingProcessRecord["browser"] = true;
14851
+ }
14852
+ (function initEsm() {
14853
+ ensureDisposeSymbols();
14854
+ ensureBrowserProcess();
14855
+ })();
14856
+ })();
14857
+ var AttachmentPathContext = /* @__PURE__ */ ((AttachmentPathContext2) => {
14858
+ AttachmentPathContext2["DeleteNote"] = "DeleteNote";
14859
+ AttachmentPathContext2["RenameNote"] = "RenameNote";
14860
+ AttachmentPathContext2["Unknown"] = "Unknown";
14861
+ return AttachmentPathContext2;
14862
+ })(AttachmentPathContext || {});
14863
+ var CUSTOM_ATTACHMENT_LOCATION_PLUGIN_ID = "obsidian-custom-attachment-location";
14864
+ var CUSTOM_ATTACHMENT_LOCATION_ATTACHMENT_PATH_API_VERSION_RANGE = "^1.3.0";
14865
+ var CUSTOM_ATTACHMENT_LOCATION_ATTACHMENT_PATH_API_CONTRACT = {
14866
+ getAvailablePathForAttachments: {
14867
+ input: createArgumentsSchema([{
14868
+ expected: "available-path-for-attachments params",
14869
+ typeGuard: isGetAvailablePathForAttachmentsExtendedFunctionParams
14870
+ }]),
14871
+ output: createTypeGuardSchema({ expected: "an attachment path", typeGuard: isString2 })
14872
+ },
14873
+ isAttachmentUnitFolder: {
14874
+ input: createArgumentsSchema([{
14875
+ expected: "attachment-unit-folder params: { folderPath: string }",
14876
+ typeGuard: isCustomAttachmentLocationIsAttachmentUnitFolderParams
14877
+ }]),
14878
+ output: createTypeGuardSchema({ expected: "a boolean", typeGuard: isBoolean })
14879
+ }
14880
+ };
14881
+ var DUMMY_PATH = "__DUMMY__";
14882
+ async function getAttachmentFilePath(params) {
14883
+ const {
14884
+ app,
14885
+ notePathOrFile,
14886
+ oldAttachmentPathOrFile,
14887
+ shouldSkipDuplicateCheck
14888
+ } = params;
14889
+ const customAttachmentLocationApi = findCustomAttachmentLocationApi();
14890
+ if (!customAttachmentLocationApi) {
14891
+ return getAttachmentFilePathSync({
14892
+ app,
14893
+ notePathOrFile,
14894
+ oldAttachmentPathOrFile,
14895
+ shouldSkipDuplicateCheck
14896
+ });
14897
+ }
14898
+ const attachmentPath = getPath2(app, oldAttachmentPathOrFile);
14899
+ const attachmentFileExtension = extname(attachmentPath);
14900
+ const attachmentFileBaseName = basename(attachmentPath, attachmentFileExtension);
14901
+ const attachmentFile = getFileOrNull({ app, pathOrFile: attachmentPath });
14902
+ return await customAttachmentLocationApi.getAvailablePathForAttachments({
14903
+ attachmentFileBaseName,
14904
+ attachmentFileExtension: attachmentFileExtension.slice(1),
14905
+ attachmentFileStats: attachmentFile?.stat,
14906
+ context: params.context,
14907
+ notePathOrFile,
14908
+ oldAttachmentPathOrFile,
14909
+ oldNotePathOrFile: params.oldNotePathOrFile,
14910
+ readAttachmentFileContent: attachmentFile ? () => app.vault.readBinary(attachmentFile) : null,
14911
+ shouldSkipDuplicateCheck,
14912
+ shouldSkipMissingAttachmentFolderCreation: true
14913
+ });
14914
+ }
14915
+ async function getAttachmentFolderPath(params) {
14916
+ const {
14917
+ app,
14918
+ context = "Unknown",
14919
+ notePathOrFile
14920
+ } = params;
14921
+ return parentFolderPath(
14922
+ await getAttachmentFilePath({
14923
+ app,
14924
+ context,
14925
+ notePathOrFile,
14926
+ oldAttachmentPathOrFile: DUMMY_PATH,
14927
+ shouldSkipDuplicateCheck: true
14928
+ })
14929
+ );
14930
+ }
14931
+ function getAttachmentFolderPathSyncOrNull(params) {
14932
+ const {
14933
+ app,
14934
+ notePathOrFile
14935
+ } = params;
14936
+ return findCustomAttachmentLocationApi() ? null : parentFolderPath(getAttachmentFilePathSync({
14937
+ app,
14938
+ notePathOrFile,
14939
+ oldAttachmentPathOrFile: DUMMY_PATH,
14940
+ shouldSkipDuplicateCheck: true
14941
+ }));
14942
+ }
14943
+ async function getAvailablePathForAttachments(params) {
14944
+ const {
14945
+ app,
14946
+ notePathOrFile,
14947
+ shouldSkipMissingAttachmentFolderCreation
14948
+ } = params;
14949
+ const attachmentFolder = resolveAttachmentFolder({ app, notePathOrFile });
14950
+ if (!attachmentFolder.folder && attachmentFolder.relativePath && !shouldSkipMissingAttachmentFolderCreation) {
14951
+ await app.vault.createFolder(attachmentFolder.path);
14952
+ }
14953
+ return getAvailablePathForAttachmentsSync(params);
14954
+ }
14955
+ function getCheckIsAttachmentUnitFolderFunction(_app) {
14956
+ const customAttachmentLocationApi = findCustomAttachmentLocationApi();
14957
+ return customAttachmentLocationApi ? (folderPath) => customAttachmentLocationApi.isAttachmentUnitFolder({ folderPath }) : void 0;
14958
+ }
14959
+ async function hasOwnAttachmentFolder(params) {
14960
+ const {
14961
+ app,
14962
+ context = "Unknown",
14963
+ path
14964
+ } = params;
14965
+ const attachmentFolderPath = await getAttachmentFolderPath({
14966
+ app,
14967
+ context,
14968
+ notePathOrFile: path
14969
+ });
14970
+ const dummyAttachmentFolderPath = await getAttachmentFolderPath({
14971
+ app,
14972
+ context,
14973
+ notePathOrFile: join(dirname(path), `${DUMMY_PATH}.${MARKDOWN_FILE_EXTENSION}`)
14974
+ });
14975
+ return attachmentFolderPath !== dummyAttachmentFolderPath;
14976
+ }
14977
+ async function isAtProperAttachmentPath(params) {
14978
+ const {
14979
+ app,
14980
+ attachmentPathOrFile,
14981
+ context = "Unknown",
14982
+ notePathOrFile
14983
+ } = params;
14984
+ const currentPath = getPath2(app, attachmentPathOrFile);
14985
+ const properPath = await getAttachmentFilePath({
14986
+ app,
14987
+ context,
14988
+ notePathOrFile,
14989
+ oldAttachmentPathOrFile: attachmentPathOrFile,
14990
+ shouldSkipDuplicateCheck: true
14991
+ });
14992
+ const isInsensitive = getDataAdapterEx(app).insensitive;
14993
+ function fold(value) {
14994
+ return isInsensitive ? value.toLowerCase() : value;
14995
+ }
14996
+ if (fold(dirname(currentPath)) !== fold(dirname(properPath))) {
14997
+ return false;
14998
+ }
14999
+ const currentExtension = extname(currentPath);
15000
+ const properExtension = extname(properPath);
15001
+ if (fold(currentExtension) !== fold(properExtension)) {
15002
+ return false;
15003
+ }
15004
+ const currentBaseName = basename(currentPath, currentExtension);
15005
+ const properBaseName = basename(properPath, properExtension);
15006
+ if (fold(currentBaseName) === fold(properBaseName)) {
15007
+ return true;
15008
+ }
15009
+ const deduplicationPrefix = `${properBaseName} `;
15010
+ if (!fold(currentBaseName).startsWith(fold(deduplicationPrefix))) {
15011
+ return false;
15012
+ }
15013
+ const deduplicationSuffix = currentBaseName.slice(deduplicationPrefix.length);
15014
+ return /^\d+$/.test(deduplicationSuffix);
15015
+ }
15016
+ function findCustomAttachmentLocationApi() {
15017
+ return findPluginApi({
15018
+ apiVersionRange: CUSTOM_ATTACHMENT_LOCATION_ATTACHMENT_PATH_API_VERSION_RANGE,
15019
+ contract: CUSTOM_ATTACHMENT_LOCATION_ATTACHMENT_PATH_API_CONTRACT,
15020
+ pluginId: CUSTOM_ATTACHMENT_LOCATION_PLUGIN_ID
15021
+ });
15022
+ }
15023
+ function getAttachmentFilePathSync(params) {
15024
+ const {
15025
+ app,
15026
+ notePathOrFile,
15027
+ oldAttachmentPathOrFile,
15028
+ shouldSkipDuplicateCheck
15029
+ } = params;
15030
+ const attachmentPath = getPath2(app, oldAttachmentPathOrFile);
15031
+ const attachmentFileExtension = extname(attachmentPath);
15032
+ return getAvailablePathForAttachmentsSync({
15033
+ app,
15034
+ attachmentFileBaseName: basename(attachmentPath, attachmentFileExtension),
15035
+ attachmentFileExtension: attachmentFileExtension.slice(1),
15036
+ notePathOrFile,
15037
+ shouldSkipDuplicateCheck
15038
+ });
15039
+ }
15040
+ function getAvailablePathForAttachmentsSync(params) {
15041
+ const {
15042
+ app,
15043
+ attachmentFileExtension,
15044
+ notePathOrFile,
15045
+ shouldSkipDuplicateCheck
15046
+ } = params;
15047
+ const attachmentFolder = resolveAttachmentFolder({ app, notePathOrFile });
15048
+ const attachmentFileBaseName = normalizeString(normalizeSlashes(params.attachmentFileBaseName));
15049
+ const folder = attachmentFolder.folder ?? getFolder({ app, pathOrFolder: attachmentFolder.path, shouldIncludeNonExisting: true });
15050
+ const prefix = folder.getParentPrefix();
15051
+ return shouldSkipDuplicateCheck ? makeFileName({
15052
+ fileBaseName: prefix + attachmentFileBaseName,
15053
+ fileExtension: attachmentFileExtension
15054
+ }) : app.vault.getAvailablePath(prefix + attachmentFileBaseName, attachmentFileExtension);
15055
+ }
15056
+ function isBoolean(value) {
15057
+ return typeof value === "boolean";
15058
+ }
15059
+ function isCustomAttachmentLocationIsAttachmentUnitFolderParams(value) {
15060
+ return typeof value === "object" && value !== null && typeof Reflect.get(value, "folderPath") === "string";
15061
+ }
15062
+ function isFileStats(value) {
15063
+ return typeof value === "object" && value !== null && typeof Reflect.get(value, "ctime") === "number" && typeof Reflect.get(value, "mtime") === "number" && typeof Reflect.get(value, "size") === "number";
15064
+ }
15065
+ function isGetAvailablePathForAttachmentsExtendedFunctionParams(value) {
15066
+ if (typeof value !== "object" || value === null) {
15067
+ return false;
15068
+ }
15069
+ function read(key) {
15070
+ return Reflect.get(value, key);
15071
+ }
15072
+ const attachmentFileStats = read("attachmentFileStats");
15073
+ const context = read("context");
15074
+ const notePathOrFile = read("notePathOrFile");
15075
+ const oldNotePathOrFile = read("oldNotePathOrFile");
15076
+ const readAttachmentFileContent = read("readAttachmentFileContent");
15077
+ return typeof read("attachmentFileBaseName") === "string" && typeof read("attachmentFileExtension") === "string" && (attachmentFileStats === void 0 || isFileStats(attachmentFileStats)) && Object.values(AttachmentPathContext).includes(context) && (notePathOrFile === null || isPathOrFile(notePathOrFile)) && isPathOrFile(read("oldAttachmentPathOrFile")) && (oldNotePathOrFile === void 0 || isPathOrFile(oldNotePathOrFile)) && (readAttachmentFileContent === null || typeof readAttachmentFileContent === "function") && isOptionalBoolean(read("shouldSkipDuplicateCheck")) && isOptionalBoolean(read("shouldSkipGeneratedAttachmentFileName")) && isOptionalBoolean(read("shouldSkipMissingAttachmentFolderCreation"));
15078
+ }
15079
+ function isOptionalBoolean(value) {
15080
+ return value === void 0 || isBoolean(value);
15081
+ }
15082
+ function isString2(value) {
15083
+ return typeof value === "string";
15084
+ }
15085
+ function normalizeSlashes(path) {
15086
+ path = replaceAll({
15087
+ $string: path,
15088
+ replacer: "/",
15089
+ searchValue: /(?:[\\/])+/g
15090
+ });
15091
+ path = replaceAll({
15092
+ $string: path,
15093
+ replacer: "",
15094
+ searchValue: /^\/+|\/+$/g
15095
+ });
15096
+ return path || "/";
15097
+ }
15098
+ function resolveAttachmentFolder(params) {
15099
+ const {
15100
+ app,
15101
+ notePathOrFile
15102
+ } = params;
15103
+ let attachmentFolderPath = app.vault.getConfig("attachmentFolderPath");
15104
+ const isCurrentFolder = attachmentFolderPath === "." || attachmentFolderPath === "./";
15105
+ const relativePath = attachmentFolderPath.startsWith("./") ? trimStart({
15106
+ $string: attachmentFolderPath,
15107
+ prefix: "./"
15108
+ }) : null;
15109
+ const noteFileOrNull = notePathOrFile === null ? null : getFile({
15110
+ app,
15111
+ pathOrFile: notePathOrFile,
15112
+ shouldIncludeNonExisting: true
15113
+ });
15114
+ if (isCurrentFolder) {
15115
+ attachmentFolderPath = noteFileOrNull ? noteFileOrNull.parent?.path ?? "" : "";
15116
+ } else if (relativePath) {
15117
+ attachmentFolderPath = (noteFileOrNull ? noteFileOrNull.parent?.getParentPrefix() ?? "" : "") + relativePath;
15118
+ }
15119
+ attachmentFolderPath = normalizeString(normalizeSlashes(attachmentFolderPath));
15120
+ return {
15121
+ folder: getFolderOrNull({ app, isCaseInsensitive: true, pathOrFolder: attachmentFolderPath }),
15122
+ path: attachmentFolderPath,
15123
+ relativePath
15124
+ };
15125
+ }
15126
+
15127
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/attachment-unit-folder.mjs
15128
+ var attachment_unit_folder_exports = {};
15129
+ __export(attachment_unit_folder_exports, {
15130
+ findAttachmentUnitFolderPath: () => findAttachmentUnitFolderPath,
15131
+ rebasePathOntoFolder: () => rebasePathOntoFolder
15132
+ });
15133
+ init_path();
14412
15134
  (function() {
14413
15135
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
14414
15136
  symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
@@ -25948,6 +26670,15 @@ var CachedMetadataExFeature = /* @__PURE__ */ ((CachedMetadataExFeature2) => {
25948
26670
  return CachedMetadataExFeature2;
25949
26671
  })(CachedMetadataExFeature || {});
25950
26672
  var ADVANCED_METADATA_CACHE_PLUGIN_ID = "advanced-metadata-cache";
26673
+ var ADVANCED_METADATA_CACHE_BACKLINKS_API_VERSION_RANGE = "^1.3.0";
26674
+ var ADVANCED_METADATA_CACHE_BACKLINKS_METHOD_CONTRACT = {
26675
+ input: createArgumentsSchema([{ expected: "a path or a file", typeGuard: isPathOrFile }]),
26676
+ output: createTypeGuardSchema({ expected: "a backlinks dictionary or null", typeGuard: isNullableBacklinksDict })
26677
+ };
26678
+ var ADVANCED_METADATA_CACHE_BACKLINKS_API_CONTRACT = {
26679
+ getBacklinksForFile: ADVANCED_METADATA_CACHE_BACKLINKS_METHOD_CONTRACT,
26680
+ getBacklinksForFileSafe: ADVANCED_METADATA_CACHE_BACKLINKS_METHOD_CONTRACT
26681
+ };
25951
26682
  var BACKLINK_CACHE_PLUGIN_ID = "backlink-cache";
25952
26683
  async function ensureMetadataCacheReady(app) {
25953
26684
  await new Promise((resolve2) => {
@@ -25959,7 +26690,7 @@ function getBacklinksForFileOrPath(app, pathOrFile) {
25959
26690
  try {
25960
26691
  const file = getFile({ app, pathOrFile, shouldIncludeNonExisting: true });
25961
26692
  const _registration = __using2(_stack, registerFiles(app, [file]));
25962
- return hasBacklinkCacheSafeOverload(app) ? app.metadataCache.getBacklinksForFile(file) : getIndexedBacklinksForFile(app, file);
26693
+ return findAdvancedMetadataCacheBacklinksApi()?.getBacklinksForFile(file) ?? getIndexedBacklinksForFile(app, file);
25963
26694
  } catch (_) {
25964
26695
  var _error = _, _hasError = true;
25965
26696
  } finally {
@@ -25968,9 +26699,9 @@ function getBacklinksForFileOrPath(app, pathOrFile) {
25968
26699
  }
25969
26700
  async function getBacklinksForFileSafe(params) {
25970
26701
  const { app, pathOrFile, ...options } = params;
25971
- const safeOverload = app.metadataCache.getBacklinksForFile.safe;
25972
- if (safeOverload) {
25973
- return safeOverload(pathOrFile);
26702
+ const cachedBacklinks = await findAdvancedMetadataCacheBacklinksApi()?.getBacklinksForFileSafe(pathOrFile);
26703
+ if (cachedBacklinks) {
26704
+ return cachedBacklinks;
25974
26705
  }
25975
26706
  let backlinks = new CustomArrayDictImpl();
25976
26707
  await retryWithTimeoutNotice({
@@ -26217,11 +26948,18 @@ function unregisterFiles(app, files) {
26217
26948
  }
26218
26949
  }
26219
26950
  }
26951
+ function findAdvancedMetadataCacheBacklinksApi() {
26952
+ return findPluginApi({
26953
+ apiVersionRange: ADVANCED_METADATA_CACHE_BACKLINKS_API_VERSION_RANGE,
26954
+ contract: ADVANCED_METADATA_CACHE_BACKLINKS_API_CONTRACT,
26955
+ pluginId: ADVANCED_METADATA_CACHE_PLUGIN_ID
26956
+ });
26957
+ }
26220
26958
  function getRegisteredFilesCounts() {
26221
26959
  return getObsidianDevUtilsState("registeredFilesCounts", /* @__PURE__ */ new Map()).value;
26222
26960
  }
26223
- function hasBacklinkCacheSafeOverload(app) {
26224
- return !!app.metadataCache.getBacklinksForFile.safe;
26961
+ function isNullableBacklinksDict(value) {
26962
+ return value === null || typeof value === "object" && Reflect.get(value, "data") instanceof Map && typeof Reflect.get(value, "get") === "function" && typeof Reflect.get(value, "keys") === "function";
26225
26963
  }
26226
26964
  function parseExternalBodyLinks(content3, cache) {
26227
26965
  const frontmatterEndOffset = cache.frontmatterPosition?.end.offset ?? 0;
@@ -26270,83 +27008,7 @@ function toParsedCachedMetadataEx(params) {
26270
27008
 
26271
27009
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/link.mjs
26272
27010
  init_obsidian_dev_utils_state();
26273
-
26274
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/obsidian-settings.mjs
26275
- var obsidian_settings_exports = {};
26276
- __export(obsidian_settings_exports, {
26277
- SpellcheckMode: () => SpellcheckMode,
26278
- getNewLinkFormat: () => getNewLinkFormat,
26279
- isSpellcheckEnabled: () => isSpellcheckEnabled,
26280
- isSpellcheckEnabledForMode: () => isSpellcheckEnabledForMode,
26281
- shouldUseWikilinks: () => shouldUseWikilinks
26282
- });
26283
- init_type_guards();
26284
- (function() {
26285
- function ensureDisposeSymbols(symbolConstructor = Symbol) {
26286
- symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
26287
- symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
26288
- }
26289
- function ensureBrowserProcess() {
26290
- const browserProcess = {
26291
- browser: true,
26292
- cwd() {
26293
- return "/";
26294
- },
26295
- env: {},
26296
- platform: "android"
26297
- };
26298
- const existingProcess = globalThis.process;
26299
- if (!existingProcess) {
26300
- globalThis.process = browserProcess;
26301
- return;
26302
- }
26303
- if (existingProcess.versions?.node) {
26304
- return;
26305
- }
26306
- const existingProcessRecord = existingProcess;
26307
- for (const [key, value] of Object.entries(browserProcess)) {
26308
- existingProcessRecord[key] ??= value;
26309
- }
26310
- existingProcessRecord["browser"] = true;
26311
- }
26312
- (function initEsm() {
26313
- ensureDisposeSymbols();
26314
- ensureBrowserProcess();
26315
- })();
26316
- })();
26317
- var SpellcheckMode = /* @__PURE__ */ ((SpellcheckMode2) => {
26318
- SpellcheckMode2["AlwaysOn"] = "AlwaysOn";
26319
- SpellcheckMode2["FollowObsidianSetting"] = "FollowObsidianSetting";
26320
- SpellcheckMode2["Off"] = "Off";
26321
- return SpellcheckMode2;
26322
- })(SpellcheckMode || {});
26323
- function getNewLinkFormat(app) {
26324
- return app.vault.getConfig("newLinkFormat");
26325
- }
26326
- function isSpellcheckEnabled(app) {
26327
- return Boolean(app.vault.getConfig("spellcheck"));
26328
- }
26329
- function isSpellcheckEnabledForMode(app, spellcheckMode) {
26330
- switch (spellcheckMode) {
26331
- case "AlwaysOn": {
26332
- return true;
26333
- }
26334
- case "FollowObsidianSetting": {
26335
- return isSpellcheckEnabled(app);
26336
- }
26337
- case "Off": {
26338
- return false;
26339
- }
26340
- default: {
26341
- assertNever(spellcheckMode);
26342
- }
26343
- }
26344
- }
26345
- function shouldUseWikilinks(app) {
26346
- return !app.vault.getConfig("useMarkdownLinks");
26347
- }
26348
-
26349
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/link.mjs
27011
+ init_obsidian_settings();
26350
27012
  (function() {
26351
27013
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
26352
27014
  symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
@@ -30339,7 +31001,7 @@ var NotebookNavigatorMenuEventRegistrarComponent = class extends LayoutReadyComp
30339
31001
  fileMenuEventHandlers = [];
30340
31002
  filesMenuEventHandlers = [];
30341
31003
  /**
30342
- * Creates a new Notebook Navigator menu event registrar.
31004
+ * Creates a new `Notebook Navigator` menu event registrar.
30343
31005
  *
30344
31006
  * @param params - The parameters for the component.
30345
31007
  */
@@ -30351,7 +31013,7 @@ var NotebookNavigatorMenuEventRegistrarComponent = class extends LayoutReadyComp
30351
31013
  /**
30352
31014
  * Accepts an editor-menu registration and does nothing with it.
30353
31015
  *
30354
- * Notebook Navigator extends the file tree, not the editor — an editor menu there is Obsidian's
31016
+ * `Notebook Navigator` extends the file tree, not the editor — an editor menu there is Obsidian's
30355
31017
  * own, which the handlers already reach through the workspace event. The registration is inert
30356
31018
  * rather than refused so a handler that declares one is not a load-time error.
30357
31019
  *
@@ -30396,7 +31058,7 @@ var NotebookNavigatorMenuEventRegistrarComponent = class extends LayoutReadyComp
30396
31058
  /**
30397
31059
  * Accepts a markdown-viewport-menu registration and does nothing with it.
30398
31060
  *
30399
- * Notebook Navigator extends the file tree, not the editor — the margin beside a note's text is
31061
+ * `Notebook Navigator` extends the file tree, not the editor — the margin beside a note's text is
30400
31062
  * Obsidian's own viewport, which the handlers already reach through the workspace event. The
30401
31063
  * registration is inert rather than refused so a handler that declares one is not a load-time error.
30402
31064
  *
@@ -30407,7 +31069,7 @@ var NotebookNavigatorMenuEventRegistrarComponent = class extends LayoutReadyComp
30407
31069
  return new CallbackDisposable({ callback: noop });
30408
31070
  }
30409
31071
  /**
30410
- * Binds to Notebook Navigator once every plugin has loaded.
31072
+ * Binds to `Notebook Navigator` once every plugin has loaded.
30411
31073
  *
30412
31074
  * Layout-ready rather than `onload`: plugin load order is not ours to choose, and Notebook
30413
31075
  * Navigator's API only exists once its own plugin is up. When it is not installed the component
@@ -30429,12 +31091,12 @@ var NotebookNavigatorMenuEventRegistrarComponent = class extends LayoutReadyComp
30429
31091
  /**
30430
31092
  * Adds the plugin's entry, unless the handlers had nothing to contribute.
30431
31093
  *
30432
- * The menu is populated TWICE, and both runs are needed: Notebook Navigator's `addItem` cannot be
31094
+ * The menu is populated TWICE, and both runs are needed: `Notebook Navigator`'s `addItem` cannot be
30433
31095
  * taken back once called, so the only way to keep an unrelated file's menu clean is to ask the
30434
31096
  * handlers first, against a menu nobody sees. The gates they answer with are metadata reads, so the
30435
31097
  * second run costs nothing and cannot disagree with the first.
30436
31098
  *
30437
- * @param context - The Notebook Navigator menu being built.
31099
+ * @param context - The `Notebook Navigator` menu being built.
30438
31100
  * @param populate - Runs the collected handlers against a menu.
30439
31101
  */
30440
31102
  contribute(context, populate) {
@@ -30451,7 +31113,7 @@ var NotebookNavigatorMenuEventRegistrarComponent = class extends LayoutReadyComp
30451
31113
  /**
30452
31114
  * Handles a file menu, single or multi-selection.
30453
31115
  *
30454
- * @param context - The Notebook Navigator menu being built.
31116
+ * @param context - The `Notebook Navigator` menu being built.
30455
31117
  */
30456
31118
  handleFileMenu(context) {
30457
31119
  const selectedFiles = [...context.selection.files];
@@ -30471,7 +31133,7 @@ var NotebookNavigatorMenuEventRegistrarComponent = class extends LayoutReadyComp
30471
31133
  * carries one — the event is typed {@link TAbstractFile}, and the folder handlers are the ones that
30472
31134
  * narrow it.
30473
31135
  *
30474
- * @param context - The Notebook Navigator menu being built.
31136
+ * @param context - The `Notebook Navigator` menu being built.
30475
31137
  */
30476
31138
  handleFolderMenu(context) {
30477
31139
  this.contribute(context, (menu) => {
@@ -30544,541 +31206,53 @@ init_component_ex();
30544
31206
  ensureBrowserProcess();
30545
31207
  })();
30546
31208
  })();
30547
- var PluginContextComponent = class extends ComponentEx {
30548
- /**
30549
- * The Obsidian app instance.
30550
- */
30551
- app;
30552
- /**
30553
- * The plugin ID used to initialize the plugin context and debug controller.
30554
- */
30555
- pluginId;
30556
- /**
30557
- * Creates a new plugin context component.
30558
- *
30559
- * @param params - The constructor parameters.
30560
- */
30561
- constructor(params) {
30562
- super();
30563
- this.app = params.app;
30564
- this.pluginId = params.pluginId;
30565
- }
30566
- /**
30567
- * Initializes the plugin context and debug controller.
30568
- */
30569
- onload() {
30570
- initPluginContext(this.pluginId);
30571
- this.register(() => {
30572
- Library.resetToDefault();
30573
- ObsidianLibrary.resetToDefault();
30574
- });
30575
- this.addChild(new AllWindowsEventComponent(this.app)).registerAllWindowsHandler((win) => {
30576
- initDebugController(win, this);
30577
- });
30578
- }
30579
- };
30580
-
30581
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/components/plugin-gate-component.mjs
30582
- var plugin_gate_component_exports = {};
30583
- __export(plugin_gate_component_exports, {
30584
- PluginConflictSeverity: () => PluginConflictSeverity,
30585
- PluginGateComponent: () => PluginGateComponent
30586
- });
30587
- init_async();
30588
- var import_compare_versions4 = __toESM(require_umd(), 1);
30589
- var import_obsidian114 = require("obsidian");
30590
- init_community_plugins();
30591
- init_css_class();
30592
-
30593
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/html-element.mjs
30594
- var html_element_exports = {};
30595
- __export(html_element_exports, {
30596
- appendCodeBlock: () => appendCodeBlock,
30597
- applySpellcheckMode: () => applySpellcheckMode,
30598
- asCodeBlock: () => asCodeBlock,
30599
- createFragmentWithCodeBlocks: () => createFragmentWithCodeBlocks
30600
- });
30601
- init_css_class();
30602
- (function() {
30603
- function ensureDisposeSymbols(symbolConstructor = Symbol) {
30604
- symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
30605
- symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
30606
- }
30607
- function ensureBrowserProcess() {
30608
- const browserProcess = {
30609
- browser: true,
30610
- cwd() {
30611
- return "/";
30612
- },
30613
- env: {},
30614
- platform: "android"
30615
- };
30616
- const existingProcess = globalThis.process;
30617
- if (!existingProcess) {
30618
- globalThis.process = browserProcess;
30619
- return;
30620
- }
30621
- if (existingProcess.versions?.node) {
30622
- return;
30623
- }
30624
- const existingProcessRecord = existingProcess;
30625
- for (const [key, value] of Object.entries(browserProcess)) {
30626
- existingProcessRecord[key] ??= value;
30627
- }
30628
- existingProcessRecord["browser"] = true;
30629
- }
30630
- (function initEsm() {
30631
- ensureDisposeSymbols();
30632
- ensureBrowserProcess();
30633
- })();
30634
- })();
30635
- var PRIVATE_USE_AREA_FIRST_CODE_POINT = 57344;
30636
- var CODE_BLOCK_DELIMITER = String.fromCodePoint(PRIVATE_USE_AREA_FIRST_CODE_POINT);
30637
- function appendCodeBlock(element2, code3) {
30638
- element2.createEl("strong", { cls: `${CssClass.MarkdownRendered} ${CssClass.Code}` }, (strong2) => {
30639
- strong2.createEl("code", { text: code3 });
30640
- });
30641
- }
30642
- function applySpellcheckMode(params) {
30643
- const {
30644
- app,
30645
- element: element2,
30646
- spellcheckMode = SpellcheckMode.Off
30647
- } = params;
30648
- element2.setAttribute("spellcheck", String(isSpellcheckEnabledForMode(app, spellcheckMode)));
30649
- }
30650
- function asCodeBlock(value) {
30651
- return `${CODE_BLOCK_DELIMITER}${value}${CODE_BLOCK_DELIMITER}`;
30652
- }
30653
- function createFragmentWithCodeBlocks(message) {
30654
- const fragment = createFragment();
30655
- let isCodeSegment = false;
30656
- for (const segment of message.split(CODE_BLOCK_DELIMITER)) {
30657
- if (segment !== "") {
30658
- if (isCodeSegment) {
30659
- appendCodeBlock(fragment, segment);
30660
- } else {
30661
- fragment.appendText(segment);
30662
- }
30663
- }
30664
- isCodeSegment = !isCodeSegment;
30665
- }
30666
- return fragment;
30667
- }
30668
-
30669
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/components/plugin-gate-component.mjs
30670
- init_i18n();
30671
-
30672
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/plugin-api.mjs
30673
- var plugin_api_exports = {};
30674
- __export(plugin_api_exports, {
30675
- PluginApiPayloadKind: () => PluginApiPayloadKind,
30676
- PluginApiRevokedError: () => PluginApiRevokedError,
30677
- PluginApiUnavailabilityReason: () => PluginApiUnavailabilityReason,
30678
- PluginApiUnavailableError: () => PluginApiUnavailableError,
30679
- PluginApiValidationError: () => PluginApiValidationError,
30680
- publishPluginApi: () => publishPluginApi,
30681
- watchPluginApi: () => watchPluginApi
30682
- });
30683
- init_array();
30684
- init_async();
30685
- init_async_events();
30686
- init_object_utils();
30687
- var import_compare_versions3 = __toESM(require_umd(), 1);
30688
- init_debug2();
30689
- init_obsidian_dev_utils_state();
30690
- (function() {
30691
- function ensureDisposeSymbols(symbolConstructor = Symbol) {
30692
- symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
30693
- symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
30694
- }
30695
- function ensureBrowserProcess() {
30696
- const browserProcess = {
30697
- browser: true,
30698
- cwd() {
30699
- return "/";
30700
- },
30701
- env: {},
30702
- platform: "android"
30703
- };
30704
- const existingProcess = globalThis.process;
30705
- if (!existingProcess) {
30706
- globalThis.process = browserProcess;
30707
- return;
30708
- }
30709
- if (existingProcess.versions?.node) {
30710
- return;
30711
- }
30712
- const existingProcessRecord = existingProcess;
30713
- for (const [key, value] of Object.entries(browserProcess)) {
30714
- existingProcessRecord[key] ??= value;
30715
- }
30716
- existingProcessRecord["browser"] = true;
30717
- }
30718
- (function initEsm() {
30719
- ensureDisposeSymbols();
30720
- ensureBrowserProcess();
30721
- })();
30722
- })();
30723
- var PLUGIN_API_DEBUGGER_NAMESPACE = "PluginApi";
30724
- var PLUGIN_API_REGISTRY_STATE_KEY = "pluginApiRegistry";
30725
- var DEFAULT_WHEN_AVAILABLE_TIMEOUT_IN_MILLISECONDS = 1e4;
30726
- var PluginApiPayloadKind = /* @__PURE__ */ ((PluginApiPayloadKind2) => {
30727
- PluginApiPayloadKind2["Input"] = "input";
30728
- PluginApiPayloadKind2["Output"] = "output";
30729
- return PluginApiPayloadKind2;
30730
- })(PluginApiPayloadKind || {});
30731
- var PluginApiUnavailabilityReason = /* @__PURE__ */ ((PluginApiUnavailabilityReason2) => {
30732
- PluginApiUnavailabilityReason2["NotEnabled"] = "notEnabled";
30733
- PluginApiUnavailabilityReason2["NotInstalled"] = "notInstalled";
30734
- PluginApiUnavailabilityReason2["NotPublished"] = "notPublished";
30735
- PluginApiUnavailabilityReason2["Revoked"] = "revoked";
30736
- PluginApiUnavailabilityReason2["ShapeMismatch"] = "shapeMismatch";
30737
- PluginApiUnavailabilityReason2["VersionMismatch"] = "versionMismatch";
30738
- return PluginApiUnavailabilityReason2;
30739
- })(PluginApiUnavailabilityReason || {});
30740
- var PluginApiWatchBase = class {
30741
- // A `protected` constructor is not assignable to `AbstractConstructor<object>`, which is what
30742
- // `mixinAsyncEvents` accepts, so this stays public even though only the subclass below calls it.
30743
- constructor(params) {
30744
- this.params = params;
30745
- }
30746
- params;
30747
- handle = null;
30748
- record = null;
30749
- /**
30750
- * Builds the error describing why the API is not available right now.
30751
- *
30752
- * @returns The classified error.
30753
- */
30754
- createUnavailableError() {
30755
- return new PluginApiUnavailableError({
30756
- pluginId: this.params.pluginId,
30757
- reason: resolveUnavailabilityReason(this.params)
30758
- });
30759
- }
30760
- };
30761
- var PluginApiRefImpl = class extends mixinAsyncEvents()(PluginApiWatchBase) {
30762
- get value() {
30763
- return castTo(this.handle);
30764
- }
30765
- constructor(params) {
30766
- super(params);
30767
- }
31209
+ var PluginContextComponent = class extends ComponentEx {
30768
31210
  /**
30769
- * Recomputes the current value from the registry, firing `change` only when it actually changed.
31211
+ * The Obsidian app instance.
30770
31212
  */
30771
- refresh() {
30772
- const record = selectRecord(this.params);
30773
- if (record === this.record) {
30774
- return;
30775
- }
30776
- this.record = record;
30777
- this.handle = record === null ? null : createRevocableHandle(record, this.params.contract);
30778
- this.trigger("change");
30779
- }
30780
- async whenAvailable(options) {
30781
- const currentValue = this.value;
30782
- if (currentValue !== null) {
30783
- return currentValue;
30784
- }
30785
- try {
30786
- return await runWithTimeout({
30787
- operationFunction: async (abortSignal) => await this.waitForValue(abortSignal),
30788
- operationName: `watchPluginApi("${this.params.pluginId}").whenAvailable`,
30789
- timeoutInMilliseconds: options?.timeoutInMilliseconds ?? DEFAULT_WHEN_AVAILABLE_TIMEOUT_IN_MILLISECONDS
30790
- });
30791
- } catch {
30792
- throw this.createUnavailableError();
30793
- }
30794
- }
30795
- async waitForValue(abortSignal) {
30796
- return await new Promise((resolve2, reject) => {
30797
- const eventRef = this.on("change", () => {
30798
- handleChange();
30799
- });
30800
- function cleanUp() {
30801
- eventRef.asyncEventSource.offref(eventRef);
30802
- abortSignal.removeEventListener("abort", handleAbort);
30803
- }
30804
- function handleAbort() {
30805
- cleanUp();
30806
- reject(abortSignal.reason);
30807
- }
30808
- const handleChange = () => {
30809
- const value = this.value;
30810
- if (value === null) {
30811
- return;
30812
- }
30813
- cleanUp();
30814
- resolve2(value);
30815
- };
30816
- abortSignal.addEventListener("abort", handleAbort);
30817
- handleChange();
30818
- });
30819
- }
30820
- };
30821
- var PluginApiUnavailableError = class extends Error {
31213
+ app;
30822
31214
  /**
30823
- * The `manifest.id` of the plugin whose API was requested.
31215
+ * The plugin ID used to initialize the plugin context and debug controller.
30824
31216
  */
30825
31217
  pluginId;
30826
31218
  /**
30827
- * Which of the five failures occurred.
30828
- */
30829
- reason;
30830
- /**
30831
- * Creates a {@link PluginApiUnavailableError}.
31219
+ * Creates a new plugin context component.
30832
31220
  *
30833
- * @param params - The parameters for the error.
31221
+ * @param params - The constructor parameters.
30834
31222
  */
30835
31223
  constructor(params) {
30836
- super(params.message ?? `The API of the plugin "${params.pluginId}" is unavailable: ${params.reason}.`);
30837
- this.name = "PluginApiUnavailableError";
31224
+ super();
31225
+ this.app = params.app;
30838
31226
  this.pluginId = params.pluginId;
30839
- this.reason = params.reason;
30840
31227
  }
30841
- };
30842
- var PluginApiRevokedError = class extends PluginApiUnavailableError {
30843
- /**
30844
- * Creates a {@link PluginApiRevokedError}.
30845
- *
30846
- * @param pluginId - The `manifest.id` of the plugin whose API was revoked.
30847
- */
30848
- constructor(pluginId) {
30849
- super({
30850
- message: `The API of the plugin "${pluginId}" has been revoked, because the plugin was unloaded.`,
30851
- pluginId,
30852
- reason: "revoked"
30853
- /* Revoked */
30854
- });
30855
- this.name = "PluginApiRevokedError";
30856
- }
30857
- };
30858
- var PluginApiValidationError = class extends Error {
30859
- /**
30860
- * The issues the schema reported.
30861
- */
30862
- issues;
30863
- /**
30864
- * The name of the method whose payload failed validation.
30865
- */
30866
- methodName;
30867
- /**
30868
- * The `manifest.id` of the providing plugin.
30869
- */
30870
- pluginId;
30871
31228
  /**
30872
- * Creates a {@link PluginApiValidationError}.
30873
- *
30874
- * @param params - The parameters for the error.
31229
+ * Initializes the plugin context and debug controller.
30875
31230
  */
30876
- constructor(params) {
30877
- super(
30878
- `The ${params.payloadKind} of "${params.pluginId}" API method "${params.methodName}" failed validation: ${formatIssues(params.issues)}`
30879
- );
30880
- this.name = "PluginApiValidationError";
30881
- this.issues = params.issues;
30882
- this.methodName = params.methodName;
30883
- this.pluginId = params.pluginId;
30884
- }
30885
- };
30886
- function publishPluginApi(params) {
30887
- const pluginId = params.plugin.manifest.id;
30888
- const registry = getRegistry();
30889
- const records = registry.records[pluginId] ?? [];
30890
- registry.records[pluginId] = records;
30891
- if (records.some((record2) => record2.apiVersion === params.apiVersion)) {
30892
- throw new Error(`The plugin "${pluginId}" has already published the API version "${params.apiVersion}".`);
30893
- }
30894
- const record = {
30895
- api: params.api,
30896
- apiVersion: params.apiVersion,
30897
- contract: params.contract ?? {},
30898
- isRevoked: false,
30899
- pluginId
30900
- };
30901
- records.push(record);
30902
- notifySubscribers();
30903
- (params.component ?? params.plugin).register(() => {
30904
- revokeRecord(record);
30905
- });
30906
- }
30907
- function watchPluginApi(params) {
30908
- const ref = new PluginApiRefImpl(params);
30909
- const unsubscribe = subscribe(() => {
30910
- ref.refresh();
30911
- });
30912
- params.component.register(unsubscribe);
30913
- ref.refresh();
30914
- return ref;
30915
- }
30916
- function checkIsPromiseLike(value) {
30917
- return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
30918
- }
30919
- function checkMatchesContractShape(record, consumerContract) {
30920
- const contract = consumerContract ?? record.contract;
30921
- return Object.keys(contract).every((methodName) => typeof getMember(record.api, methodName) === "function");
30922
- }
30923
- function createMethodWrapper(params) {
30924
- return function pluginApiMethod(...$arguments) {
30925
- const method = castTo(getMember(params.target, params.propertyKey));
30926
- const methodContract = params.methodContract;
30927
- if (methodContract === void 0 || !getPluginApiDebugger().enabled) {
30928
- return method.apply(params.target, $arguments);
30929
- }
30930
- if (methodContract.input) {
30931
- validatePayload({
30932
- methodName: params.methodName,
30933
- payloadKind: "input",
30934
- pluginId: params.pluginId,
30935
- schema: methodContract.input,
30936
- value: $arguments
30937
- });
30938
- }
30939
- const returnValue = method.apply(params.target, $arguments);
30940
- const outputSchema = methodContract.output;
30941
- if (!outputSchema) {
30942
- return returnValue;
30943
- }
30944
- if (checkIsPromiseLike(returnValue)) {
30945
- return returnValue.then((resolvedValue) => {
30946
- validatePayload({
30947
- methodName: params.methodName,
30948
- payloadKind: "output",
30949
- pluginId: params.pluginId,
30950
- schema: outputSchema,
30951
- value: resolvedValue
30952
- });
30953
- return resolvedValue;
30954
- });
30955
- }
30956
- validatePayload({
30957
- methodName: params.methodName,
30958
- payloadKind: "output",
30959
- pluginId: params.pluginId,
30960
- schema: outputSchema,
30961
- value: returnValue
30962
- });
30963
- return returnValue;
30964
- };
30965
- }
30966
- function createRevocableHandle(record, consumerContract) {
30967
- const contract = consumerContract ?? record.contract;
30968
- const methodCache = /* @__PURE__ */ new Map();
30969
- return new Proxy(record.api, {
30970
- get(target, propertyKey) {
30971
- if (record.isRevoked) {
30972
- throw new PluginApiRevokedError(record.pluginId);
30973
- }
30974
- const value = getMember(target, propertyKey);
30975
- if (typeof value !== "function") {
30976
- return value;
30977
- }
30978
- let method = methodCache.get(propertyKey);
30979
- if (method === void 0) {
30980
- method = createMethodWrapper({
30981
- methodContract: typeof propertyKey === "string" ? contract[propertyKey] : void 0,
30982
- methodName: String(propertyKey),
30983
- pluginId: record.pluginId,
30984
- propertyKey,
30985
- target
30986
- });
30987
- methodCache.set(propertyKey, method);
30988
- }
30989
- return method;
30990
- }
30991
- });
30992
- }
30993
- function formatIssues(issues) {
30994
- return issues.map((issue) => {
30995
- const path = issue.path?.map((segment) => String(typeof segment === "object" ? segment.key : segment)).join(".");
30996
- return path ? `${path}: ${issue.message}` : issue.message;
30997
- }).join("; ");
30998
- }
30999
- function getLiveRecords(pluginId) {
31000
- return (getRegistry().records[pluginId] ?? []).filter((record) => !record.isRevoked);
31001
- }
31002
- function getMember(api, methodName) {
31003
- return Reflect.get(api, methodName);
31004
- }
31005
- function getPluginApiDebugger() {
31006
- return getObsidianLibDebugger(PLUGIN_API_DEBUGGER_NAMESPACE);
31007
- }
31008
- function getRegistry() {
31009
- const wrapper = getObsidianDevUtilsState(PLUGIN_API_REGISTRY_STATE_KEY, {});
31010
- const registry = wrapper.value;
31011
- registry.records ??= {};
31012
- registry.subscribers ??= [];
31013
- return castTo(registry);
31014
- }
31015
- function notifySubscribers() {
31016
- for (const subscriber of snapshot(getRegistry().subscribers)) {
31017
- subscriber();
31018
- }
31019
- }
31020
- function resolveUnavailabilityReason(params) {
31021
- if (!Object.hasOwn(params.app.plugins.manifests, params.pluginId)) {
31022
- return "notInstalled";
31023
- }
31024
- if (!params.app.plugins.enabledPlugins.has(params.pluginId)) {
31025
- return "notEnabled";
31026
- }
31027
- const records = getLiveRecords(params.pluginId);
31028
- if (records.length === 0) {
31029
- return "notPublished";
31030
- }
31031
- return records.every((record) => !(0, import_compare_versions3.satisfies)(record.apiVersion, params.apiVersionRange)) ? "versionMismatch" : "shapeMismatch";
31032
- }
31033
- function revokeRecord(record) {
31034
- record.isRevoked = true;
31035
- const registry = getRegistry();
31036
- const records = registry.records[record.pluginId];
31037
- if (records) {
31038
- registry.records[record.pluginId] = records.filter((candidate) => candidate !== record);
31039
- }
31040
- notifySubscribers();
31041
- }
31042
- function selectRecord(params) {
31043
- const candidates2 = getLiveRecords(params.pluginId).filter((record) => (0, import_compare_versions3.satisfies)(record.apiVersion, params.apiVersionRange)).filter((record) => checkMatchesContractShape(record, params.contract)).sort((a2, b) => (0, import_compare_versions3.compareVersions)(b.apiVersion, a2.apiVersion));
31044
- return candidates2[0] ?? null;
31045
- }
31046
- function subscribe(subscriber) {
31047
- const registry = getRegistry();
31048
- registry.subscribers.push(subscriber);
31049
- return () => {
31050
- const index2 = registry.subscribers.indexOf(subscriber);
31051
- if (index2 !== -1) {
31052
- registry.subscribers.splice(index2, 1);
31053
- }
31054
- };
31055
- }
31056
- function validatePayload(params) {
31057
- const result = params.schema["~standard"].validate(params.value);
31058
- if (checkIsPromiseLike(result)) {
31059
- invokeAsyncSafely(async () => {
31060
- const asyncResult = await result;
31061
- if (asyncResult.issues) {
31062
- getPluginApiDebugger()(
31063
- 'Asynchronous validation of the %s of "%s" API method "%s" failed: %s',
31064
- params.payloadKind,
31065
- params.pluginId,
31066
- params.methodName,
31067
- formatIssues(asyncResult.issues)
31068
- );
31069
- }
31231
+ onload() {
31232
+ initPluginContext(this.pluginId);
31233
+ this.register(() => {
31234
+ Library.resetToDefault();
31235
+ ObsidianLibrary.resetToDefault();
31070
31236
  });
31071
- return;
31072
- }
31073
- if (result.issues) {
31074
- throw new PluginApiValidationError({
31075
- issues: result.issues,
31076
- methodName: params.methodName,
31077
- payloadKind: params.payloadKind,
31078
- pluginId: params.pluginId
31237
+ this.addChild(new AllWindowsEventComponent(this.app)).registerAllWindowsHandler((win) => {
31238
+ initDebugController(win, this);
31079
31239
  });
31080
31240
  }
31081
- }
31241
+ };
31242
+
31243
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/components/plugin-gate-component.mjs
31244
+ var plugin_gate_component_exports = {};
31245
+ __export(plugin_gate_component_exports, {
31246
+ PluginConflictSeverity: () => PluginConflictSeverity,
31247
+ PluginGateComponent: () => PluginGateComponent
31248
+ });
31249
+ init_async();
31250
+ var import_compare_versions4 = __toESM(require_umd(), 1);
31251
+ var import_obsidian114 = require("obsidian");
31252
+ init_community_plugins();
31253
+ init_css_class();
31254
+ init_html_element();
31255
+ init_i18n();
31082
31256
 
31083
31257
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/plugin-install-state.mjs
31084
31258
  var plugin_install_state_exports = {};
@@ -31089,6 +31263,7 @@ __export(plugin_install_state_exports, {
31089
31263
  installAndEnablePlugin: () => installAndEnablePlugin
31090
31264
  });
31091
31265
  init_community_plugins();
31266
+ init_html_element();
31092
31267
  init_i18n();
31093
31268
  (function() {
31094
31269
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
@@ -31582,7 +31757,7 @@ var PluginGateComponent = class extends ComponentEx {
31582
31757
  cls: [CssClass.LibraryName, CssClass.PluginDependencyBanner]
31583
31758
  });
31584
31759
  bannerEl.append(this.createBlockedMessage(dependency));
31585
- bannerEl.createDiv({ text: dependency.reason });
31760
+ appendTextOrFragmentClone(bannerEl.createDiv(), dependency.reason);
31586
31761
  const state = getInstalledPluginState({
31587
31762
  app: this.app,
31588
31763
  pluginId: dependency.pluginId
@@ -31626,7 +31801,7 @@ var PluginGateComponent = class extends ComponentEx {
31626
31801
  cls: [CssClass.LibraryName, CssClass.PluginConflictBanner]
31627
31802
  });
31628
31803
  bannerEl.append(messageFragment);
31629
- bannerEl.createDiv({ text: conflict.reason });
31804
+ appendTextOrFragmentClone(bannerEl.createDiv(), conflict.reason);
31630
31805
  new import_obsidian114.ButtonComponent(bannerEl).setButtonText(t2(($) => $.obsidianDevUtils.pluginConflict.disable, { conflictingPluginName: conflict.pluginName })).setCta().onClick(convertAsyncToSync(async () => {
31631
31806
  await disableCommunityPlugin({
31632
31807
  app: this.app,
@@ -33130,6 +33305,7 @@ __export(plugin_suggestion_component_exports, {
33130
33305
  init_async();
33131
33306
  var import_obsidian117 = require("obsidian");
33132
33307
  init_css_class();
33308
+ init_html_element();
33133
33309
  init_i18n();
33134
33310
  init_component_ex();
33135
33311
  (function() {
@@ -33264,7 +33440,7 @@ var PluginSuggestionComponent = class extends ComponentEx {
33264
33440
  const bannerEl = containerEl.createDiv({
33265
33441
  cls: [CssClass.LibraryName, CssClass.PluginSuggestionBanner]
33266
33442
  });
33267
- bannerEl.createDiv({ text: this.reason });
33443
+ appendTextOrFragmentClone(bannerEl.createDiv(), this.reason);
33268
33444
  new import_obsidian117.ButtonComponent(bannerEl).setButtonText(this.getActionButtonText(state)).setCta().onClick(convertAsyncToSync(async () => {
33269
33445
  await this.installAndEnableSuggestedPlugin();
33270
33446
  }));
@@ -33280,7 +33456,7 @@ var PluginSuggestionComponent = class extends ComponentEx {
33280
33456
  return;
33281
33457
  }
33282
33458
  const fragment = createFragment((fragmentEl) => {
33283
- fragmentEl.createDiv({ text: this.reason });
33459
+ appendTextOrFragmentClone(fragmentEl.createDiv(), this.reason);
33284
33460
  const buttonsEl = fragmentEl.createDiv();
33285
33461
  new import_obsidian117.ButtonComponent(buttonsEl).setButtonText(this.getActionButtonText(state)).setCta().onClick(convertAsyncToSync(async () => {
33286
33462
  await this.installAndEnableSuggestedPlugin();
@@ -33784,6 +33960,7 @@ __export(release_notes_component_exports, {
33784
33960
  ReleaseNotesComponent: () => ReleaseNotesComponent
33785
33961
  });
33786
33962
  var import_compare_versions5 = __toESM(require_umd(), 1);
33963
+ init_html_element();
33787
33964
  init_i18n();
33788
33965
 
33789
33966
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/modals/alert.mjs
@@ -33970,7 +34147,7 @@ var ReleaseNotesComponent = class extends ComponentEx {
33970
34147
  await alert({
33971
34148
  app: this.app,
33972
34149
  message,
33973
- title: t2(($) => $.obsidianDevUtils.releaseNotes.title, { pluginName: this.pluginName })
34150
+ title: createFragmentWithCodeBlocks(t2(($) => $.obsidianDevUtils.releaseNotes.title, { pluginName: asCodeBlock(this.pluginName) }))
33974
34151
  });
33975
34152
  }
33976
34153
  };
@@ -34321,6 +34498,7 @@ function readOnlyExtension() {
34321
34498
  }
34322
34499
 
34323
34500
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/resource-lock.mjs
34501
+ init_html_element();
34324
34502
  init_i18n();
34325
34503
 
34326
34504
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/modals/confirm.mjs
@@ -36721,7 +36899,64 @@ __export(settings_migration_component_exports, {
36721
36899
  SettingsMigrationComponent: () => SettingsMigrationComponent
36722
36900
  });
36723
36901
  init_async();
36724
- init_object_utils();
36902
+
36903
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/settings-migration-api.mjs
36904
+ var settings_migration_api_exports = {};
36905
+ __export(settings_migration_api_exports, {
36906
+ getSettingsMigrationApiContract: () => getSettingsMigrationApiContract
36907
+ });
36908
+ (function() {
36909
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
36910
+ symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
36911
+ symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
36912
+ }
36913
+ function ensureBrowserProcess() {
36914
+ const browserProcess = {
36915
+ browser: true,
36916
+ cwd() {
36917
+ return "/";
36918
+ },
36919
+ env: {},
36920
+ platform: "android"
36921
+ };
36922
+ const existingProcess = globalThis.process;
36923
+ if (!existingProcess) {
36924
+ globalThis.process = browserProcess;
36925
+ return;
36926
+ }
36927
+ if (existingProcess.versions?.node) {
36928
+ return;
36929
+ }
36930
+ const existingProcessRecord = existingProcess;
36931
+ for (const [key, value] of Object.entries(browserProcess)) {
36932
+ existingProcessRecord[key] ??= value;
36933
+ }
36934
+ existingProcessRecord["browser"] = true;
36935
+ }
36936
+ (function initEsm() {
36937
+ ensureDisposeSymbols();
36938
+ ensureBrowserProcess();
36939
+ })();
36940
+ })();
36941
+ function getSettingsMigrationApiContract() {
36942
+ return {
36943
+ migrateSettings: {
36944
+ input: createArgumentsSchema([{
36945
+ expected: "an object with an object proposedSettings and a string sourcePluginId",
36946
+ typeGuard: (value) => isObject(value) && isObject(Reflect.get(value, "proposedSettings")) && typeof Reflect.get(value, "sourcePluginId") === "string"
36947
+ }]),
36948
+ output: createTypeGuardSchema({
36949
+ expected: "an object with a boolean isApplied",
36950
+ typeGuard: (value) => isObject(value) && typeof Reflect.get(value, "isApplied") === "boolean"
36951
+ })
36952
+ }
36953
+ };
36954
+ }
36955
+ function isObject(value) {
36956
+ return typeof value === "object" && value !== null;
36957
+ }
36958
+
36959
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/components/settings-migration-component.mjs
36725
36960
  init_component_ex();
36726
36961
  (function() {
36727
36962
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
@@ -36775,7 +37010,7 @@ var SettingsMigrationComponent = class extends ComponentEx {
36775
37010
  super();
36776
37011
  this.apiVersionRange = params.apiVersionRange;
36777
37012
  this.app = params.app;
36778
- this.contract = params.contract;
37013
+ this.contract = params.contract ?? getSettingsMigrationApiContract();
36779
37014
  this.getProposedSettings = params.getProposedSettings;
36780
37015
  this.pluginSettingsComponent = params.pluginSettingsComponent;
36781
37016
  this.providerPluginId = params.providerPluginId;
@@ -36786,13 +37021,13 @@ var SettingsMigrationComponent = class extends ComponentEx {
36786
37021
  * Loads the component, wiring both edges that can make an offer possible.
36787
37022
  */
36788
37023
  onload() {
36789
- const ref = watchPluginApi(normalizeOptionalProperties({
37024
+ const ref = watchPluginApi({
36790
37025
  apiVersionRange: this.apiVersionRange,
36791
37026
  app: this.app,
36792
37027
  component: this,
36793
37028
  contract: this.contract,
36794
37029
  pluginId: this.providerPluginId
36795
- }));
37030
+ });
36796
37031
  registerAsyncEvent(
36797
37032
  this,
36798
37033
  ref.on("change", () => {
@@ -37372,6 +37607,7 @@ init_path();
37372
37607
  init_string();
37373
37608
  var import_obsidian124 = require("obsidian");
37374
37609
  init_community_plugins();
37610
+ init_html_element();
37375
37611
  (function() {
37376
37612
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
37377
37613
  symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
@@ -37452,7 +37688,7 @@ async function bootstrapDemoVault(params) {
37452
37688
  function buildSandboxNoticeFragment(pluginName) {
37453
37689
  return createFragment((fragment) => {
37454
37690
  fragment.appendText("This is a demo vault for ");
37455
- fragment.createEl("b", { text: pluginName });
37691
+ appendCodeBlock(fragment, pluginName);
37456
37692
  fragment.appendText(".");
37457
37693
  fragment.createEl("br");
37458
37694
  fragment.appendText("It is a temporary sandbox, cleaned up automatically about a day after you last use it.");
@@ -44822,6 +45058,7 @@ var PluginHoverLinkSourceRegistrar = class {
44822
45058
  };
44823
45059
 
44824
45060
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/__merged.mjs
45061
+ init_html_element();
44825
45062
  init_i18n();
44826
45063
  init_en();
44827
45064
  init_translations_map();
@@ -46626,7 +46863,9 @@ init_function();
46626
46863
  init_object_utils();
46627
46864
  var import_obsidian136 = require("obsidian");
46628
46865
  init_css_class();
46866
+ init_html_element();
46629
46867
  init_i18n();
46868
+ init_obsidian_settings();
46630
46869
  init_modal();
46631
46870
  (function() {
46632
46871
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
@@ -46774,6 +47013,8 @@ __export(select_item_exports, {
46774
47013
  });
46775
47014
  var import_obsidian137 = require("obsidian");
46776
47015
  init_css_class();
47016
+ init_html_element();
47017
+ init_obsidian_settings();
46777
47018
  init_plugin_context();
46778
47019
  init_modal();
46779
47020
  (function() {
@@ -47096,6 +47337,9 @@ var PluginObsidianProtocolHandlerRegistrar = class {
47096
47337
  }
47097
47338
  };
47098
47339
 
47340
+ // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/__merged.mjs
47341
+ init_obsidian_settings();
47342
+
47099
47343
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/path-settings.mjs
47100
47344
  var path_settings_exports = {};
47101
47345
  __export(path_settings_exports, {
@@ -51391,7 +51635,7 @@ var PluginBase = class extends mixinAsyncEvents()(import_obsidian158.Plugin) {
51391
51635
  return defaultTranslationsMap;
51392
51636
  }
51393
51637
  /**
51394
- * Provides the icon shown on the plugin's parent entry in Notebook Navigator's context menus.
51638
+ * Provides the icon shown on the plugin's parent entry in `Notebook Navigator`'s context menus.
51395
51639
  *
51396
51640
  * Override in subclass to brand that entry; the default leaves it without an icon. The entry is
51397
51641
  * titled with the plugin name and is added automatically — see
@@ -52158,11 +52402,11 @@ async function parseTemplate(params) {
52158
52402
  renderTargetFiles.push(targetFile);
52159
52403
  try {
52160
52404
  return await api.read_and_parse_template({
52161
- // eslint-disable-next-line camelcase -- Templater API.
52405
+ // eslint-disable-next-line camelcase -- `Templater` API.
52162
52406
  run_mode: 4,
52163
- // eslint-disable-next-line camelcase -- Templater API.
52407
+ // eslint-disable-next-line camelcase -- `Templater` API.
52164
52408
  target_file: targetFile,
52165
- // eslint-disable-next-line camelcase -- Templater API.
52409
+ // eslint-disable-next-line camelcase -- `Templater` API.
52166
52410
  template_file: templateFile
52167
52411
  });
52168
52412
  } finally {
@@ -53495,6 +53739,7 @@ init_demo_vault_naming();
53495
53739
  init_desktop_demo_vault_opener();
53496
53740
  init_desktop_trusted_input();
53497
53741
  init_generated_during_build();
53742
+ init_html_element();
53498
53743
 
53499
53744
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/i18n/index.mjs
53500
53745
  var i18n_exports2 = {};
@@ -53789,12 +54034,14 @@ init_select_option();
53789
54034
 
53790
54035
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/index.mjs
53791
54036
  init_obsidian_dev_utils_state();
54037
+ init_obsidian_settings();
53792
54038
 
53793
54039
  // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/index.mjs
53794
54040
  var plugin_exports2 = {};
53795
54041
  __export(plugin_exports2, {
53796
54042
  plugin: () => plugin_exports,
53797
54043
  "plugin-api": () => plugin_api_exports,
54044
+ "plugin-api-schema": () => plugin_api_schema_exports,
53798
54045
  "plugin-context": () => plugin_context_exports,
53799
54046
  "plugin-event-source": () => plugin_event_source_exports,
53800
54047
  "plugin-install-state": () => plugin_install_state_exports,
@@ -53803,44 +54050,6 @@ __export(plugin_exports2, {
53803
54050
  "settings-migration-api": () => settings_migration_api_exports
53804
54051
  });
53805
54052
  init_plugin_context();
53806
-
53807
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/settings-migration-api.mjs
53808
- var settings_migration_api_exports = {};
53809
- (function() {
53810
- function ensureDisposeSymbols(symbolConstructor = Symbol) {
53811
- symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
53812
- symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
53813
- }
53814
- function ensureBrowserProcess() {
53815
- const browserProcess = {
53816
- browser: true,
53817
- cwd() {
53818
- return "/";
53819
- },
53820
- env: {},
53821
- platform: "android"
53822
- };
53823
- const existingProcess = globalThis.process;
53824
- if (!existingProcess) {
53825
- globalThis.process = browserProcess;
53826
- return;
53827
- }
53828
- if (existingProcess.versions?.node) {
53829
- return;
53830
- }
53831
- const existingProcessRecord = existingProcess;
53832
- for (const [key, value] of Object.entries(browserProcess)) {
53833
- existingProcessRecord[key] ??= value;
53834
- }
53835
- existingProcessRecord["browser"] = true;
53836
- }
53837
- (function initEsm() {
53838
- ensureDisposeSymbols();
53839
- ensureBrowserProcess();
53840
- })();
53841
- })();
53842
-
53843
- // node_modules/@mnaoumov/obsidian-lib/dist/lib/esm/plugin/index.mjs
53844
54053
  (function() {
53845
54054
  function ensureDisposeSymbols(symbolConstructor = Symbol) {
53846
54055
  symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");