Files
cours/.obsidian/plugins/metaedit/main.js
T
2026-07-05 20:01:25 +02:00

11822 lines
408 KiB
JavaScript

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __typeError = (msg) => {
throw TypeError(msg);
};
var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key2 of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key2) && key2 !== except)
__defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => MetaEdit
});
module.exports = __toCommonJS(main_exports);
var import_obsidian25 = require("obsidian");
// src/Settings/metaEditSettingsTab.ts
var import_obsidian3 = require("obsidian");
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/version.js
var PUBLIC_VERSION = "5";
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/disclose-version.js
var _a;
if (typeof window !== "undefined") {
((_a = window.__svelte ?? (window.__svelte = {})).v ?? (_a.v = /* @__PURE__ */ new Set())).add(PUBLIC_VERSION);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/constants.js
var EACH_ITEM_REACTIVE = 1;
var EACH_INDEX_REACTIVE = 1 << 1;
var EACH_IS_CONTROLLED = 1 << 2;
var EACH_IS_ANIMATED = 1 << 3;
var EACH_ITEM_IMMUTABLE = 1 << 4;
var PROPS_IS_IMMUTABLE = 1;
var PROPS_IS_RUNES = 1 << 1;
var PROPS_IS_UPDATED = 1 << 2;
var PROPS_IS_BINDABLE = 1 << 3;
var PROPS_IS_LAZY_INITIAL = 1 << 4;
var TRANSITION_OUT = 1 << 1;
var TRANSITION_GLOBAL = 1 << 2;
var TEMPLATE_FRAGMENT = 1;
var TEMPLATE_USE_IMPORT_NODE = 1 << 1;
var TEMPLATE_USE_SVG = 1 << 2;
var TEMPLATE_USE_MATHML = 1 << 3;
var HYDRATION_START = "[";
var HYDRATION_START_ELSE = "[!";
var HYDRATION_START_FAILED = "[?";
var HYDRATION_END = "]";
var HYDRATION_ERROR = {};
var ELEMENT_PRESERVE_ATTRIBUTE_CASE = 1 << 1;
var ELEMENT_IS_INPUT = 1 << 2;
var UNINITIALIZED = /* @__PURE__ */ Symbol("uninitialized");
var FILENAME = /* @__PURE__ */ Symbol("filename");
var NAMESPACE_HTML = "http://www.w3.org/1999/xhtml";
// node_modules/.pnpm/esm-env@1.2.2/node_modules/esm-env/dev-fallback.js
var node_env = globalThis.process?.env?.NODE_ENV;
var dev_fallback_default = node_env && !node_env.toLowerCase().startsWith("prod");
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/shared/utils.js
var is_array = Array.isArray;
var index_of = Array.prototype.indexOf;
var includes = Array.prototype.includes;
var array_from = Array.from;
var object_keys = Object.keys;
var define_property = Object.defineProperty;
var get_descriptor = Object.getOwnPropertyDescriptor;
var get_descriptors = Object.getOwnPropertyDescriptors;
var object_prototype = Object.prototype;
var array_prototype = Array.prototype;
var get_prototype_of = Object.getPrototypeOf;
var is_extensible = Object.isExtensible;
var noop = () => {
};
function run_all(arr) {
for (var i = 0; i < arr.length; i++) {
arr[i]();
}
}
function deferred() {
var resolve;
var reject;
var promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/constants.js
var DERIVED = 1 << 1;
var EFFECT = 1 << 2;
var RENDER_EFFECT = 1 << 3;
var MANAGED_EFFECT = 1 << 24;
var BLOCK_EFFECT = 1 << 4;
var BRANCH_EFFECT = 1 << 5;
var ROOT_EFFECT = 1 << 6;
var BOUNDARY_EFFECT = 1 << 7;
var CONNECTED = 1 << 9;
var CLEAN = 1 << 10;
var DIRTY = 1 << 11;
var MAYBE_DIRTY = 1 << 12;
var INERT = 1 << 13;
var DESTROYED = 1 << 14;
var REACTION_RAN = 1 << 15;
var DESTROYING = 1 << 25;
var EFFECT_TRANSPARENT = 1 << 16;
var EAGER_EFFECT = 1 << 17;
var HEAD_EFFECT = 1 << 18;
var EFFECT_PRESERVED = 1 << 19;
var USER_EFFECT = 1 << 20;
var EFFECT_OFFSCREEN = 1 << 25;
var WAS_MARKED = 1 << 16;
var REACTION_IS_UPDATING = 1 << 21;
var ASYNC = 1 << 22;
var ERROR_VALUE = 1 << 23;
var STATE_SYMBOL = /* @__PURE__ */ Symbol("$state");
var LEGACY_PROPS = /* @__PURE__ */ Symbol("legacy props");
var LOADING_ATTR_SYMBOL = /* @__PURE__ */ Symbol("");
var PROXY_PATH_SYMBOL = /* @__PURE__ */ Symbol("proxy path");
var ATTRIBUTES_CACHE = /* @__PURE__ */ Symbol("attributes");
var CLASS_CACHE = /* @__PURE__ */ Symbol("class");
var STYLE_CACHE = /* @__PURE__ */ Symbol("style");
var TEXT_CACHE = /* @__PURE__ */ Symbol("text");
var FORM_RESET_HANDLER = /* @__PURE__ */ Symbol("form reset");
var HMR_ANCHOR = /* @__PURE__ */ Symbol("hmr anchor");
var STALE_REACTION = new class StaleReactionError extends Error {
constructor() {
super(...arguments);
__publicField(this, "name", "StaleReactionError");
__publicField(this, "message", "The reaction that called `getAbortSignal()` was re-run or destroyed");
}
}();
var IS_XHTML = (
// We gotta write it like this because after downleveling the pure comment may end up in the wrong location
!!globalThis.document?.contentType && /* @__PURE__ */ globalThis.document.contentType.includes("xml")
);
var TEXT_NODE = 3;
var COMMENT_NODE = 8;
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/shared/errors.js
function invariant_violation(message) {
if (dev_fallback_default) {
const error = new Error(`invariant_violation
An invariant violation occurred, meaning Svelte's internal assumptions were flawed. This is a bug in Svelte, not your app \u2014 please open an issue at https://github.com/sveltejs/svelte, citing the following message: "${message}"
https://svelte.dev/e/invariant_violation`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/invariant_violation`);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/errors.js
function async_derived_orphan() {
if (dev_fallback_default) {
const error = new Error(`async_derived_orphan
Cannot create a \`$derived(...)\` with an \`await\` expression outside of an effect tree
https://svelte.dev/e/async_derived_orphan`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/async_derived_orphan`);
}
}
function bind_invalid_checkbox_value() {
if (dev_fallback_default) {
const error = new Error(`bind_invalid_checkbox_value
Using \`bind:value\` together with a checkbox input is not allowed. Use \`bind:checked\` instead
https://svelte.dev/e/bind_invalid_checkbox_value`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/bind_invalid_checkbox_value`);
}
}
function derived_references_self() {
if (dev_fallback_default) {
const error = new Error(`derived_references_self
A derived value cannot reference itself recursively
https://svelte.dev/e/derived_references_self`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/derived_references_self`);
}
}
function each_key_duplicate(a, b, value) {
if (dev_fallback_default) {
const error = new Error(`each_key_duplicate
${value ? `Keyed each block has duplicate key \`${value}\` at indexes ${a} and ${b}` : `Keyed each block has duplicate key at indexes ${a} and ${b}`}
https://svelte.dev/e/each_key_duplicate`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/each_key_duplicate`);
}
}
function each_key_volatile(index2, a, b) {
if (dev_fallback_default) {
const error = new Error(`each_key_volatile
Keyed each block has key that is not idempotent \u2014 the key for item at index ${index2} was \`${a}\` but is now \`${b}\`. Keys must be the same each time for a given item
https://svelte.dev/e/each_key_volatile`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/each_key_volatile`);
}
}
function effect_in_teardown(rune) {
if (dev_fallback_default) {
const error = new Error(`effect_in_teardown
\`${rune}\` cannot be used inside an effect cleanup function
https://svelte.dev/e/effect_in_teardown`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/effect_in_teardown`);
}
}
function effect_in_unowned_derived() {
if (dev_fallback_default) {
const error = new Error(`effect_in_unowned_derived
Effect cannot be created inside a \`$derived\` value that was not itself created inside an effect
https://svelte.dev/e/effect_in_unowned_derived`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/effect_in_unowned_derived`);
}
}
function effect_orphan(rune) {
if (dev_fallback_default) {
const error = new Error(`effect_orphan
\`${rune}\` can only be used inside an effect (e.g. during component initialisation)
https://svelte.dev/e/effect_orphan`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/effect_orphan`);
}
}
function effect_update_depth_exceeded() {
if (dev_fallback_default) {
const error = new Error(`effect_update_depth_exceeded
Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state
https://svelte.dev/e/effect_update_depth_exceeded`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`);
}
}
function hydration_failed() {
if (dev_fallback_default) {
const error = new Error(`hydration_failed
Failed to hydrate the application
https://svelte.dev/e/hydration_failed`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/hydration_failed`);
}
}
function props_invalid_value(key2) {
if (dev_fallback_default) {
const error = new Error(`props_invalid_value
Cannot do \`bind:${key2}={undefined}\` when \`${key2}\` has a fallback value
https://svelte.dev/e/props_invalid_value`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/props_invalid_value`);
}
}
function rune_outside_svelte(rune) {
if (dev_fallback_default) {
const error = new Error(`rune_outside_svelte
The \`${rune}\` rune is only available inside \`.svelte\` and \`.svelte.js/ts\` files
https://svelte.dev/e/rune_outside_svelte`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/rune_outside_svelte`);
}
}
function state_descriptors_fixed() {
if (dev_fallback_default) {
const error = new Error(`state_descriptors_fixed
Property descriptors defined on \`$state\` objects must contain \`value\` and always be \`enumerable\`, \`configurable\` and \`writable\`.
https://svelte.dev/e/state_descriptors_fixed`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/state_descriptors_fixed`);
}
}
function state_prototype_fixed() {
if (dev_fallback_default) {
const error = new Error(`state_prototype_fixed
Cannot set prototype of \`$state\` object
https://svelte.dev/e/state_prototype_fixed`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/state_prototype_fixed`);
}
}
function state_unsafe_mutation() {
if (dev_fallback_default) {
const error = new Error(`state_unsafe_mutation
Updating state inside \`$derived(...)\`, \`$inspect(...)\` or a template expression is forbidden. If the value should not be reactive, declare it without \`$state\`
https://svelte.dev/e/state_unsafe_mutation`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/state_unsafe_mutation`);
}
}
function svelte_boundary_reset_onerror() {
if (dev_fallback_default) {
const error = new Error(`svelte_boundary_reset_onerror
A \`<svelte:boundary>\` \`reset\` function cannot be called while an error is still being handled
https://svelte.dev/e/svelte_boundary_reset_onerror`);
error.name = "Svelte error";
throw error;
} else {
throw new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/warnings.js
var bold = "font-weight: bold";
var normal = "font-weight: normal";
function await_reactivity_loss(name) {
if (dev_fallback_default) {
console.warn(`%c[svelte] await_reactivity_loss
%cDetected reactivity loss when reading \`${name}\`. This happens when state is read in an async function after an earlier \`await\`
https://svelte.dev/e/await_reactivity_loss`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/await_reactivity_loss`);
}
}
function await_waterfall(name, location) {
if (dev_fallback_default) {
console.warn(`%c[svelte] await_waterfall
%cAn async derived, \`${name}\` (${location}) was not read immediately after it resolved. This often indicates an unnecessary waterfall, which can slow down your app
https://svelte.dev/e/await_waterfall`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/await_waterfall`);
}
}
function derived_inert() {
if (dev_fallback_default) {
console.warn(`%c[svelte] derived_inert
%cReading a derived belonging to a now-destroyed effect may result in stale values
https://svelte.dev/e/derived_inert`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/derived_inert`);
}
}
function hydration_attribute_changed(attribute, html2, value) {
if (dev_fallback_default) {
console.warn(`%c[svelte] hydration_attribute_changed
%cThe \`${attribute}\` attribute on \`${html2}\` changed its value between server and client renders. The client value, \`${value}\`, will be ignored in favour of the server value
https://svelte.dev/e/hydration_attribute_changed`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/hydration_attribute_changed`);
}
}
function hydration_mismatch(location) {
if (dev_fallback_default) {
console.warn(
`%c[svelte] hydration_mismatch
%c${location ? `Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near ${location}` : "Hydration failed because the initial UI does not match what was rendered on the server"}
https://svelte.dev/e/hydration_mismatch`,
bold,
normal
);
} else {
console.warn(`https://svelte.dev/e/hydration_mismatch`);
}
}
function lifecycle_double_unmount() {
if (dev_fallback_default) {
console.warn(`%c[svelte] lifecycle_double_unmount
%cTried to unmount a component that was not mounted
https://svelte.dev/e/lifecycle_double_unmount`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/lifecycle_double_unmount`);
}
}
function select_multiple_invalid_value() {
if (dev_fallback_default) {
console.warn(`%c[svelte] select_multiple_invalid_value
%cThe \`value\` property of a \`<select multiple>\` element should be an array, but it received a non-array value. The selection will be kept as is.
https://svelte.dev/e/select_multiple_invalid_value`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/select_multiple_invalid_value`);
}
}
function state_proxy_equality_mismatch(operator) {
if (dev_fallback_default) {
console.warn(`%c[svelte] state_proxy_equality_mismatch
%cReactive \`$state(...)\` proxies and the values they proxy have different identities. Because of this, comparisons with \`${operator}\` will produce unexpected results
https://svelte.dev/e/state_proxy_equality_mismatch`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/state_proxy_equality_mismatch`);
}
}
function state_proxy_unmount() {
if (dev_fallback_default) {
console.warn(`%c[svelte] state_proxy_unmount
%cTried to unmount a state proxy, rather than a component
https://svelte.dev/e/state_proxy_unmount`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/state_proxy_unmount`);
}
}
function svelte_boundary_reset_noop() {
if (dev_fallback_default) {
console.warn(`%c[svelte] svelte_boundary_reset_noop
%cA \`<svelte:boundary>\` \`reset\` function only resets the boundary the first time it is called
https://svelte.dev/e/svelte_boundary_reset_noop`, bold, normal);
} else {
console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/hydration.js
var hydrating = false;
function set_hydrating(value) {
hydrating = value;
}
var hydrate_node;
function set_hydrate_node(node) {
if (node === null) {
hydration_mismatch();
throw HYDRATION_ERROR;
}
return hydrate_node = node;
}
function hydrate_next() {
return set_hydrate_node(get_next_sibling(hydrate_node));
}
function reset(node) {
if (!hydrating) return;
if (get_next_sibling(hydrate_node) !== null) {
hydration_mismatch();
throw HYDRATION_ERROR;
}
hydrate_node = node;
}
function next(count = 1) {
if (hydrating) {
var i = count;
var node = hydrate_node;
while (i--) {
node = /** @type {TemplateNode} */
get_next_sibling(node);
}
hydrate_node = node;
}
}
function skip_nodes(remove = true) {
var depth = 0;
var node = hydrate_node;
while (true) {
if (node.nodeType === COMMENT_NODE) {
var data = (
/** @type {Comment} */
node.data
);
if (data === HYDRATION_END) {
if (depth === 0) return node;
depth -= 1;
} else if (data === HYDRATION_START || data === HYDRATION_START_ELSE || // "[1", "[2", etc. for if blocks
data[0] === "[" && !isNaN(Number(data.slice(1)))) {
depth += 1;
}
}
var next2 = (
/** @type {TemplateNode} */
get_next_sibling(node)
);
if (remove) node.remove();
node = next2;
}
}
function read_hydration_instruction(node) {
if (!node || node.nodeType !== COMMENT_NODE) {
hydration_mismatch();
throw HYDRATION_ERROR;
}
return (
/** @type {Comment} */
node.data
);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/equality.js
function equals(value) {
return value === this.v;
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || a !== null && typeof a === "object" || typeof a === "function";
}
function safe_equals(value) {
return !safe_not_equal(value, this.v);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/flags/index.js
var async_mode_flag = false;
var legacy_mode_flag = false;
var tracing_mode_flag = false;
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/shared/warnings.js
var bold2 = "font-weight: bold";
var normal2 = "font-weight: normal";
function state_snapshot_uncloneable(properties) {
if (dev_fallback_default) {
console.warn(
`%c[svelte] state_snapshot_uncloneable
%c${properties ? `The following properties cannot be cloned with \`$state.snapshot\` \u2014 the return value contains the originals:
${properties}` : "Value cannot be cloned with `$state.snapshot` \u2014 the original value was returned"}
https://svelte.dev/e/state_snapshot_uncloneable`,
bold2,
normal2
);
} else {
console.warn(`https://svelte.dev/e/state_snapshot_uncloneable`);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/shared/clone.js
var empty = [];
function snapshot(value, skip_warning = false, no_tojson = false) {
if (dev_fallback_default && !skip_warning) {
const paths = [];
const copy = clone(value, /* @__PURE__ */ new Map(), "", paths, null, no_tojson);
if (paths.length === 1 && paths[0] === "") {
state_snapshot_uncloneable();
} else if (paths.length > 0) {
const slice = paths.length > 10 ? paths.slice(0, 7) : paths.slice(0, 10);
const excess = paths.length - slice.length;
let uncloned = slice.map((path) => `- <value>${path}`).join("\n");
if (excess > 0) uncloned += `
- ...and ${excess} more`;
state_snapshot_uncloneable(uncloned);
}
return copy;
}
return clone(value, /* @__PURE__ */ new Map(), "", empty, null, no_tojson);
}
function clone(value, cloned, path, paths, original = null, no_tojson = false) {
if (typeof value === "object" && value !== null) {
var unwrapped = cloned.get(value);
if (unwrapped !== void 0) return unwrapped;
if (value instanceof Map) return (
/** @type {Snapshot<T>} */
new Map(value)
);
if (value instanceof Set) return (
/** @type {Snapshot<T>} */
new Set(value)
);
if (is_array(value)) {
var copy = (
/** @type {Snapshot<any>} */
Array(value.length)
);
cloned.set(value, copy);
if (original !== null) {
cloned.set(original, copy);
}
for (var i = 0; i < value.length; i += 1) {
var element2 = value[i];
if (i in value) {
copy[i] = clone(element2, cloned, dev_fallback_default ? `${path}[${i}]` : path, paths, null, no_tojson);
}
}
return copy;
}
if (get_prototype_of(value) === object_prototype) {
copy = {};
cloned.set(value, copy);
if (original !== null) {
cloned.set(original, copy);
}
for (var key2 of Object.keys(value)) {
copy[key2] = clone(
// @ts-expect-error
value[key2],
cloned,
dev_fallback_default ? `${path}.${key2}` : path,
paths,
null,
no_tojson
);
}
return copy;
}
if (value instanceof Date) {
return (
/** @type {Snapshot<T>} */
structuredClone(value)
);
}
if (typeof /** @type {T & { toJSON?: any } } */
value.toJSON === "function" && !no_tojson) {
return clone(
/** @type {T & { toJSON(): any } } */
value.toJSON(),
cloned,
dev_fallback_default ? `${path}.toJSON()` : path,
paths,
// Associate the instance with the toJSON clone
value
);
}
}
if (value instanceof EventTarget) {
return (
/** @type {Snapshot<T>} */
value
);
}
try {
return (
/** @type {Snapshot<T>} */
structuredClone(value)
);
} catch (e) {
if (dev_fallback_default) {
paths.push(path);
}
return (
/** @type {Snapshot<T>} */
value
);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dev/tracing.js
var tracing_expressions = null;
function tag(source2, label) {
source2.label = label;
tag_proxy(source2.v, label);
return source2;
}
function tag_proxy(value, label) {
value?.[PROXY_PATH_SYMBOL]?.(label);
return value;
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/shared/dev.js
function get_error(label) {
const error = new Error();
const stack2 = get_stack();
if (stack2.length === 0) {
return null;
}
stack2.unshift("\n");
define_property(error, "stack", {
value: stack2.join("\n")
});
define_property(error, "name", {
value: label
});
return (
/** @type {Error & { stack: string }} */
error
);
}
function get_stack() {
const limit = Error.stackTraceLimit;
Error.stackTraceLimit = Infinity;
const stack2 = new Error().stack;
Error.stackTraceLimit = limit;
if (!stack2) return [];
const lines = stack2.split("\n");
const new_lines = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const posixified = line.replaceAll("\\", "/");
if (line.trim() === "Error") {
continue;
}
if (line.includes("validate_each_keys")) {
return [];
}
if (posixified.includes("svelte/src/internal") || posixified.includes("node_modules/.vite")) {
continue;
}
new_lines.push(line);
}
return new_lines;
}
function invariant(condition, message) {
if (!dev_fallback_default) {
throw new Error("invariant(...) was not guarded by if (DEV)");
}
if (!condition) invariant_violation(message);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/context.js
var component_context = null;
function set_component_context(context) {
component_context = context;
}
var dev_stack = null;
function set_dev_stack(stack2) {
dev_stack = stack2;
}
var dev_current_component_function = null;
function set_dev_current_component_function(fn) {
dev_current_component_function = fn;
}
function push(props, runes = false, fn) {
component_context = {
p: component_context,
i: false,
c: null,
e: null,
s: props,
x: null,
r: (
/** @type {Effect} */
active_effect
),
l: legacy_mode_flag && !runes ? { s: null, u: null, $: [] } : null
};
if (dev_fallback_default) {
component_context.function = fn;
dev_current_component_function = fn;
}
}
function pop(component2) {
var context = (
/** @type {ComponentContext} */
component_context
);
var effects = context.e;
if (effects !== null) {
context.e = null;
for (var fn of effects) {
create_user_effect(fn);
}
}
if (component2 !== void 0) {
context.x = component2;
}
context.i = true;
component_context = context.p;
if (dev_fallback_default) {
dev_current_component_function = component_context?.function ?? null;
}
return component2 ?? /** @type {T} */
{};
}
function is_runes() {
return !legacy_mode_flag || component_context !== null && component_context.l === null;
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/task.js
var micro_tasks = [];
function run_micro_tasks() {
var tasks = micro_tasks;
micro_tasks = [];
run_all(tasks);
}
function queue_micro_task(fn) {
if (micro_tasks.length === 0 && !is_flushing_sync) {
var tasks = micro_tasks;
queueMicrotask(() => {
if (tasks === micro_tasks) run_micro_tasks();
});
}
micro_tasks.push(fn);
}
function flush_tasks() {
while (micro_tasks.length > 0) {
run_micro_tasks();
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/error-handling.js
var adjustments = /* @__PURE__ */ new WeakMap();
function handle_error(error) {
var effect2 = active_effect;
if (effect2 === null) {
active_reaction.f |= ERROR_VALUE;
return error;
}
if (dev_fallback_default && error instanceof Error && !adjustments.has(error)) {
adjustments.set(error, get_adjustments(error, effect2));
}
if ((effect2.f & REACTION_RAN) === 0 && (effect2.f & EFFECT) === 0) {
if (dev_fallback_default && !effect2.parent && error instanceof Error) {
apply_adjustments(error);
}
throw error;
}
invoke_error_boundary(error, effect2);
}
function invoke_error_boundary(error, effect2) {
if (effect2 !== null && (effect2.f & DESTROYED) !== 0) {
return;
}
while (effect2 !== null) {
if ((effect2.f & BOUNDARY_EFFECT) !== 0) {
if ((effect2.f & REACTION_RAN) === 0) {
throw error;
}
try {
effect2.b.error(error);
return;
} catch (e) {
error = e;
}
}
effect2 = effect2.parent;
}
if (dev_fallback_default && error instanceof Error) {
apply_adjustments(error);
}
throw error;
}
function get_adjustments(error, effect2) {
const message_descriptor = get_descriptor(error, "message");
if (message_descriptor && !message_descriptor.configurable) return;
var indent = is_firefox ? " " : " ";
var component_stack = `
${indent}in ${effect2.fn?.name || "<unknown>"}`;
var context = effect2.ctx;
while (context !== null) {
component_stack += `
${indent}in ${context.function?.[FILENAME].split("/").pop()}`;
context = context.p;
}
return {
message: error.message + `
${component_stack}
`,
stack: error.stack?.split("\n").filter((line) => !line.includes("svelte/src/internal")).join("\n")
};
}
function apply_adjustments(error) {
const adjusted = adjustments.get(error);
if (adjusted) {
define_property(error, "message", {
value: adjusted.message
});
define_property(error, "stack", {
value: adjusted.stack
});
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/status.js
var STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);
function set_signal_status(signal, status) {
signal.f = signal.f & STATUS_MASK | status;
}
function update_derived_status(derived2) {
if ((derived2.f & CONNECTED) !== 0 || derived2.deps === null) {
set_signal_status(derived2, CLEAN);
} else {
set_signal_status(derived2, MAYBE_DIRTY);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/utils.js
function clear_marked(deps) {
if (deps === null) return;
for (const dep of deps) {
if ((dep.f & DERIVED) === 0 || (dep.f & WAS_MARKED) === 0) {
continue;
}
dep.f ^= WAS_MARKED;
clear_marked(
/** @type {Derived} */
dep.deps
);
}
}
function defer_effect(effect2, dirty_effects, maybe_dirty_effects) {
if ((effect2.f & DIRTY) !== 0) {
dirty_effects.add(effect2);
} else if ((effect2.f & MAYBE_DIRTY) !== 0) {
maybe_dirty_effects.add(effect2);
}
clear_marked(effect2.deps);
set_signal_status(effect2, CLEAN);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/store.js
var legacy_is_updating_store = false;
var is_store_binding = false;
function capture_store_binding(fn) {
var previous_is_store_binding = is_store_binding;
try {
is_store_binding = false;
return [fn(), is_store_binding];
} finally {
is_store_binding = previous_is_store_binding;
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/reactivity/create-subscriber.js
function createSubscriber(start) {
let subscribers = 0;
let version = source(0);
let stop;
if (dev_fallback_default) {
tag(version, "createSubscriber version");
}
return () => {
if (effect_tracking()) {
get2(version);
render_effect(() => {
if (subscribers === 0) {
stop = untrack(() => start(() => increment(version)));
}
subscribers += 1;
return () => {
queue_micro_task(() => {
subscribers -= 1;
if (subscribers === 0) {
stop?.();
stop = void 0;
increment(version);
}
});
};
});
}
};
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/blocks/boundary.js
var flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED;
function boundary(node, props, children, transform_error) {
new Boundary(node, props, children, transform_error);
}
var _anchor, _hydrate_open, _props, _children, _effect, _main_effect, _pending_effect, _failed_effect, _offscreen_fragment, _local_pending_count, _pending_count, _pending_count_update_queued, _dirty_effects, _maybe_dirty_effects, _effect_pending, _effect_pending_subscriber, _Boundary_instances, hydrate_resolved_content_fn, hydrate_failed_content_fn, hydrate_pending_content_fn, render_fn, resolve_fn, run_fn, update_pending_count_fn, handle_error_fn;
var Boundary = class {
/**
* @param {TemplateNode} node
* @param {BoundaryProps} props
* @param {((anchor: Node) => void)} children
* @param {((error: unknown) => unknown) | undefined} [transform_error]
*/
constructor(node, props, children, transform_error) {
__privateAdd(this, _Boundary_instances);
/** @type {Boundary | null} */
__publicField(this, "parent");
__publicField(this, "is_pending", false);
/**
* API-level transformError transform function. Transforms errors before they reach the `failed` snippet.
* Inherited from parent boundary, or defaults to identity.
* @type {(error: unknown) => unknown}
*/
__publicField(this, "transform_error");
/** @type {TemplateNode} */
__privateAdd(this, _anchor);
/** @type {TemplateNode | null} */
__privateAdd(this, _hydrate_open, hydrating ? hydrate_node : null);
/** @type {BoundaryProps} */
__privateAdd(this, _props);
/** @type {((anchor: Node) => void)} */
__privateAdd(this, _children);
/** @type {Effect} */
__privateAdd(this, _effect);
/** @type {Effect | null} */
__privateAdd(this, _main_effect, null);
/** @type {Effect | null} */
__privateAdd(this, _pending_effect, null);
/** @type {Effect | null} */
__privateAdd(this, _failed_effect, null);
/** @type {DocumentFragment | null} */
__privateAdd(this, _offscreen_fragment, null);
__privateAdd(this, _local_pending_count, 0);
__privateAdd(this, _pending_count, 0);
__privateAdd(this, _pending_count_update_queued, false);
/** @type {Set<Effect>} */
__privateAdd(this, _dirty_effects, /* @__PURE__ */ new Set());
/** @type {Set<Effect>} */
__privateAdd(this, _maybe_dirty_effects, /* @__PURE__ */ new Set());
/**
* A source containing the number of pending async deriveds/expressions.
* Only created if `$effect.pending()` is used inside the boundary,
* otherwise updating the source results in needless `Batch.ensure()`
* calls followed by no-op flushes
* @type {Source<number> | null}
*/
__privateAdd(this, _effect_pending, null);
__privateAdd(this, _effect_pending_subscriber, createSubscriber(() => {
__privateSet(this, _effect_pending, source(__privateGet(this, _local_pending_count)));
if (dev_fallback_default) {
tag(__privateGet(this, _effect_pending), "$effect.pending()");
}
return () => {
__privateSet(this, _effect_pending, null);
};
}));
__privateSet(this, _anchor, node);
__privateSet(this, _props, props);
__privateSet(this, _children, (anchor) => {
var effect2 = (
/** @type {Effect} */
active_effect
);
effect2.b = this;
effect2.f |= BOUNDARY_EFFECT;
children(anchor);
});
this.parent = /** @type {Effect} */
active_effect.b;
this.transform_error = transform_error ?? this.parent?.transform_error ?? ((e) => e);
__privateSet(this, _effect, block(() => {
if (hydrating) {
const comment2 = (
/** @type {Comment} */
__privateGet(this, _hydrate_open)
);
hydrate_next();
const server_rendered_pending = comment2.data === HYDRATION_START_ELSE;
const server_rendered_failed = comment2.data.startsWith(HYDRATION_START_FAILED);
if (server_rendered_failed) {
const serialized_error = JSON.parse(comment2.data.slice(HYDRATION_START_FAILED.length));
__privateMethod(this, _Boundary_instances, hydrate_failed_content_fn).call(this, serialized_error);
} else if (server_rendered_pending) {
__privateMethod(this, _Boundary_instances, hydrate_pending_content_fn).call(this);
} else {
__privateMethod(this, _Boundary_instances, hydrate_resolved_content_fn).call(this);
}
} else {
__privateMethod(this, _Boundary_instances, render_fn).call(this);
}
}, flags));
if (hydrating) {
__privateSet(this, _anchor, hydrate_node);
}
}
/**
* Defer an effect inside a pending boundary until the boundary resolves
* @param {Effect} effect
*/
defer_effect(effect2) {
defer_effect(effect2, __privateGet(this, _dirty_effects), __privateGet(this, _maybe_dirty_effects));
}
/**
* Returns `false` if the effect exists inside a boundary whose pending snippet is shown
* @returns {boolean}
*/
is_rendered() {
return !this.is_pending && (!this.parent || this.parent.is_rendered());
}
has_pending_snippet() {
return !!__privateGet(this, _props).pending;
}
/**
* Update the source that powers `$effect.pending()` inside this boundary,
* and controls when the current `pending` snippet (if any) is removed.
* Do not call from inside the class
* @param {1 | -1} d
* @param {Batch} batch
*/
update_pending_count(d, batch) {
__privateMethod(this, _Boundary_instances, update_pending_count_fn).call(this, d, batch);
__privateSet(this, _local_pending_count, __privateGet(this, _local_pending_count) + d);
if (!__privateGet(this, _effect_pending) || __privateGet(this, _pending_count_update_queued)) return;
__privateSet(this, _pending_count_update_queued, true);
queue_micro_task(() => {
__privateSet(this, _pending_count_update_queued, false);
if (__privateGet(this, _effect_pending)) {
internal_set(__privateGet(this, _effect_pending), __privateGet(this, _local_pending_count));
}
});
}
get_effect_pending() {
__privateGet(this, _effect_pending_subscriber).call(this);
return get2(
/** @type {Source<number>} */
__privateGet(this, _effect_pending)
);
}
/** @param {unknown} error */
error(error) {
if (!__privateGet(this, _props).onerror && !__privateGet(this, _props).failed) {
throw error;
}
if (current_batch?.is_fork) {
if (__privateGet(this, _main_effect)) current_batch.skip_effect(__privateGet(this, _main_effect));
if (__privateGet(this, _pending_effect)) current_batch.skip_effect(__privateGet(this, _pending_effect));
if (__privateGet(this, _failed_effect)) current_batch.skip_effect(__privateGet(this, _failed_effect));
current_batch.oncommit(() => {
__privateMethod(this, _Boundary_instances, handle_error_fn).call(this, error);
});
} else {
__privateMethod(this, _Boundary_instances, handle_error_fn).call(this, error);
}
}
};
_anchor = new WeakMap();
_hydrate_open = new WeakMap();
_props = new WeakMap();
_children = new WeakMap();
_effect = new WeakMap();
_main_effect = new WeakMap();
_pending_effect = new WeakMap();
_failed_effect = new WeakMap();
_offscreen_fragment = new WeakMap();
_local_pending_count = new WeakMap();
_pending_count = new WeakMap();
_pending_count_update_queued = new WeakMap();
_dirty_effects = new WeakMap();
_maybe_dirty_effects = new WeakMap();
_effect_pending = new WeakMap();
_effect_pending_subscriber = new WeakMap();
_Boundary_instances = new WeakSet();
hydrate_resolved_content_fn = function() {
try {
__privateSet(this, _main_effect, branch(() => __privateGet(this, _children).call(this, __privateGet(this, _anchor))));
} catch (error) {
this.error(error);
}
};
/**
* @param {unknown} error The deserialized error from the server's hydration comment
*/
hydrate_failed_content_fn = function(error) {
const failed = __privateGet(this, _props).failed;
if (!failed) return;
__privateSet(this, _failed_effect, branch(() => {
failed(
__privateGet(this, _anchor),
() => error,
() => () => {
}
);
}));
};
hydrate_pending_content_fn = function() {
const pending3 = __privateGet(this, _props).pending;
if (!pending3) return;
this.is_pending = true;
__privateSet(this, _pending_effect, branch(() => pending3(__privateGet(this, _anchor))));
queue_micro_task(() => {
var fragment = __privateSet(this, _offscreen_fragment, document.createDocumentFragment());
var anchor = create_text();
fragment.append(anchor);
__privateSet(this, _main_effect, __privateMethod(this, _Boundary_instances, run_fn).call(this, () => {
return branch(() => __privateGet(this, _children).call(this, anchor));
}));
if (__privateGet(this, _pending_count) === 0) {
__privateGet(this, _anchor).before(fragment);
__privateSet(this, _offscreen_fragment, null);
pause_effect(
/** @type {Effect} */
__privateGet(this, _pending_effect),
() => {
__privateSet(this, _pending_effect, null);
}
);
__privateMethod(this, _Boundary_instances, resolve_fn).call(
this,
/** @type {Batch} */
current_batch
);
}
});
};
render_fn = function() {
try {
this.is_pending = this.has_pending_snippet();
__privateSet(this, _pending_count, 0);
__privateSet(this, _local_pending_count, 0);
__privateSet(this, _main_effect, branch(() => {
__privateGet(this, _children).call(this, __privateGet(this, _anchor));
}));
if (__privateGet(this, _pending_count) > 0) {
var fragment = __privateSet(this, _offscreen_fragment, document.createDocumentFragment());
move_effect(__privateGet(this, _main_effect), fragment);
const pending3 = (
/** @type {(anchor: Node) => void} */
__privateGet(this, _props).pending
);
__privateSet(this, _pending_effect, branch(() => pending3(__privateGet(this, _anchor))));
} else {
__privateMethod(this, _Boundary_instances, resolve_fn).call(
this,
/** @type {Batch} */
current_batch
);
}
} catch (error) {
this.error(error);
}
};
/**
* @param {Batch} batch
*/
resolve_fn = function(batch) {
this.is_pending = false;
batch.transfer_effects(__privateGet(this, _dirty_effects), __privateGet(this, _maybe_dirty_effects));
};
/**
* @template T
* @param {() => T} fn
*/
run_fn = function(fn) {
var previous_effect = active_effect;
var previous_reaction = active_reaction;
var previous_ctx = component_context;
set_active_effect(__privateGet(this, _effect));
set_active_reaction(__privateGet(this, _effect));
set_component_context(__privateGet(this, _effect).ctx);
try {
Batch.ensure();
return fn();
} catch (e) {
handle_error(e);
return null;
} finally {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_ctx);
}
};
/**
* Updates the pending count associated with the currently visible pending snippet,
* if any, such that we can replace the snippet with content once work is done
* @param {1 | -1} d
* @param {Batch} batch
*/
update_pending_count_fn = function(d, batch) {
var _a2;
if (!this.has_pending_snippet()) {
if (this.parent) {
__privateMethod(_a2 = this.parent, _Boundary_instances, update_pending_count_fn).call(_a2, d, batch);
}
return;
}
__privateSet(this, _pending_count, __privateGet(this, _pending_count) + d);
if (__privateGet(this, _pending_count) === 0) {
__privateMethod(this, _Boundary_instances, resolve_fn).call(this, batch);
if (__privateGet(this, _pending_effect)) {
pause_effect(__privateGet(this, _pending_effect), () => {
__privateSet(this, _pending_effect, null);
});
}
if (__privateGet(this, _offscreen_fragment)) {
__privateGet(this, _anchor).before(__privateGet(this, _offscreen_fragment));
__privateSet(this, _offscreen_fragment, null);
}
}
};
/**
* @param {unknown} error
*/
handle_error_fn = function(error) {
if (__privateGet(this, _main_effect)) {
destroy_effect(__privateGet(this, _main_effect));
__privateSet(this, _main_effect, null);
}
if (__privateGet(this, _pending_effect)) {
destroy_effect(__privateGet(this, _pending_effect));
__privateSet(this, _pending_effect, null);
}
if (__privateGet(this, _failed_effect)) {
destroy_effect(__privateGet(this, _failed_effect));
__privateSet(this, _failed_effect, null);
}
if (hydrating) {
set_hydrate_node(
/** @type {TemplateNode} */
__privateGet(this, _hydrate_open)
);
next();
set_hydrate_node(skip_nodes());
}
var onerror = __privateGet(this, _props).onerror;
let failed = __privateGet(this, _props).failed;
var did_reset = false;
var calling_on_error = false;
const reset2 = () => {
if (did_reset) {
svelte_boundary_reset_noop();
return;
}
did_reset = true;
if (calling_on_error) {
svelte_boundary_reset_onerror();
}
if (__privateGet(this, _failed_effect) !== null) {
pause_effect(__privateGet(this, _failed_effect), () => {
__privateSet(this, _failed_effect, null);
});
}
__privateMethod(this, _Boundary_instances, run_fn).call(this, () => {
__privateMethod(this, _Boundary_instances, render_fn).call(this);
});
};
const handle_error_result = (transformed_error) => {
try {
calling_on_error = true;
onerror?.(transformed_error, reset2);
calling_on_error = false;
} catch (error2) {
invoke_error_boundary(error2, __privateGet(this, _effect) && __privateGet(this, _effect).parent);
}
if (failed) {
__privateSet(this, _failed_effect, __privateMethod(this, _Boundary_instances, run_fn).call(this, () => {
try {
return branch(() => {
var effect2 = (
/** @type {Effect} */
active_effect
);
effect2.b = this;
effect2.f |= BOUNDARY_EFFECT;
failed(
__privateGet(this, _anchor),
() => transformed_error,
() => reset2
);
});
} catch (error2) {
invoke_error_boundary(
error2,
/** @type {Effect} */
__privateGet(this, _effect).parent
);
return null;
}
}));
}
};
queue_micro_task(() => {
var result;
try {
result = this.transform_error(error);
} catch (e) {
invoke_error_boundary(e, __privateGet(this, _effect) && __privateGet(this, _effect).parent);
return;
}
if (result !== null && typeof result === "object" && typeof /** @type {any} */
result.then === "function") {
result.then(
handle_error_result,
/** @param {unknown} e */
(e) => invoke_error_boundary(e, __privateGet(this, _effect) && __privateGet(this, _effect).parent)
);
} else {
handle_error_result(result);
}
});
};
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/async.js
function flatten(blockers, sync, async2, fn) {
const d = is_runes() ? derived : derived_safe_equal;
var pending3 = blockers.filter((b) => !b.settled);
var deriveds = sync.map(d);
if (dev_fallback_default) {
deriveds.forEach((d2, i) => {
d2.label = sync[i].toString().replace("() => ", "").replaceAll("$.eager(() => ", "$state.eager(").replace(/\$\.get\((.+?)\)/g, (_, id) => id);
});
}
if (async2.length === 0 && pending3.length === 0) {
fn(deriveds);
return;
}
var parent = (
/** @type {Effect} */
active_effect
);
var restore = capture();
var blocker_promise = pending3.length === 1 ? pending3[0].promise : pending3.length > 1 ? Promise.all(pending3.map((b) => b.promise)) : null;
function finish(async3) {
if ((parent.f & DESTROYED) !== 0) {
return;
}
restore();
try {
fn([...deriveds, ...async3]);
} catch (error) {
invoke_error_boundary(error, parent);
}
unset_context();
}
var decrement_pending = increment_pending();
if (async2.length === 0) {
blocker_promise.then(() => finish([])).finally(decrement_pending);
return;
}
function run3() {
Promise.all(async2.map((expression) => async_derived(expression))).then(finish).catch((error) => invoke_error_boundary(error, parent)).finally(decrement_pending);
}
if (blocker_promise) {
blocker_promise.then(() => {
restore();
run3();
unset_context();
});
} else {
run3();
}
}
function capture() {
var previous_effect = (
/** @type {Effect} */
active_effect
);
var previous_reaction = active_reaction;
var previous_component_context = component_context;
var previous_batch2 = (
/** @type {Batch} */
current_batch
);
if (dev_fallback_default) {
var previous_dev_stack = dev_stack;
}
return function restore(activate_batch = true) {
set_active_effect(previous_effect);
set_active_reaction(previous_reaction);
set_component_context(previous_component_context);
if (activate_batch && (previous_effect.f & DESTROYED) === 0) {
previous_batch2?.activate();
previous_batch2?.apply();
}
if (dev_fallback_default) {
set_reactivity_loss_tracker(null);
set_dev_stack(previous_dev_stack);
}
};
}
function unset_context(deactivate_batch = true) {
set_active_effect(null);
set_active_reaction(null);
set_component_context(null);
if (deactivate_batch) current_batch?.deactivate();
if (dev_fallback_default) {
set_reactivity_loss_tracker(null);
set_dev_stack(null);
}
}
function increment_pending() {
var effect2 = (
/** @type {Effect} */
active_effect
);
var boundary2 = effect2.b;
var batch = (
/** @type {Batch} */
current_batch
);
var blocking = !!boundary2?.is_rendered();
boundary2?.update_pending_count(1, batch);
batch.increment(blocking, effect2);
return () => {
boundary2?.update_pending_count(-1, batch);
batch.decrement(blocking, effect2);
};
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/deriveds.js
var reactivity_loss_tracker = null;
function set_reactivity_loss_tracker(v) {
reactivity_loss_tracker = v;
}
var recent_async_deriveds = /* @__PURE__ */ new Set();
// @__NO_SIDE_EFFECTS__
function derived(fn) {
var flags2 = DERIVED | DIRTY;
if (active_effect !== null) {
active_effect.f |= EFFECT_PRESERVED;
}
const signal = {
ctx: component_context,
deps: null,
effects: null,
equals,
f: flags2,
fn,
reactions: null,
rv: 0,
v: (
/** @type {V} */
UNINITIALIZED
),
wv: 0,
parent: active_effect,
ac: null
};
if (dev_fallback_default && tracing_mode_flag) {
signal.created = get_error("created at");
}
return signal;
}
var OBSOLETE = /* @__PURE__ */ Symbol("obsolete");
// @__NO_SIDE_EFFECTS__
function async_derived(fn, label, location) {
let parent = (
/** @type {Effect | null} */
active_effect
);
if (parent === null) {
async_derived_orphan();
}
var promise = (
/** @type {Promise<V>} */
/** @type {unknown} */
void 0
);
var signal = source(
/** @type {V} */
UNINITIALIZED
);
if (dev_fallback_default) signal.label = label ?? fn.toString();
var should_suspend = !active_reaction;
var deferreds = /* @__PURE__ */ new Set();
async_effect(() => {
var effect2 = (
/** @type {Effect} */
active_effect
);
if (dev_fallback_default) {
reactivity_loss_tracker = { effect: effect2, effect_deps: /* @__PURE__ */ new Set(), warned: false };
}
var d = deferred();
promise = d.promise;
try {
Promise.resolve(fn()).then(d.resolve, (e) => {
if (e !== STALE_REACTION) d.reject(e);
}).finally(unset_context);
} catch (error) {
d.reject(error);
unset_context();
}
if (dev_fallback_default) {
if (reactivity_loss_tracker) {
if (effect2.deps !== null) {
for (let i = 0; i < skipped_deps; i += 1) {
reactivity_loss_tracker.effect_deps.add(effect2.deps[i]);
}
}
if (new_deps !== null) {
for (let i = 0; i < new_deps.length; i += 1) {
reactivity_loss_tracker.effect_deps.add(new_deps[i]);
}
}
}
reactivity_loss_tracker = null;
}
var batch = (
/** @type {Batch} */
current_batch
);
if (should_suspend) {
if ((effect2.f & REACTION_RAN) !== 0) {
var decrement_pending = increment_pending();
}
if (
// boundary can be null if the async derived is inside an $effect.root not connected to the component render tree
parent.b?.is_rendered()
) {
batch.async_deriveds.get(effect2)?.reject(OBSOLETE);
} else {
for (const d2 of deferreds.values()) {
d2.reject(OBSOLETE);
}
}
deferreds.add(d);
batch.async_deriveds.set(effect2, d);
}
const handler = (value, error = void 0) => {
if (dev_fallback_default) {
reactivity_loss_tracker = null;
}
decrement_pending?.();
deferreds.delete(d);
if (error === OBSOLETE) return;
batch.activate();
if (error) {
signal.f |= ERROR_VALUE;
internal_set(signal, error);
} else {
if ((signal.f & ERROR_VALUE) !== 0) {
signal.f ^= ERROR_VALUE;
}
if (dev_fallback_default && location !== void 0 && !signal.equals(value)) {
recent_async_deriveds.add(signal);
setTimeout(() => {
if (recent_async_deriveds.has(signal) && (effect2.f & DESTROYED) === 0) {
await_waterfall(
/** @type {string} */
signal.label,
location
);
recent_async_deriveds.delete(signal);
}
});
}
internal_set(signal, value);
}
batch.deactivate();
};
d.promise.then(handler, (e) => handler(null, e || "unknown"));
});
teardown(() => {
for (const d of deferreds) {
d.reject(OBSOLETE);
}
});
if (dev_fallback_default) {
signal.f |= ASYNC;
}
return new Promise((fulfil) => {
function next2(p) {
function go() {
if (p === promise) {
fulfil(signal);
} else {
next2(promise);
}
}
p.then(go, go);
}
next2(promise);
});
}
// @__NO_SIDE_EFFECTS__
function user_derived(fn) {
const d = /* @__PURE__ */ derived(fn);
if (!async_mode_flag) push_reaction_value(d);
return d;
}
// @__NO_SIDE_EFFECTS__
function derived_safe_equal(fn) {
const signal = /* @__PURE__ */ derived(fn);
signal.equals = safe_equals;
return signal;
}
function destroy_derived_effects(derived2) {
var effects = derived2.effects;
if (effects !== null) {
derived2.effects = null;
for (var i = 0; i < effects.length; i += 1) {
destroy_effect(
/** @type {Effect} */
effects[i]
);
}
}
}
var stack = [];
function execute_derived(derived2) {
var value;
var prev_active_effect = active_effect;
var parent = derived2.parent;
if (!is_destroying_effect && parent !== null && derived2.v !== UNINITIALIZED && // if it was never evaluated before, it's guaranteed to fail downstream, so we try to execute instead
(parent.f & (DESTROYED | INERT)) !== 0) {
derived_inert();
return derived2.v;
}
set_active_effect(parent);
if (dev_fallback_default) {
let prev_eager_effects = eager_effects;
set_eager_effects(/* @__PURE__ */ new Set());
try {
if (includes.call(stack, derived2)) {
derived_references_self();
}
stack.push(derived2);
derived2.f &= ~WAS_MARKED;
destroy_derived_effects(derived2);
value = update_reaction(derived2);
} finally {
set_active_effect(prev_active_effect);
set_eager_effects(prev_eager_effects);
stack.pop();
}
} else {
try {
derived2.f &= ~WAS_MARKED;
destroy_derived_effects(derived2);
value = update_reaction(derived2);
} finally {
set_active_effect(prev_active_effect);
}
}
return value;
}
function update_derived(derived2) {
var value = execute_derived(derived2);
if (!derived2.equals(value)) {
derived2.wv = increment_write_version();
if (!current_batch?.is_fork || derived2.deps === null) {
if (current_batch !== null) {
current_batch.capture(derived2, value, true);
previous_batch?.capture(derived2, value, true);
} else {
derived2.v = value;
}
if (derived2.deps === null) {
set_signal_status(derived2, CLEAN);
return;
}
}
}
if (is_destroying_effect) {
return;
}
if (batch_values !== null) {
if (effect_tracking() || current_batch?.is_fork) {
batch_values.set(derived2, value);
}
} else {
update_derived_status(derived2);
}
}
function freeze_derived_effects(derived2) {
if (derived2.effects === null) return;
for (const e of derived2.effects) {
if (e.teardown || e.ac) {
e.teardown?.();
e.ac?.abort(STALE_REACTION);
if (e.fn !== null) e.teardown = noop;
e.ac = null;
remove_reactions(e, 0);
destroy_effect_children(e);
}
}
}
function unfreeze_derived_effects(derived2) {
if (derived2.effects === null) return;
for (const e of derived2.effects) {
if (e.teardown && e.fn !== null) {
update_effect(e);
}
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/batch.js
var first_batch = null;
var last_batch = null;
var current_batch = null;
var previous_batch = null;
var batch_values = null;
var last_scheduled_effect = null;
var is_flushing_sync = false;
var is_processing = false;
var collected_effects = null;
var legacy_updates = null;
var flush_count = 0;
var source_stacks = /* @__PURE__ */ new Set();
var uid = 1;
var _started, _prev, _next, _commit_callbacks, _discard_callbacks, _pending, _blocking_pending, _deferred, _roots, _new_effects, _dirty_effects2, _maybe_dirty_effects2, _skipped_branches, _unskipped_branches, _decrement_queued, _Batch_instances, is_deferred_fn, process_fn, traverse_fn, find_earlier_batch_fn, merge_fn, defer_effects_fn, commit_fn, unlink_fn;
var _Batch = class _Batch {
constructor() {
__privateAdd(this, _Batch_instances);
__publicField(this, "id", uid++);
/** True as soon as `#process` was called */
__privateAdd(this, _started, false);
__publicField(this, "linked", true);
/** @type {Batch | null} */
__privateAdd(this, _prev, null);
/** @type {Batch | null} */
__privateAdd(this, _next, null);
/** @type {Map<Effect, ReturnType<typeof deferred<any>>>} */
__publicField(this, "async_deriveds", /* @__PURE__ */ new Map());
/**
* The current values of any signals that are updated in this batch.
* Tuple format: [value, is_derived] (note: is_derived is false for deriveds, too, if they were overridden via assignment)
* They keys of this map are identical to `this.#previous`
* @type {Map<Value, [any, boolean]>}
*/
__publicField(this, "current", /* @__PURE__ */ new Map());
/**
* The values of any signals (sources and deriveds) that are updated in this batch _before_ those updates took place.
* They keys of this map are identical to `this.#current`
* @type {Map<Value, any>}
*/
__publicField(this, "previous", /* @__PURE__ */ new Map());
/**
* When the batch is committed (and the DOM is updated), we need to remove old branches
* and append new ones by calling the functions added inside (if/each/key/etc) blocks
* @type {Set<(batch: Batch) => void>}
*/
__privateAdd(this, _commit_callbacks, /* @__PURE__ */ new Set());
/**
* If a fork is discarded, we need to destroy any effects that are no longer needed
* @type {Set<(batch: Batch) => void>}
*/
__privateAdd(this, _discard_callbacks, /* @__PURE__ */ new Set());
/**
* The number of async effects that are currently in flight
*/
__privateAdd(this, _pending, 0);
/**
* Async effects that are currently in flight, _not_ inside a pending boundary
* @type {Map<Effect, number>}
*/
__privateAdd(this, _blocking_pending, /* @__PURE__ */ new Map());
/**
* A deferred that resolves when the batch is committed, used with `settled()`
* TODO replace with Promise.withResolvers once supported widely enough
* @type {{ promise: Promise<void>, resolve: (value?: any) => void, reject: (reason: unknown) => void } | null}
*/
__privateAdd(this, _deferred, null);
/**
* The root effects that need to be flushed
* @type {Effect[]}
*/
__privateAdd(this, _roots, []);
/**
* Effects created while this batch was active.
* @type {Effect[]}
*/
__privateAdd(this, _new_effects, []);
/**
* Deferred effects (which run after async work has completed) that are DIRTY
* @type {Set<Effect>}
*/
__privateAdd(this, _dirty_effects2, /* @__PURE__ */ new Set());
/**
* Deferred effects that are MAYBE_DIRTY
* @type {Set<Effect>}
*/
__privateAdd(this, _maybe_dirty_effects2, /* @__PURE__ */ new Set());
/**
* A map of branches that still exist, but will be destroyed when this batch
* is committed — we skip over these during `process`.
* The value contains child effects that were dirty/maybe_dirty before being reset,
* so they can be rescheduled if the branch survives.
* @type {Map<Effect, { d: Effect[], m: Effect[] }>}
*/
__privateAdd(this, _skipped_branches, /* @__PURE__ */ new Map());
/**
* Inverse of #skipped_branches which we need to tell prior batches to unskip them when committing
* @type {Set<Effect>}
*/
__privateAdd(this, _unskipped_branches, /* @__PURE__ */ new Set());
__publicField(this, "is_fork", false);
__privateAdd(this, _decrement_queued, false);
if (last_batch === null) {
first_batch = last_batch = this;
} else {
__privateSet(last_batch, _next, this);
__privateSet(this, _prev, last_batch);
}
last_batch = this;
}
/**
* Add an effect to the #skipped_branches map and reset its children
* @param {Effect} effect
*/
skip_effect(effect2) {
if (!__privateGet(this, _skipped_branches).has(effect2)) {
__privateGet(this, _skipped_branches).set(effect2, { d: [], m: [] });
}
__privateGet(this, _unskipped_branches).delete(effect2);
}
/**
* Remove an effect from the #skipped_branches map and reschedule
* any tracked dirty/maybe_dirty child effects
* @param {Effect} effect
* @param {(e: Effect) => void} callback
*/
unskip_effect(effect2, callback = (e) => this.schedule(e)) {
var tracked = __privateGet(this, _skipped_branches).get(effect2);
if (tracked) {
__privateGet(this, _skipped_branches).delete(effect2);
for (var e of tracked.d) {
set_signal_status(e, DIRTY);
callback(e);
}
for (e of tracked.m) {
set_signal_status(e, MAYBE_DIRTY);
callback(e);
}
}
__privateGet(this, _unskipped_branches).add(effect2);
}
/**
* Associate a change to a given source with the current
* batch, noting its previous and current values
* @param {Value} source
* @param {any} value
* @param {boolean} [is_derived]
*/
capture(source2, value, is_derived = false) {
if (source2.v !== UNINITIALIZED && !this.previous.has(source2)) {
this.previous.set(source2, source2.v);
}
if ((source2.f & ERROR_VALUE) === 0) {
this.current.set(source2, [value, is_derived]);
batch_values?.set(source2, value);
}
if (!this.is_fork) {
source2.v = value;
}
}
activate() {
current_batch = this;
}
deactivate() {
current_batch = null;
batch_values = null;
}
flush() {
try {
if (dev_fallback_default) {
source_stacks.clear();
}
is_processing = true;
current_batch = this;
__privateMethod(this, _Batch_instances, process_fn).call(this);
} finally {
flush_count = 0;
last_scheduled_effect = null;
collected_effects = null;
legacy_updates = null;
is_processing = false;
current_batch = null;
batch_values = null;
old_values.clear();
if (dev_fallback_default) {
for (const source2 of source_stacks) {
source2.updated = null;
}
}
}
}
discard() {
for (const fn of __privateGet(this, _discard_callbacks)) fn(this);
__privateGet(this, _discard_callbacks).clear();
for (const deferred2 of this.async_deriveds.values()) {
deferred2.reject(OBSOLETE);
}
__privateMethod(this, _Batch_instances, unlink_fn).call(this);
__privateGet(this, _deferred)?.resolve();
}
/**
* @param {Effect} effect
*/
register_created_effect(effect2) {
__privateGet(this, _new_effects).push(effect2);
}
/**
* @param {boolean} blocking
* @param {Effect} effect
*/
increment(blocking, effect2) {
__privateSet(this, _pending, __privateGet(this, _pending) + 1);
if (blocking) {
let blocking_pending_count = __privateGet(this, _blocking_pending).get(effect2) ?? 0;
__privateGet(this, _blocking_pending).set(effect2, blocking_pending_count + 1);
}
}
/**
* @param {boolean} blocking
* @param {Effect} effect
*/
decrement(blocking, effect2) {
__privateSet(this, _pending, __privateGet(this, _pending) - 1);
if (blocking) {
let blocking_pending_count = __privateGet(this, _blocking_pending).get(effect2) ?? 0;
if (blocking_pending_count === 1) {
__privateGet(this, _blocking_pending).delete(effect2);
} else {
__privateGet(this, _blocking_pending).set(effect2, blocking_pending_count - 1);
}
}
if (__privateGet(this, _decrement_queued)) return;
__privateSet(this, _decrement_queued, true);
queue_micro_task(() => {
__privateSet(this, _decrement_queued, false);
if (this.linked) {
this.flush();
}
});
}
/**
* @param {Set<Effect>} dirty_effects
* @param {Set<Effect>} maybe_dirty_effects
*/
transfer_effects(dirty_effects, maybe_dirty_effects) {
for (const e of dirty_effects) {
__privateGet(this, _dirty_effects2).add(e);
}
for (const e of maybe_dirty_effects) {
__privateGet(this, _maybe_dirty_effects2).add(e);
}
dirty_effects.clear();
maybe_dirty_effects.clear();
}
/** @param {(batch: Batch) => void} fn */
oncommit(fn) {
__privateGet(this, _commit_callbacks).add(fn);
}
/** @param {(batch: Batch) => void} fn */
ondiscard(fn) {
__privateGet(this, _discard_callbacks).add(fn);
}
settled() {
return (__privateGet(this, _deferred) ?? __privateSet(this, _deferred, deferred())).promise;
}
static ensure() {
if (current_batch === null) {
const batch = current_batch = new _Batch();
if (!is_processing && !is_flushing_sync) {
queue_micro_task(() => {
if (!__privateGet(batch, _started)) {
batch.flush();
}
});
}
}
return current_batch;
}
apply() {
if (!async_mode_flag || !this.is_fork && __privateGet(this, _prev) === null && __privateGet(this, _next) === null) {
batch_values = null;
return;
}
batch_values = /* @__PURE__ */ new Map();
for (const [source2, [value]] of this.current) {
batch_values.set(source2, value);
}
for (let batch = first_batch; batch !== null; batch = __privateGet(batch, _next)) {
if (batch === this || batch.is_fork) continue;
var intersects = false;
if (batch.id < this.id) {
for (const [source2, [, is_derived]] of batch.current) {
if (is_derived) continue;
if (this.current.has(source2)) {
intersects = true;
break;
}
}
}
if (!intersects) {
for (const [source2, previous] of batch.previous) {
if (!batch_values.has(source2)) {
batch_values.set(source2, previous);
}
}
}
}
}
/**
*
* @param {Effect} effect
*/
schedule(effect2) {
last_scheduled_effect = effect2;
if (effect2.b?.is_pending && (effect2.f & (EFFECT | RENDER_EFFECT | MANAGED_EFFECT)) !== 0 && (effect2.f & REACTION_RAN) === 0) {
effect2.b.defer_effect(effect2);
return;
}
var e = effect2;
while (e.parent !== null) {
e = e.parent;
var flags2 = e.f;
if (collected_effects !== null && e === active_effect) {
if (async_mode_flag) return;
if ((active_reaction === null || (active_reaction.f & DERIVED) === 0) && !legacy_is_updating_store) {
return;
}
}
if ((flags2 & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) {
if ((flags2 & CLEAN) === 0) {
return;
}
e.f ^= CLEAN;
}
}
__privateGet(this, _roots).push(e);
}
};
_started = new WeakMap();
_prev = new WeakMap();
_next = new WeakMap();
_commit_callbacks = new WeakMap();
_discard_callbacks = new WeakMap();
_pending = new WeakMap();
_blocking_pending = new WeakMap();
_deferred = new WeakMap();
_roots = new WeakMap();
_new_effects = new WeakMap();
_dirty_effects2 = new WeakMap();
_maybe_dirty_effects2 = new WeakMap();
_skipped_branches = new WeakMap();
_unskipped_branches = new WeakMap();
_decrement_queued = new WeakMap();
_Batch_instances = new WeakSet();
is_deferred_fn = function() {
if (this.is_fork) return true;
for (const effect2 of __privateGet(this, _blocking_pending).keys()) {
var e = effect2;
var skipped = false;
while (e.parent !== null) {
if (__privateGet(this, _skipped_branches).has(e)) {
skipped = true;
break;
}
e = e.parent;
}
if (!skipped) {
return true;
}
}
return false;
};
process_fn = function() {
var _a2, _b, _c;
__privateSet(this, _started, true);
if (flush_count++ > 1e3) {
__privateMethod(this, _Batch_instances, unlink_fn).call(this);
infinite_loop_guard();
}
if (dev_fallback_default) {
for (const value of this.current.keys()) {
source_stacks.add(value);
}
}
for (const e of __privateGet(this, _dirty_effects2)) {
__privateGet(this, _maybe_dirty_effects2).delete(e);
set_signal_status(e, DIRTY);
this.schedule(e);
}
for (const e of __privateGet(this, _maybe_dirty_effects2)) {
set_signal_status(e, MAYBE_DIRTY);
this.schedule(e);
}
const roots = __privateGet(this, _roots);
__privateSet(this, _roots, []);
this.apply();
var effects = collected_effects = [];
var render_effects = [];
var updates = legacy_updates = [];
for (const root7 of roots) {
try {
__privateMethod(this, _Batch_instances, traverse_fn).call(this, root7, effects, render_effects);
} catch (e) {
reset_all(root7);
if (!__privateMethod(this, _Batch_instances, is_deferred_fn).call(this)) this.discard();
throw e;
}
}
current_batch = null;
if (updates.length > 0) {
var batch = _Batch.ensure();
for (const e of updates) {
batch.schedule(e);
}
}
collected_effects = null;
legacy_updates = null;
if (__privateMethod(this, _Batch_instances, is_deferred_fn).call(this)) {
__privateMethod(this, _Batch_instances, defer_effects_fn).call(this, render_effects);
__privateMethod(this, _Batch_instances, defer_effects_fn).call(this, effects);
for (const [e, t] of __privateGet(this, _skipped_branches)) {
reset_branch(e, t);
}
if (updates.length > 0) {
/** @type {unknown} */
__privateMethod(_a2 = current_batch, _Batch_instances, process_fn).call(_a2);
}
return;
}
const earlier_batch = __privateMethod(this, _Batch_instances, find_earlier_batch_fn).call(this);
if (earlier_batch) {
__privateMethod(this, _Batch_instances, defer_effects_fn).call(this, render_effects);
__privateMethod(this, _Batch_instances, defer_effects_fn).call(this, effects);
__privateMethod(_b = earlier_batch, _Batch_instances, merge_fn).call(_b, this);
return;
}
__privateGet(this, _dirty_effects2).clear();
__privateGet(this, _maybe_dirty_effects2).clear();
for (const fn of __privateGet(this, _commit_callbacks)) fn(this);
__privateGet(this, _commit_callbacks).clear();
previous_batch = this;
flush_queued_effects(render_effects);
flush_queued_effects(effects);
previous_batch = null;
__privateGet(this, _deferred)?.resolve();
var next_batch = (
/** @type {Batch | null} */
/** @type {unknown} */
current_batch
);
if (__privateGet(this, _pending) === 0 && (__privateGet(this, _roots).length === 0 || next_batch !== null)) {
__privateMethod(this, _Batch_instances, unlink_fn).call(this);
if (async_mode_flag) {
__privateMethod(this, _Batch_instances, commit_fn).call(this);
current_batch = next_batch;
}
}
if (__privateGet(this, _roots).length > 0) {
if (next_batch !== null) {
const batch2 = next_batch;
__privateGet(batch2, _roots).push(...__privateGet(this, _roots).filter((r) => !__privateGet(batch2, _roots).includes(r)));
} else {
next_batch = this;
}
}
if (next_batch !== null) {
__privateMethod(_c = next_batch, _Batch_instances, process_fn).call(_c);
}
};
/**
* Traverse the effect tree, executing effects or stashing
* them for later execution as appropriate
* @param {Effect} root
* @param {Effect[]} effects
* @param {Effect[]} render_effects
*/
traverse_fn = function(root7, effects, render_effects) {
root7.f ^= CLEAN;
var effect2 = root7.first;
while (effect2 !== null) {
var flags2 = effect2.f;
var is_branch = (flags2 & (BRANCH_EFFECT | ROOT_EFFECT)) !== 0;
var is_skippable_branch = is_branch && (flags2 & CLEAN) !== 0;
var skip = is_skippable_branch || (flags2 & INERT) !== 0 || __privateGet(this, _skipped_branches).has(effect2);
if (!skip && effect2.fn !== null) {
if (is_branch) {
effect2.f ^= CLEAN;
} else if ((flags2 & EFFECT) !== 0) {
effects.push(effect2);
} else if (async_mode_flag && (flags2 & (RENDER_EFFECT | MANAGED_EFFECT)) !== 0) {
render_effects.push(effect2);
} else if (is_dirty(effect2)) {
if ((flags2 & BLOCK_EFFECT) !== 0) __privateGet(this, _maybe_dirty_effects2).add(effect2);
update_effect(effect2);
}
var child2 = effect2.first;
if (child2 !== null) {
effect2 = child2;
continue;
}
}
while (effect2 !== null) {
var next2 = effect2.next;
if (next2 !== null) {
effect2 = next2;
break;
}
effect2 = effect2.parent;
}
}
};
find_earlier_batch_fn = function() {
var batch = __privateGet(this, _prev);
while (batch !== null) {
if (!batch.is_fork) {
for (const [value, [, is_derived]] of this.current) {
if (batch.current.has(value) && !is_derived) {
return batch;
}
}
}
batch = __privateGet(batch, _prev);
}
return null;
};
/**
* @param {Batch} batch
*/
merge_fn = function(batch) {
var _a2;
for (const [source2, value] of batch.current) {
if (!this.previous.has(source2) && batch.previous.has(source2)) {
this.previous.set(source2, batch.previous.get(source2));
}
this.current.set(source2, value);
}
for (const [effect2, deferred2] of batch.async_deriveds) {
const d = this.async_deriveds.get(effect2);
if (d) deferred2.promise.then(d.resolve).catch(d.reject);
}
batch.async_deriveds.clear();
this.transfer_effects(__privateGet(batch, _dirty_effects2), __privateGet(batch, _maybe_dirty_effects2));
const mark = (value) => {
var reactions = value.reactions;
if (reactions === null) return;
for (const reaction of reactions) {
var flags2 = reaction.f;
if ((flags2 & DERIVED) !== 0) {
mark(
/** @type {Derived} */
reaction
);
} else {
var effect2 = (
/** @type {Effect} */
reaction
);
if (flags2 & (ASYNC | BLOCK_EFFECT) && !this.async_deriveds.has(effect2)) {
__privateGet(this, _maybe_dirty_effects2).delete(effect2);
set_signal_status(effect2, DIRTY);
this.schedule(effect2);
}
}
}
};
for (const source2 of this.current.keys()) {
mark(source2);
}
this.oncommit(() => batch.discard());
__privateMethod(_a2 = batch, _Batch_instances, unlink_fn).call(_a2);
current_batch = this;
__privateMethod(this, _Batch_instances, process_fn).call(this);
};
/**
* @param {Effect[]} effects
*/
defer_effects_fn = function(effects) {
for (var i = 0; i < effects.length; i += 1) {
defer_effect(effects[i], __privateGet(this, _dirty_effects2), __privateGet(this, _maybe_dirty_effects2));
}
};
commit_fn = function() {
var _a2;
for (let batch = first_batch; batch !== null; batch = __privateGet(batch, _next)) {
var is_earlier = batch.id < this.id;
var sources = [];
for (const [source3, [value, is_derived]] of this.current) {
if (batch.current.has(source3)) {
var batch_value = (
/** @type {[any, boolean]} */
batch.current.get(source3)[0]
);
if (is_earlier && value !== batch_value) {
batch.current.set(source3, [value, is_derived]);
} else {
continue;
}
}
sources.push(source3);
}
if (is_earlier) {
for (const [effect2, deferred2] of this.async_deriveds) {
const d = batch.async_deriveds.get(effect2);
if (d) deferred2.promise.then(d.resolve).catch(d.reject);
}
}
var current = [...batch.current.keys()].filter(
(source3) => !/** @type {[any, boolean]} */
batch.current.get(source3)[1]
);
if (!__privateGet(batch, _started) || current.length === 0) continue;
var others = current.filter((source3) => !this.current.has(source3));
if (others.length === 0) {
if (is_earlier) {
batch.discard();
}
} else if (sources.length > 0) {
if (dev_fallback_default && !__privateGet(batch, _decrement_queued)) {
invariant(__privateGet(batch, _roots).length === 0, "Batch has scheduled roots");
}
if (is_earlier) {
for (const unskipped of __privateGet(this, _unskipped_branches)) {
batch.unskip_effect(unskipped, (e) => {
var _a3;
if ((e.f & (BLOCK_EFFECT | ASYNC)) !== 0) {
batch.schedule(e);
} else {
__privateMethod(_a3 = batch, _Batch_instances, defer_effects_fn).call(_a3, [e]);
}
});
}
}
batch.activate();
var marked = /* @__PURE__ */ new Set();
var checked = /* @__PURE__ */ new Map();
for (var source2 of sources) {
mark_effects(source2, others, marked, checked);
}
checked = /* @__PURE__ */ new Map();
var current_unequal = [...batch.current].filter(([c, v1]) => {
const v2 = this.current.get(c);
if (!v2) return true;
return v2[0] !== v1[0] || v2[1] !== v1[1];
}).map(([c]) => c);
if (current_unequal.length > 0) {
for (const effect2 of __privateGet(this, _new_effects)) {
if ((effect2.f & (DESTROYED | INERT | EAGER_EFFECT)) === 0 && depends_on(effect2, current_unequal, checked)) {
if ((effect2.f & (ASYNC | BLOCK_EFFECT)) !== 0) {
set_signal_status(effect2, DIRTY);
batch.schedule(effect2);
} else {
__privateGet(batch, _dirty_effects2).add(effect2);
}
}
}
}
if (__privateGet(batch, _roots).length > 0 && !__privateGet(batch, _decrement_queued)) {
batch.apply();
for (var root7 of __privateGet(batch, _roots)) {
__privateMethod(_a2 = batch, _Batch_instances, traverse_fn).call(_a2, root7, [], []);
}
__privateSet(batch, _roots, []);
}
batch.deactivate();
}
}
};
unlink_fn = function() {
if (!this.linked) return;
var prev = __privateGet(this, _prev);
var next2 = __privateGet(this, _next);
if (prev === null) {
first_batch = next2;
} else {
__privateSet(prev, _next, next2);
}
if (next2 === null) {
last_batch = prev;
} else {
__privateSet(next2, _prev, prev);
}
this.linked = false;
};
var Batch = _Batch;
function flushSync(fn) {
var was_flushing_sync = is_flushing_sync;
is_flushing_sync = true;
try {
var result;
if (fn) {
if (current_batch !== null && !current_batch.is_fork) {
current_batch.flush();
}
result = fn();
}
while (true) {
flush_tasks();
if (current_batch === null) {
return (
/** @type {T} */
result
);
}
current_batch.flush();
}
} finally {
is_flushing_sync = was_flushing_sync;
}
}
function infinite_loop_guard() {
if (dev_fallback_default) {
var updates = /* @__PURE__ */ new Map();
for (
const source2 of
/** @type {Batch} */
current_batch.current.keys()
) {
for (const [stack2, update2] of source2.updated ?? []) {
var entry = updates.get(stack2);
if (!entry) {
entry = { error: update2.error, count: 0 };
updates.set(stack2, entry);
}
entry.count += update2.count;
}
}
for (const update2 of updates.values()) {
if (update2.error) {
console.error(update2.error);
}
}
}
try {
effect_update_depth_exceeded();
} catch (error) {
if (dev_fallback_default) {
define_property(error, "stack", { value: "" });
}
invoke_error_boundary(error, last_scheduled_effect);
}
}
var eager_block_effects = null;
function flush_queued_effects(effects) {
var length = effects.length;
if (length === 0) return;
var i = 0;
while (i < length) {
var effect2 = effects[i++];
if ((effect2.f & (DESTROYED | INERT)) === 0 && is_dirty(effect2)) {
eager_block_effects = /* @__PURE__ */ new Set();
update_effect(effect2);
if (effect2.deps === null && effect2.first === null && effect2.nodes === null && effect2.teardown === null && effect2.ac === null) {
unlink_effect(effect2);
}
if (eager_block_effects?.size > 0) {
old_values.clear();
for (const e of eager_block_effects) {
if ((e.f & (DESTROYED | INERT)) !== 0) continue;
const ordered_effects = [e];
let ancestor = e.parent;
while (ancestor !== null) {
if (eager_block_effects.has(ancestor)) {
eager_block_effects.delete(ancestor);
ordered_effects.push(ancestor);
}
ancestor = ancestor.parent;
}
for (let j = ordered_effects.length - 1; j >= 0; j--) {
const e2 = ordered_effects[j];
if ((e2.f & (DESTROYED | INERT)) !== 0) continue;
update_effect(e2);
}
}
eager_block_effects.clear();
}
}
}
eager_block_effects = null;
}
function mark_effects(value, sources, marked, checked) {
if (marked.has(value)) return;
marked.add(value);
if (value.reactions !== null) {
for (const reaction of value.reactions) {
const flags2 = reaction.f;
if ((flags2 & DERIVED) !== 0) {
mark_effects(
/** @type {Derived} */
reaction,
sources,
marked,
checked
);
} else if ((flags2 & (ASYNC | BLOCK_EFFECT)) !== 0 && (flags2 & DIRTY) === 0 && depends_on(reaction, sources, checked)) {
set_signal_status(reaction, DIRTY);
schedule_effect(
/** @type {Effect} */
reaction
);
}
}
}
}
function depends_on(reaction, sources, checked) {
const depends = checked.get(reaction);
if (depends !== void 0) return depends;
if (reaction.deps !== null) {
for (const dep of reaction.deps) {
if (includes.call(sources, dep)) {
return true;
}
if ((dep.f & DERIVED) !== 0 && depends_on(
/** @type {Derived} */
dep,
sources,
checked
)) {
checked.set(
/** @type {Derived} */
dep,
true
);
return true;
}
}
}
checked.set(reaction, false);
return false;
}
function schedule_effect(effect2) {
current_batch.schedule(effect2);
}
function reset_branch(effect2, tracked) {
if ((effect2.f & BRANCH_EFFECT) !== 0 && (effect2.f & CLEAN) !== 0) {
return;
}
if ((effect2.f & DIRTY) !== 0) {
tracked.d.push(effect2);
} else if ((effect2.f & MAYBE_DIRTY) !== 0) {
tracked.m.push(effect2);
}
set_signal_status(effect2, CLEAN);
var e = effect2.first;
while (e !== null) {
reset_branch(e, tracked);
e = e.next;
}
}
function reset_all(effect2) {
set_signal_status(effect2, CLEAN);
var e = effect2.first;
while (e !== null) {
reset_all(e);
e = e.next;
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/sources.js
var eager_effects = /* @__PURE__ */ new Set();
var old_values = /* @__PURE__ */ new Map();
function set_eager_effects(v) {
eager_effects = v;
}
var eager_effects_deferred = false;
function set_eager_effects_deferred() {
eager_effects_deferred = true;
}
function source(v, stack2) {
var signal = {
f: 0,
// TODO ideally we could skip this altogether, but it causes type errors
v,
reactions: null,
equals,
rv: 0,
wv: 0
};
if (dev_fallback_default && tracing_mode_flag) {
signal.created = stack2 ?? get_error("created at");
signal.updated = null;
signal.set_during_effect = false;
signal.trace = null;
}
return signal;
}
// @__NO_SIDE_EFFECTS__
function state(v, stack2) {
const s = source(v, stack2);
push_reaction_value(s);
return s;
}
// @__NO_SIDE_EFFECTS__
function mutable_source(initial_value, immutable = false, trackable = true) {
var _a2;
const s = source(initial_value);
if (!immutable) {
s.equals = safe_equals;
}
if (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) {
((_a2 = component_context.l).s ?? (_a2.s = [])).push(s);
}
return s;
}
function set(source2, value, should_proxy = false) {
if (active_reaction !== null && // since we are untracking the function inside `$inspect.with` we need to add this check
// to ensure we error if state is set inside an inspect effect
(!untracking || (active_reaction.f & EAGER_EFFECT) !== 0) && is_runes() && (active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC | EAGER_EFFECT)) !== 0 && (current_sources === null || !current_sources.has(source2))) {
state_unsafe_mutation();
}
let new_value = should_proxy ? proxy(value) : value;
if (dev_fallback_default) {
tag_proxy(
new_value,
/** @type {string} */
source2.label
);
}
return internal_set(source2, new_value, legacy_updates);
}
function internal_set(source2, value, updated_during_traversal = null) {
if (!source2.equals(value)) {
old_values.set(source2, is_destroying_effect ? value : source2.v);
var batch = Batch.ensure();
batch.capture(source2, value);
if (dev_fallback_default) {
if (tracing_mode_flag || active_effect !== null) {
source2.updated ?? (source2.updated = /* @__PURE__ */ new Map());
const count = (source2.updated.get("")?.count ?? 0) + 1;
source2.updated.set("", { error: (
/** @type {any} */
null
), count });
if (tracing_mode_flag || count > 5) {
const error = get_error("updated at");
if (error !== null) {
let entry = source2.updated.get(error.stack);
if (!entry) {
entry = { error, count: 0 };
source2.updated.set(error.stack, entry);
}
entry.count++;
}
}
}
if (active_effect !== null) {
source2.set_during_effect = true;
}
}
if ((source2.f & DERIVED) !== 0) {
const derived2 = (
/** @type {Derived} */
source2
);
if ((source2.f & DIRTY) !== 0) {
execute_derived(derived2);
}
if (batch_values === null) {
update_derived_status(derived2);
}
}
source2.wv = increment_write_version();
mark_reactions(source2, DIRTY, updated_during_traversal);
if (is_runes() && active_effect !== null && (active_effect.f & CLEAN) !== 0 && (active_effect.f & (BRANCH_EFFECT | ROOT_EFFECT)) === 0) {
if (untracked_writes === null) {
set_untracked_writes([source2]);
} else {
untracked_writes.push(source2);
}
}
if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) {
flush_eager_effects();
}
}
return value;
}
function flush_eager_effects() {
eager_effects_deferred = false;
for (const effect2 of eager_effects) {
if ((effect2.f & CLEAN) !== 0) {
set_signal_status(effect2, MAYBE_DIRTY);
}
let dirty;
try {
dirty = is_dirty(effect2);
} catch {
dirty = true;
}
if (dirty) {
update_effect(effect2);
}
}
eager_effects.clear();
}
function increment(source2) {
set(source2, source2.v + 1);
}
function mark_reactions(signal, status, updated_during_traversal) {
var reactions = signal.reactions;
if (reactions === null) return;
var runes = is_runes();
var length = reactions.length;
for (var i = 0; i < length; i++) {
var reaction = reactions[i];
var flags2 = reaction.f;
if (!runes && reaction === active_effect) continue;
var not_dirty = (flags2 & DIRTY) === 0;
if (not_dirty) {
set_signal_status(reaction, status);
}
if ((flags2 & EAGER_EFFECT) !== 0) {
eager_effects.add(
/** @type {Effect} */
reaction
);
} else if ((flags2 & DERIVED) !== 0) {
var derived2 = (
/** @type {Derived} */
reaction
);
batch_values?.delete(derived2);
if ((flags2 & WAS_MARKED) === 0) {
if (flags2 & CONNECTED && (active_effect === null || (active_effect.f & REACTION_IS_UPDATING) === 0)) {
reaction.f |= WAS_MARKED;
}
mark_reactions(derived2, MAYBE_DIRTY, updated_during_traversal);
}
} else if (not_dirty) {
var effect2 = (
/** @type {Effect} */
reaction
);
if ((flags2 & BLOCK_EFFECT) !== 0 && eager_block_effects !== null) {
eager_block_effects.add(effect2);
}
if (updated_during_traversal !== null) {
updated_during_traversal.push(effect2);
} else {
schedule_effect(effect2);
}
}
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/proxy.js
var regex_is_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
function proxy(value) {
if (typeof value !== "object" || value === null || STATE_SYMBOL in value) {
return value;
}
const prototype = get_prototype_of(value);
if (prototype !== object_prototype && prototype !== array_prototype) {
return value;
}
var sources = /* @__PURE__ */ new Map();
var is_proxied_array = is_array(value);
var version = state(0);
var stack2 = dev_fallback_default && tracing_mode_flag ? get_error("created at") : null;
var parent_version = update_version;
var with_parent = (fn) => {
if (update_version === parent_version) {
return fn();
}
var reaction = active_reaction;
var version2 = update_version;
set_active_reaction(null);
set_update_version(parent_version);
var result = fn();
set_active_reaction(reaction);
set_update_version(version2);
return result;
};
if (is_proxied_array) {
sources.set("length", state(
/** @type {any[]} */
value.length,
stack2
));
if (dev_fallback_default) {
value = /** @type {any} */
inspectable_array(
/** @type {any[]} */
value
);
}
}
var path = "";
let updating = false;
function update_path(new_path) {
if (updating) return;
updating = true;
path = new_path;
tag(version, `${path} version`);
for (const [prop2, source2] of sources) {
tag(source2, get_label(path, prop2));
}
updating = false;
}
return new Proxy(
/** @type {any} */
value,
{
defineProperty(_, prop2, descriptor) {
if (!("value" in descriptor) || descriptor.configurable === false || descriptor.enumerable === false || descriptor.writable === false) {
state_descriptors_fixed();
}
var s = sources.get(prop2);
if (s === void 0) {
with_parent(() => {
var s2 = state(descriptor.value, stack2);
sources.set(prop2, s2);
if (dev_fallback_default && typeof prop2 === "string") {
tag(s2, get_label(path, prop2));
}
return s2;
});
} else {
set(s, descriptor.value, true);
}
return true;
},
deleteProperty(target, prop2) {
var s = sources.get(prop2);
if (s === void 0) {
if (prop2 in target) {
const s2 = with_parent(() => state(UNINITIALIZED, stack2));
sources.set(prop2, s2);
increment(version);
if (dev_fallback_default) {
tag(s2, get_label(path, prop2));
}
}
} else {
set(s, UNINITIALIZED);
increment(version);
}
return true;
},
get(target, prop2, receiver) {
if (prop2 === STATE_SYMBOL) {
return value;
}
if (dev_fallback_default && prop2 === PROXY_PATH_SYMBOL) {
return update_path;
}
var s = sources.get(prop2);
var exists = prop2 in target;
if (s === void 0 && (!exists || get_descriptor(target, prop2)?.writable)) {
s = with_parent(() => {
var p = proxy(exists ? target[prop2] : UNINITIALIZED);
var s2 = state(p, stack2);
if (dev_fallback_default) {
tag(s2, get_label(path, prop2));
}
return s2;
});
sources.set(prop2, s);
}
if (s !== void 0) {
var v = get2(s);
return v === UNINITIALIZED ? void 0 : v;
}
return Reflect.get(target, prop2, receiver);
},
getOwnPropertyDescriptor(target, prop2) {
var descriptor = Reflect.getOwnPropertyDescriptor(target, prop2);
if (descriptor && "value" in descriptor) {
var s = sources.get(prop2);
if (s) descriptor.value = get2(s);
} else if (descriptor === void 0) {
var source2 = sources.get(prop2);
var value2 = source2?.v;
if (source2 !== void 0 && value2 !== UNINITIALIZED) {
return {
enumerable: true,
configurable: true,
value: value2,
writable: true
};
}
}
return descriptor;
},
has(target, prop2) {
if (prop2 === STATE_SYMBOL) {
return true;
}
var s = sources.get(prop2);
var has = s !== void 0 && s.v !== UNINITIALIZED || Reflect.has(target, prop2);
if (s !== void 0 || active_effect !== null && (!has || get_descriptor(target, prop2)?.writable)) {
if (s === void 0) {
s = with_parent(() => {
var p = has ? proxy(target[prop2]) : UNINITIALIZED;
var s2 = state(p, stack2);
if (dev_fallback_default) {
tag(s2, get_label(path, prop2));
}
return s2;
});
sources.set(prop2, s);
}
var value2 = get2(s);
if (value2 === UNINITIALIZED) {
return false;
}
}
return has;
},
set(target, prop2, value2, receiver) {
var s = sources.get(prop2);
var has = prop2 in target;
if (is_proxied_array && prop2 === "length") {
for (var i = value2; i < /** @type {Source<number>} */
s.v; i += 1) {
var other_s = sources.get(i + "");
if (other_s !== void 0) {
set(other_s, UNINITIALIZED);
} else if (i in target) {
other_s = with_parent(() => state(UNINITIALIZED, stack2));
sources.set(i + "", other_s);
if (dev_fallback_default) {
tag(other_s, get_label(path, i));
}
}
}
}
if (s === void 0) {
if (!has || get_descriptor(target, prop2)?.writable) {
s = with_parent(() => state(void 0, stack2));
if (dev_fallback_default) {
tag(s, get_label(path, prop2));
}
set(s, proxy(value2));
sources.set(prop2, s);
}
} else {
has = s.v !== UNINITIALIZED;
var p = with_parent(() => proxy(value2));
set(s, p);
}
var descriptor = Reflect.getOwnPropertyDescriptor(target, prop2);
if (descriptor?.set) {
descriptor.set.call(receiver, value2);
}
if (!has) {
if (is_proxied_array && typeof prop2 === "string") {
var ls = (
/** @type {Source<number>} */
sources.get("length")
);
var n = Number(prop2);
if (Number.isInteger(n) && n >= ls.v) {
set(ls, n + 1);
}
}
increment(version);
}
return true;
},
ownKeys(target) {
get2(version);
var own_keys = Reflect.ownKeys(target).filter((key3) => {
var source3 = sources.get(key3);
return source3 === void 0 || source3.v !== UNINITIALIZED;
});
for (var [key2, source2] of sources) {
if (source2.v !== UNINITIALIZED && !(key2 in target)) {
own_keys.push(key2);
}
}
return own_keys;
},
setPrototypeOf() {
state_prototype_fixed();
}
}
);
}
function get_label(path, prop2) {
if (typeof prop2 === "symbol") return `${path}[Symbol(${prop2.description ?? ""})]`;
if (regex_is_valid_identifier.test(prop2)) return `${path}.${prop2}`;
return /^\d+$/.test(prop2) ? `${path}[${prop2}]` : `${path}['${prop2}']`;
}
function get_proxied_value(value) {
try {
if (value !== null && typeof value === "object" && STATE_SYMBOL in value) {
return value[STATE_SYMBOL];
}
} catch {
}
return value;
}
function is(a, b) {
return Object.is(get_proxied_value(a), get_proxied_value(b));
}
var ARRAY_MUTATING_METHODS = /* @__PURE__ */ new Set([
"copyWithin",
"fill",
"pop",
"push",
"reverse",
"shift",
"sort",
"splice",
"unshift"
]);
function inspectable_array(array) {
return new Proxy(array, {
get(target, prop2, receiver) {
var value = Reflect.get(target, prop2, receiver);
if (!ARRAY_MUTATING_METHODS.has(
/** @type {string} */
prop2
)) {
return value;
}
return function(...args) {
set_eager_effects_deferred();
var result = value.apply(this, args);
flush_eager_effects();
return result;
};
}
});
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dev/equality.js
function init_array_prototype_warnings() {
const array_prototype2 = Array.prototype;
const cleanup = Array.__svelte_cleanup;
if (cleanup) {
cleanup();
}
const { indexOf, lastIndexOf, includes: includes2 } = array_prototype2;
array_prototype2.indexOf = function(item, from_index) {
const index2 = indexOf.call(this, item, from_index);
if (index2 === -1) {
for (let i = from_index ?? 0; i < this.length; i += 1) {
if (get_proxied_value(this[i]) === item) {
state_proxy_equality_mismatch("array.indexOf(...)");
break;
}
}
}
return index2;
};
array_prototype2.lastIndexOf = function(item, from_index) {
const index2 = lastIndexOf.call(this, item, from_index ?? this.length - 1);
if (index2 === -1) {
for (let i = 0; i <= (from_index ?? this.length - 1); i += 1) {
if (get_proxied_value(this[i]) === item) {
state_proxy_equality_mismatch("array.lastIndexOf(...)");
break;
}
}
}
return index2;
};
array_prototype2.includes = function(item, from_index) {
const has = includes2.call(this, item, from_index);
if (!has) {
for (let i = 0; i < this.length; i += 1) {
if (get_proxied_value(this[i]) === item) {
state_proxy_equality_mismatch("array.includes(...)");
break;
}
}
}
return has;
};
Array.__svelte_cleanup = () => {
array_prototype2.indexOf = indexOf;
array_prototype2.lastIndexOf = lastIndexOf;
array_prototype2.includes = includes2;
};
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/operations.js
var $window;
var $document;
var is_firefox;
var first_child_getter;
var next_sibling_getter;
function init_operations() {
if ($window !== void 0) {
return;
}
$window = window;
$document = document;
is_firefox = /Firefox/.test(navigator.userAgent);
var element_prototype = Element.prototype;
var node_prototype = Node.prototype;
var text_prototype = Text.prototype;
first_child_getter = get_descriptor(node_prototype, "firstChild").get;
next_sibling_getter = get_descriptor(node_prototype, "nextSibling").get;
if (is_extensible(element_prototype)) {
element_prototype[CLASS_CACHE] = void 0;
element_prototype[ATTRIBUTES_CACHE] = null;
element_prototype[STYLE_CACHE] = void 0;
element_prototype.__e = void 0;
}
if (is_extensible(text_prototype)) {
text_prototype[TEXT_CACHE] = void 0;
}
if (dev_fallback_default) {
element_prototype.__svelte_meta = null;
init_array_prototype_warnings();
}
}
function create_text(value = "") {
return document.createTextNode(value);
}
// @__NO_SIDE_EFFECTS__
function get_first_child(node) {
return (
/** @type {TemplateNode | null} */
first_child_getter.call(node)
);
}
// @__NO_SIDE_EFFECTS__
function get_next_sibling(node) {
return (
/** @type {TemplateNode | null} */
next_sibling_getter.call(node)
);
}
function child(node, is_text) {
if (!hydrating) {
return /* @__PURE__ */ get_first_child(node);
}
var child2 = /* @__PURE__ */ get_first_child(hydrate_node);
if (child2 === null) {
child2 = hydrate_node.appendChild(create_text());
} else if (is_text && child2.nodeType !== TEXT_NODE) {
var text2 = create_text();
child2?.before(text2);
set_hydrate_node(text2);
return text2;
}
if (is_text) {
merge_text_nodes(
/** @type {Text} */
child2
);
}
set_hydrate_node(child2);
return child2;
}
function first_child(node, is_text = false) {
if (!hydrating) {
var first = /* @__PURE__ */ get_first_child(node);
if (first instanceof Comment && first.data === "") return /* @__PURE__ */ get_next_sibling(first);
return first;
}
if (is_text) {
if (hydrate_node?.nodeType !== TEXT_NODE) {
var text2 = create_text();
hydrate_node?.before(text2);
set_hydrate_node(text2);
return text2;
}
merge_text_nodes(
/** @type {Text} */
hydrate_node
);
}
return hydrate_node;
}
function sibling(node, count = 1, is_text = false) {
let next_sibling = hydrating ? hydrate_node : node;
var last_sibling;
while (count--) {
last_sibling = next_sibling;
next_sibling = /** @type {TemplateNode} */
/* @__PURE__ */ get_next_sibling(next_sibling);
}
if (!hydrating) {
return next_sibling;
}
if (is_text) {
if (next_sibling?.nodeType !== TEXT_NODE) {
var text2 = create_text();
if (next_sibling === null) {
last_sibling?.after(text2);
} else {
next_sibling.before(text2);
}
set_hydrate_node(text2);
return text2;
}
merge_text_nodes(
/** @type {Text} */
next_sibling
);
}
set_hydrate_node(next_sibling);
return next_sibling;
}
function clear_text_content(node) {
node.textContent = "";
}
function should_defer_append() {
if (!async_mode_flag) return false;
if (eager_block_effects !== null) return false;
var flags2 = (
/** @type {Effect} */
active_effect.f
);
return (flags2 & REACTION_RAN) !== 0;
}
function create_element(tag2, namespace, is2) {
if (namespace == null || namespace === NAMESPACE_HTML) {
return (
/** @type {T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element} */
is2 ? document.createElement(tag2, { is: is2 }) : document.createElement(tag2)
);
}
return (
/** @type {T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element} */
is2 ? document.createElementNS(namespace, tag2, { is: is2 }) : document.createElementNS(namespace, tag2)
);
}
function merge_text_nodes(text2) {
if (
/** @type {string} */
text2.nodeValue.length < 65536
) {
return;
}
let next2 = text2.nextSibling;
while (next2 !== null && next2.nodeType === TEXT_NODE) {
next2.remove();
text2.nodeValue += /** @type {string} */
next2.nodeValue;
next2 = text2.nextSibling;
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/misc.js
var listening_to_form_reset = false;
function add_form_reset_listener() {
if (!listening_to_form_reset) {
listening_to_form_reset = true;
document.addEventListener(
"reset",
(evt) => {
Promise.resolve().then(() => {
if (!evt.defaultPrevented) {
for (
const e of
/**@type {HTMLFormElement} */
evt.target.elements
) {
e[FORM_RESET_HANDLER]?.();
}
}
});
},
// In the capture phase to guarantee we get noticed of it (no possibility of stopPropagation)
{ capture: true }
);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/bindings/shared.js
function without_reactive_context(fn) {
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
return fn();
} finally {
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
}
function listen_to_event_and_reset_event(element2, event2, handler, on_reset = handler) {
element2.addEventListener(event2, () => without_reactive_context(handler));
const prev = (
/** @type {any} */
element2[FORM_RESET_HANDLER]
);
if (prev) {
element2[FORM_RESET_HANDLER] = () => {
prev();
on_reset(true);
};
} else {
element2[FORM_RESET_HANDLER] = () => on_reset(true);
}
add_form_reset_listener();
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/effects.js
function validate_effect(rune) {
if (active_effect === null) {
if (active_reaction === null) {
effect_orphan(rune);
}
effect_in_unowned_derived();
}
if (is_destroying_effect) {
effect_in_teardown(rune);
}
}
function push_effect(effect2, parent_effect) {
var parent_last = parent_effect.last;
if (parent_last === null) {
parent_effect.last = parent_effect.first = effect2;
} else {
parent_last.next = effect2;
effect2.prev = parent_last;
parent_effect.last = effect2;
}
}
function create_effect(type, fn) {
var parent = active_effect;
if (dev_fallback_default) {
while (parent !== null && (parent.f & EAGER_EFFECT) !== 0) {
parent = parent.parent;
}
}
if (parent !== null && (parent.f & INERT) !== 0) {
type |= INERT;
}
var effect2 = {
ctx: component_context,
deps: null,
nodes: null,
f: type | DIRTY | CONNECTED,
first: null,
fn,
last: null,
next: null,
parent,
b: parent && parent.b,
prev: null,
teardown: null,
wv: 0,
ac: null
};
if (dev_fallback_default) {
effect2.component_function = dev_current_component_function;
}
current_batch?.register_created_effect(effect2);
var e = effect2;
if ((type & EFFECT) !== 0) {
if (collected_effects !== null) {
collected_effects.push(effect2);
} else {
Batch.ensure().schedule(effect2);
}
} else if (fn !== null) {
try {
update_effect(effect2);
} catch (e2) {
destroy_effect(effect2);
throw e2;
}
if (e.deps === null && e.teardown === null && e.nodes === null && e.first === e.last && // either `null`, or a singular child
(e.f & EFFECT_PRESERVED) === 0) {
e = e.first;
if ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) {
e.f |= EFFECT_TRANSPARENT;
}
}
}
if (e !== null) {
e.parent = parent;
if (parent !== null) {
push_effect(e, parent);
}
if (active_reaction !== null && (active_reaction.f & DERIVED) !== 0 && (type & ROOT_EFFECT) === 0) {
var derived2 = (
/** @type {Derived} */
active_reaction
);
(derived2.effects ?? (derived2.effects = [])).push(e);
}
}
return effect2;
}
function effect_tracking() {
return active_reaction !== null && !untracking;
}
function teardown(fn) {
const effect2 = create_effect(RENDER_EFFECT, null);
set_signal_status(effect2, CLEAN);
effect2.teardown = fn;
return effect2;
}
function user_effect(fn) {
validate_effect("$effect");
if (dev_fallback_default) {
define_property(fn, "name", {
value: "$effect"
});
}
var flags2 = (
/** @type {Effect} */
active_effect.f
);
var defer = !active_reaction && (flags2 & BRANCH_EFFECT) !== 0 && component_context !== null && !component_context.i;
if (defer) {
var context = (
/** @type {ComponentContext} */
component_context
);
(context.e ?? (context.e = [])).push(fn);
} else {
return create_user_effect(fn);
}
}
function create_user_effect(fn) {
return create_effect(EFFECT | USER_EFFECT, fn);
}
function effect_root(fn) {
Batch.ensure();
const effect2 = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn);
return () => {
destroy_effect(effect2);
};
}
function component_root(fn) {
Batch.ensure();
const effect2 = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn);
return (options = {}) => {
return new Promise((fulfil) => {
if (options.outro) {
pause_effect(effect2, () => {
destroy_effect(effect2);
fulfil(void 0);
});
} else {
destroy_effect(effect2);
fulfil(void 0);
}
});
};
}
function effect(fn) {
return create_effect(EFFECT, fn);
}
function async_effect(fn) {
return create_effect(ASYNC | EFFECT_PRESERVED, fn);
}
function render_effect(fn, flags2 = 0) {
return create_effect(RENDER_EFFECT | flags2, fn);
}
function template_effect(fn, sync = [], async2 = [], blockers = []) {
flatten(blockers, sync, async2, (values) => {
create_effect(RENDER_EFFECT, () => {
fn(...values.map(get2));
});
});
}
function block(fn, flags2 = 0) {
var effect2 = create_effect(BLOCK_EFFECT | flags2, fn);
if (dev_fallback_default) {
effect2.dev_stack = dev_stack;
}
return effect2;
}
function branch(fn) {
return create_effect(BRANCH_EFFECT | EFFECT_PRESERVED, fn);
}
function execute_effect_teardown(effect2) {
var teardown2 = effect2.teardown;
if (teardown2 !== null) {
const previously_destroying_effect = is_destroying_effect;
const previous_reaction = active_reaction;
set_is_destroying_effect(true);
set_active_reaction(null);
try {
teardown2.call(null);
} finally {
set_is_destroying_effect(previously_destroying_effect);
set_active_reaction(previous_reaction);
}
}
}
function destroy_effect_children(signal, remove_dom = false) {
var effect2 = signal.first;
signal.first = signal.last = null;
while (effect2 !== null) {
const controller = effect2.ac;
if (controller !== null) {
without_reactive_context(() => {
controller.abort(STALE_REACTION);
});
}
var next2 = effect2.next;
if ((effect2.f & ROOT_EFFECT) !== 0) {
effect2.parent = null;
} else {
destroy_effect(effect2, remove_dom);
}
effect2 = next2;
}
}
function destroy_block_effect_children(signal) {
var effect2 = signal.first;
while (effect2 !== null) {
var next2 = effect2.next;
if ((effect2.f & BRANCH_EFFECT) === 0) {
destroy_effect(effect2);
}
effect2 = next2;
}
}
function destroy_effect(effect2, remove_dom = true) {
var removed = false;
if ((remove_dom || (effect2.f & HEAD_EFFECT) !== 0) && effect2.nodes !== null && effect2.nodes.end !== null) {
remove_effect_dom(
effect2.nodes.start,
/** @type {TemplateNode} */
effect2.nodes.end
);
removed = true;
}
effect2.f |= DESTROYING;
destroy_effect_children(effect2, remove_dom && !removed);
remove_reactions(effect2, 0);
var transitions = effect2.nodes && effect2.nodes.t;
if (transitions !== null) {
for (const transition2 of transitions) {
transition2.stop();
}
}
execute_effect_teardown(effect2);
effect2.f ^= DESTROYING;
effect2.f |= DESTROYED;
var parent = effect2.parent;
if (parent !== null && parent.first !== null) {
unlink_effect(effect2);
}
if (dev_fallback_default) {
effect2.component_function = null;
}
effect2.next = effect2.prev = effect2.teardown = effect2.ctx = effect2.deps = effect2.fn = effect2.nodes = effect2.ac = effect2.b = null;
}
function remove_effect_dom(node, end) {
while (node !== null) {
var next2 = node === end ? null : get_next_sibling(node);
node.remove();
node = next2;
}
}
function unlink_effect(effect2) {
var parent = effect2.parent;
var prev = effect2.prev;
var next2 = effect2.next;
if (prev !== null) prev.next = next2;
if (next2 !== null) next2.prev = prev;
if (parent !== null) {
if (parent.first === effect2) parent.first = next2;
if (parent.last === effect2) parent.last = prev;
}
}
function pause_effect(effect2, callback, destroy = true) {
var transitions = [];
pause_children(effect2, transitions, true);
var fn = () => {
if (destroy) destroy_effect(effect2);
if (callback) callback();
};
var remaining = transitions.length;
if (remaining > 0) {
var check = () => --remaining || fn();
for (var transition2 of transitions) {
transition2.out(check);
}
} else {
fn();
}
}
function pause_children(effect2, transitions, local) {
if ((effect2.f & INERT) !== 0) return;
effect2.f ^= INERT;
var t = effect2.nodes && effect2.nodes.t;
if (t !== null) {
for (const transition2 of t) {
if (transition2.is_global || local) {
transitions.push(transition2);
}
}
}
var child2 = effect2.first;
while (child2 !== null) {
var sibling2 = child2.next;
if ((child2.f & ROOT_EFFECT) === 0) {
var transparent = (child2.f & EFFECT_TRANSPARENT) !== 0 || // If this is a branch effect without a block effect parent,
// it means the parent block effect was pruned. In that case,
// transparency information was transferred to the branch effect.
(child2.f & BRANCH_EFFECT) !== 0 && (effect2.f & BLOCK_EFFECT) !== 0;
pause_children(child2, transitions, transparent ? local : false);
}
child2 = sibling2;
}
}
function resume_effect(effect2) {
resume_children(effect2, true);
}
function resume_children(effect2, local) {
if ((effect2.f & INERT) === 0) return;
effect2.f ^= INERT;
if ((effect2.f & CLEAN) === 0) {
set_signal_status(effect2, DIRTY);
Batch.ensure().schedule(effect2);
}
var child2 = effect2.first;
while (child2 !== null) {
var sibling2 = child2.next;
var transparent = (child2.f & EFFECT_TRANSPARENT) !== 0 || (child2.f & BRANCH_EFFECT) !== 0;
resume_children(child2, transparent ? local : false);
child2 = sibling2;
}
var t = effect2.nodes && effect2.nodes.t;
if (t !== null) {
for (const transition2 of t) {
if (transition2.is_global || local) {
transition2.in();
}
}
}
}
function move_effect(effect2, fragment) {
if (!effect2.nodes) return;
var node = effect2.nodes.start;
var end = effect2.nodes.end;
while (node !== null) {
var next2 = node === end ? null : get_next_sibling(node);
fragment.append(node);
node = next2;
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/legacy.js
var captured_signals = null;
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/runtime.js
var is_updating_effect = false;
var is_destroying_effect = false;
function set_is_destroying_effect(value) {
is_destroying_effect = value;
}
var active_reaction = null;
var untracking = false;
function set_active_reaction(reaction) {
active_reaction = reaction;
}
var active_effect = null;
function set_active_effect(effect2) {
active_effect = effect2;
}
var current_sources = null;
function push_reaction_value(value) {
if (active_reaction !== null && (!async_mode_flag || (active_reaction.f & DERIVED) !== 0)) {
(current_sources ?? (current_sources = /* @__PURE__ */ new Set())).add(value);
}
}
var new_deps = null;
var skipped_deps = 0;
var untracked_writes = null;
function set_untracked_writes(value) {
untracked_writes = value;
}
var write_version = 1;
var read_version = 0;
var update_version = read_version;
function set_update_version(value) {
update_version = value;
}
function increment_write_version() {
return ++write_version;
}
function is_dirty(reaction) {
var flags2 = reaction.f;
if ((flags2 & DIRTY) !== 0) {
return true;
}
if (flags2 & DERIVED) {
reaction.f &= ~WAS_MARKED;
}
if ((flags2 & MAYBE_DIRTY) !== 0) {
var dependencies = (
/** @type {Value[]} */
reaction.deps
);
var length = dependencies.length;
for (var i = 0; i < length; i++) {
var dependency = dependencies[i];
if (is_dirty(
/** @type {Derived} */
dependency
)) {
update_derived(
/** @type {Derived} */
dependency
);
}
if (dependency.wv > reaction.wv) {
return true;
}
}
if ((flags2 & CONNECTED) !== 0 && // During time traveling we don't want to reset the status so that
// traversal of the graph in the other batches still happens
batch_values === null) {
set_signal_status(reaction, CLEAN);
}
}
return false;
}
function schedule_possible_effect_self_invalidation(signal, effect2, root7 = true) {
var reactions = signal.reactions;
if (reactions === null) return;
if (!async_mode_flag && current_sources !== null && current_sources.has(signal)) {
return;
}
for (var i = 0; i < reactions.length; i++) {
var reaction = reactions[i];
if ((reaction.f & DERIVED) !== 0) {
schedule_possible_effect_self_invalidation(
/** @type {Derived} */
reaction,
effect2,
false
);
} else if (effect2 === reaction) {
if (root7) {
set_signal_status(reaction, DIRTY);
} else if ((reaction.f & CLEAN) !== 0) {
set_signal_status(reaction, MAYBE_DIRTY);
}
schedule_effect(
/** @type {Effect} */
reaction
);
}
}
}
function update_reaction(reaction) {
var _a2;
var previous_deps = new_deps;
var previous_skipped_deps = skipped_deps;
var previous_untracked_writes = untracked_writes;
var previous_reaction = active_reaction;
var previous_sources = current_sources;
var previous_component_context = component_context;
var previous_untracking = untracking;
var previous_update_version = update_version;
var flags2 = reaction.f;
new_deps = /** @type {null | Value[]} */
null;
skipped_deps = 0;
untracked_writes = null;
active_reaction = (flags2 & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null;
current_sources = null;
set_component_context(reaction.ctx);
untracking = false;
update_version = ++read_version;
if (reaction.ac !== null) {
without_reactive_context(() => {
reaction.ac.abort(STALE_REACTION);
});
reaction.ac = null;
}
try {
reaction.f |= REACTION_IS_UPDATING;
var fn = (
/** @type {Function} */
reaction.fn
);
var result = fn();
reaction.f |= REACTION_RAN;
var deps = reaction.deps;
var is_fork = current_batch?.is_fork;
if (new_deps !== null) {
var i;
if (!is_fork) {
remove_reactions(reaction, skipped_deps);
}
if (deps !== null && skipped_deps > 0) {
deps.length = skipped_deps + new_deps.length;
for (i = 0; i < new_deps.length; i++) {
deps[skipped_deps + i] = new_deps[i];
}
} else {
reaction.deps = deps = new_deps;
}
if (effect_tracking() && (reaction.f & CONNECTED) !== 0) {
for (i = skipped_deps; i < deps.length; i++) {
((_a2 = deps[i]).reactions ?? (_a2.reactions = [])).push(reaction);
}
}
} else if (!is_fork && deps !== null && skipped_deps < deps.length) {
remove_reactions(reaction, skipped_deps);
deps.length = skipped_deps;
}
if (is_runes() && untracked_writes !== null && !untracking && deps !== null && (reaction.f & (DERIVED | MAYBE_DIRTY | DIRTY)) === 0) {
for (i = 0; i < /** @type {Source[]} */
untracked_writes.length; i++) {
schedule_possible_effect_self_invalidation(
untracked_writes[i],
/** @type {Effect} */
reaction
);
}
}
if (previous_reaction !== null && previous_reaction !== reaction) {
read_version++;
if (previous_reaction.deps !== null) {
for (let i2 = 0; i2 < previous_skipped_deps; i2 += 1) {
previous_reaction.deps[i2].rv = read_version;
}
}
if (previous_deps !== null) {
for (const dep of previous_deps) {
dep.rv = read_version;
}
}
if (untracked_writes !== null) {
if (previous_untracked_writes === null) {
previous_untracked_writes = untracked_writes;
} else {
previous_untracked_writes.push(.../** @type {Source[]} */
untracked_writes);
}
}
}
if ((reaction.f & ERROR_VALUE) !== 0) {
reaction.f ^= ERROR_VALUE;
}
return result;
} catch (error) {
return handle_error(error);
} finally {
reaction.f ^= REACTION_IS_UPDATING;
new_deps = previous_deps;
skipped_deps = previous_skipped_deps;
untracked_writes = previous_untracked_writes;
active_reaction = previous_reaction;
current_sources = previous_sources;
set_component_context(previous_component_context);
untracking = previous_untracking;
update_version = previous_update_version;
}
}
function remove_reaction(signal, dependency) {
let reactions = dependency.reactions;
if (reactions !== null) {
var index2 = index_of.call(reactions, signal);
if (index2 !== -1) {
var new_length = reactions.length - 1;
if (new_length === 0) {
reactions = dependency.reactions = null;
} else {
reactions[index2] = reactions[new_length];
reactions.pop();
}
}
}
if (reactions === null && (dependency.f & DERIVED) !== 0 && // Destroying a child effect while updating a parent effect can cause a dependency to appear
// to be unused, when in fact it is used by the currently-updating parent. Checking `new_deps`
// allows us to skip the expensive work of disconnecting and immediately reconnecting it
(new_deps === null || !includes.call(new_deps, dependency))) {
var derived2 = (
/** @type {Derived} */
dependency
);
if ((derived2.f & CONNECTED) !== 0) {
derived2.f ^= CONNECTED;
derived2.f &= ~WAS_MARKED;
}
if (derived2.v !== UNINITIALIZED) {
update_derived_status(derived2);
}
freeze_derived_effects(derived2);
remove_reactions(derived2, 0);
}
}
function remove_reactions(signal, start_index) {
var dependencies = signal.deps;
if (dependencies === null) return;
for (var i = start_index; i < dependencies.length; i++) {
remove_reaction(signal, dependencies[i]);
}
}
function update_effect(effect2) {
var flags2 = effect2.f;
if ((flags2 & DESTROYED) !== 0) {
return;
}
set_signal_status(effect2, CLEAN);
var previous_effect = active_effect;
var was_updating_effect = is_updating_effect;
active_effect = effect2;
is_updating_effect = true;
if (dev_fallback_default) {
var previous_component_fn = dev_current_component_function;
set_dev_current_component_function(effect2.component_function);
var previous_stack = (
/** @type {any} */
dev_stack
);
set_dev_stack(effect2.dev_stack ?? dev_stack);
}
try {
if ((flags2 & (BLOCK_EFFECT | MANAGED_EFFECT)) !== 0) {
destroy_block_effect_children(effect2);
} else {
destroy_effect_children(effect2);
}
execute_effect_teardown(effect2);
var teardown2 = update_reaction(effect2);
effect2.teardown = typeof teardown2 === "function" ? teardown2 : null;
effect2.wv = write_version;
if (dev_fallback_default && tracing_mode_flag && (effect2.f & DIRTY) !== 0 && effect2.deps !== null) {
for (var dep of effect2.deps) {
if (dep.set_during_effect) {
dep.wv = increment_write_version();
dep.set_during_effect = false;
}
}
}
} finally {
is_updating_effect = was_updating_effect;
active_effect = previous_effect;
if (dev_fallback_default) {
set_dev_current_component_function(previous_component_fn);
set_dev_stack(previous_stack);
}
}
}
async function tick() {
if (async_mode_flag) {
return new Promise((f) => {
requestAnimationFrame(() => f());
setTimeout(() => f());
});
}
await Promise.resolve();
flushSync();
}
function get2(signal) {
var flags2 = signal.f;
var is_derived = (flags2 & DERIVED) !== 0;
captured_signals?.add(signal);
if (active_reaction !== null && !untracking) {
var destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0;
if (!destroyed && (current_sources === null || !current_sources.has(signal))) {
var deps = active_reaction.deps;
if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) {
if (signal.rv < read_version) {
signal.rv = read_version;
if (new_deps === null && deps !== null && deps[skipped_deps] === signal) {
skipped_deps++;
} else if (new_deps === null) {
new_deps = [signal];
} else {
new_deps.push(signal);
}
}
} else {
active_reaction.deps ?? (active_reaction.deps = []);
if (!includes.call(active_reaction.deps, signal)) {
active_reaction.deps.push(signal);
}
var reactions = signal.reactions;
if (reactions === null) {
signal.reactions = [active_reaction];
} else if (!includes.call(reactions, active_reaction)) {
reactions.push(active_reaction);
}
}
}
}
if (dev_fallback_default) {
if (!untracking && reactivity_loss_tracker && // By checking that current/previous batch are null we filter out false positives.
// reactivity_loss_tracker is only reset after a microtask, so if a flush happens
// before that, we get warnings for things we shouldn't warn on.
current_batch === null && previous_batch === null && !reactivity_loss_tracker.warned && (reactivity_loss_tracker.effect.f & REACTION_IS_UPDATING) === 0 && !reactivity_loss_tracker.effect_deps.has(signal)) {
reactivity_loss_tracker.warned = true;
await_reactivity_loss(
/** @type {string} */
signal.label
);
var trace2 = get_error("traced at");
if (trace2) console.warn(trace2);
}
recent_async_deriveds.delete(signal);
if (tracing_mode_flag && !untracking && tracing_expressions !== null && active_reaction !== null && tracing_expressions.reaction === active_reaction) {
if (signal.trace) {
signal.trace();
} else {
trace2 = get_error("traced at");
if (trace2) {
var entry = tracing_expressions.entries.get(signal);
if (entry === void 0) {
entry = { traces: [] };
tracing_expressions.entries.set(signal, entry);
}
var last = entry.traces[entry.traces.length - 1];
if (trace2.stack !== last?.stack) {
entry.traces.push(trace2);
}
}
}
}
}
if (is_destroying_effect && old_values.has(signal)) {
return old_values.get(signal);
}
if (is_derived) {
var derived2 = (
/** @type {Derived} */
signal
);
if (is_destroying_effect) {
var value = derived2.v;
if ((derived2.f & CLEAN) === 0 && derived2.reactions !== null || depends_on_old_values(derived2)) {
value = execute_derived(derived2);
}
old_values.set(derived2, value);
return value;
}
var should_connect = (derived2.f & CONNECTED) === 0 && !untracking && active_reaction !== null && (is_updating_effect || (active_reaction.f & CONNECTED) !== 0);
var is_new = (derived2.f & REACTION_RAN) === 0;
if (is_dirty(derived2)) {
if (should_connect) {
derived2.f |= CONNECTED;
}
update_derived(derived2);
}
if (should_connect && !is_new) {
unfreeze_derived_effects(derived2);
reconnect(derived2);
}
}
if (batch_values?.has(signal)) {
return batch_values.get(signal);
}
if ((signal.f & ERROR_VALUE) !== 0) {
throw signal.v;
}
return signal.v;
}
function reconnect(derived2) {
derived2.f |= CONNECTED;
if (derived2.deps === null) return;
for (const dep of derived2.deps) {
(dep.reactions ?? (dep.reactions = [])).push(derived2);
if ((dep.f & DERIVED) !== 0 && (dep.f & CONNECTED) === 0) {
unfreeze_derived_effects(
/** @type {Derived} */
dep
);
reconnect(
/** @type {Derived} */
dep
);
}
}
}
function depends_on_old_values(derived2) {
if (derived2.v === UNINITIALIZED) return true;
if (derived2.deps === null) return false;
for (const dep of derived2.deps) {
if (old_values.has(dep)) {
return true;
}
if ((dep.f & DERIVED) !== 0 && depends_on_old_values(
/** @type {Derived} */
dep
)) {
return true;
}
}
return false;
}
function untrack(fn) {
var previous_untracking = untracking;
try {
untracking = true;
return fn();
} finally {
untracking = previous_untracking;
}
}
function deep_read_state(value) {
if (typeof value !== "object" || !value || value instanceof EventTarget) {
return;
}
if (STATE_SYMBOL in value) {
deep_read(value);
} else if (!Array.isArray(value)) {
for (let key2 in value) {
const prop2 = value[key2];
if (typeof prop2 === "object" && prop2 && STATE_SYMBOL in prop2) {
deep_read(prop2);
}
}
}
}
function deep_read(value, visited = /* @__PURE__ */ new Set()) {
if (typeof value === "object" && value !== null && // We don't want to traverse DOM elements
!(value instanceof EventTarget) && !visited.has(value)) {
visited.add(value);
if (value instanceof Date) {
value.getTime();
}
for (let key2 in value) {
try {
deep_read(value[key2], visited);
} catch (e) {
}
}
const proto = get_prototype_of(value);
if (proto !== Object.prototype && proto !== Array.prototype && proto !== Map.prototype && proto !== Set.prototype && proto !== Date.prototype) {
const descriptors = get_descriptors(proto);
for (let key2 in descriptors) {
const get3 = descriptors[key2].get;
if (get3) {
try {
get3.call(value);
} catch (e) {
}
}
}
}
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/events.js
var event_symbol = /* @__PURE__ */ Symbol("events");
var all_registered_events = /* @__PURE__ */ new Set();
var root_event_handles = /* @__PURE__ */ new Set();
function create_event(event_name, dom, handler, options = {}) {
function target_handler(event2) {
if (!options.capture) {
handle_event_propagation.call(dom, event2);
}
if (!event2.cancelBubble) {
return without_reactive_context(() => {
return handler?.call(this, event2);
});
}
}
if (event_name.startsWith("pointer") || event_name.startsWith("touch") || event_name === "wheel") {
queue_micro_task(() => {
dom.addEventListener(event_name, target_handler, options);
});
} else {
dom.addEventListener(event_name, target_handler, options);
}
return target_handler;
}
function event(event_name, dom, handler, capture2, passive2) {
var options = { capture: capture2, passive: passive2 };
var target_handler = create_event(event_name, dom, handler, options);
if (dom === document.body || // @ts-ignore
dom === window || // @ts-ignore
dom === document || // Firefox has quirky behavior, it can happen that we still get "canplay" events when the element is already removed
dom instanceof HTMLMediaElement) {
teardown(() => {
dom.removeEventListener(event_name, target_handler, options);
});
}
}
function delegated(event_name, element2, handler) {
(element2[event_symbol] ?? (element2[event_symbol] = {}))[event_name] = handler;
}
function delegate(events) {
for (var i = 0; i < events.length; i++) {
all_registered_events.add(events[i]);
}
for (var fn of root_event_handles) {
fn(events);
}
}
var last_propagated_event = null;
function handle_event_propagation(event2) {
var handler_element = this;
var owner_document = (
/** @type {Node} */
handler_element.ownerDocument
);
var event_name = event2.type;
var path = event2.composedPath?.() || [];
var current_target = (
/** @type {null | Element} */
path[0] || event2.target
);
last_propagated_event = event2;
var path_idx = 0;
var handled_at = last_propagated_event === event2 && event2[event_symbol];
if (handled_at) {
var at_idx = path.indexOf(handled_at);
if (at_idx !== -1 && (handler_element === document || handler_element === /** @type {any} */
window)) {
event2[event_symbol] = handler_element;
return;
}
var handler_idx = path.indexOf(handler_element);
if (handler_idx === -1) {
return;
}
if (at_idx <= handler_idx) {
path_idx = at_idx;
}
}
current_target = /** @type {Element} */
path[path_idx] || event2.target;
if (current_target === handler_element) return;
define_property(event2, "currentTarget", {
configurable: true,
get() {
return current_target || owner_document;
}
});
var previous_reaction = active_reaction;
var previous_effect = active_effect;
set_active_reaction(null);
set_active_effect(null);
try {
var throw_error;
var other_errors = [];
while (current_target !== null) {
if (current_target === handler_element) break;
try {
var delegated2 = current_target[event_symbol]?.[event_name];
if (delegated2 != null && (!/** @type {any} */
current_target.disabled || // DOM could've been updated already by the time this is reached, so we check this as well
// -> the target could not have been disabled because it emits the event in the first place
event2.target === current_target)) {
delegated2.call(current_target, event2);
}
} catch (error) {
if (throw_error) {
other_errors.push(error);
} else {
throw_error = error;
}
}
if (event2.cancelBubble) break;
path_idx++;
current_target = path_idx < path.length ? (
/** @type {Element} */
path[path_idx]
) : null;
}
if (throw_error) {
for (let error of other_errors) {
queueMicrotask(() => {
throw error;
});
}
throw throw_error;
}
} finally {
event2[event_symbol] = handler_element;
delete event2.currentTarget;
set_active_reaction(previous_reaction);
set_active_effect(previous_effect);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/reconciler.js
var policy = (
// We gotta write it like this because after downleveling the pure comment may end up in the wrong location
globalThis?.window?.trustedTypes && /* @__PURE__ */ globalThis.window.trustedTypes.createPolicy("svelte-trusted-html", {
/** @param {string} html */
createHTML: (html2) => {
return html2;
}
})
);
function create_trusted_html(html2) {
return (
/** @type {string} */
policy?.createHTML(html2) ?? html2
);
}
function create_fragment_from_html(html2) {
var elem = create_element("template");
elem.innerHTML = create_trusted_html(html2.replaceAll("<!>", "<!---->"));
return elem.content;
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/template.js
function assign_nodes(start, end) {
var effect2 = (
/** @type {Effect} */
active_effect
);
if (effect2.nodes === null) {
effect2.nodes = { start, end, a: null, t: null };
}
}
// @__NO_SIDE_EFFECTS__
function from_html(content, flags2) {
var is_fragment = (flags2 & TEMPLATE_FRAGMENT) !== 0;
var use_import_node = (flags2 & TEMPLATE_USE_IMPORT_NODE) !== 0;
var node;
var has_start = !content.startsWith("<!>");
return () => {
if (hydrating) {
assign_nodes(hydrate_node, null);
return hydrate_node;
}
if (node === void 0) {
node = create_fragment_from_html(has_start ? content : "<!>" + content);
if (!is_fragment) node = /** @type {TemplateNode} */
get_first_child(node);
}
var clone2 = (
/** @type {TemplateNode} */
use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true)
);
if (is_fragment) {
var start = (
/** @type {TemplateNode} */
get_first_child(clone2)
);
var end = (
/** @type {TemplateNode} */
clone2.lastChild
);
assign_nodes(start, end);
} else {
assign_nodes(clone2, clone2);
}
return clone2;
};
}
function append(anchor, dom) {
if (hydrating) {
var effect2 = (
/** @type {Effect & { nodes: EffectNodes }} */
active_effect
);
if ((effect2.f & REACTION_RAN) === 0 || effect2.nodes.end === null) {
effect2.nodes.end = hydrate_node;
}
hydrate_next();
return;
}
if (anchor === null) {
return;
}
anchor.before(
/** @type {Node} */
dom
);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/utils.js
var DOM_BOOLEAN_ATTRIBUTES = [
"allowfullscreen",
"async",
"autofocus",
"autoplay",
"checked",
"controls",
"default",
"disabled",
"formnovalidate",
"indeterminate",
"inert",
"ismap",
"loop",
"multiple",
"muted",
"nomodule",
"novalidate",
"open",
"playsinline",
"readonly",
"required",
"reversed",
"seamless",
"selected",
"webkitdirectory",
"defer",
"disablepictureinpicture",
"disableremoteplayback"
];
var DOM_PROPERTIES = [
...DOM_BOOLEAN_ATTRIBUTES,
"formNoValidate",
"isMap",
"noModule",
"playsInline",
"readOnly",
"value",
"volume",
"defaultValue",
"defaultChecked",
"srcObject",
"noValidate",
"allowFullscreen",
"disablePictureInPicture",
"disableRemotePlayback"
];
var PASSIVE_EVENTS = ["touchstart", "touchmove"];
function is_passive_event(name) {
return PASSIVE_EVENTS.includes(name);
}
var STATE_CREATION_RUNES = (
/** @type {const} */
[
"$state",
"$state.raw",
"$derived",
"$derived.by"
]
);
var RUNES = (
/** @type {const} */
[
...STATE_CREATION_RUNES,
"$state.eager",
"$state.snapshot",
"$props",
"$props.id",
"$bindable",
"$effect",
"$effect.pre",
"$effect.tracking",
"$effect.root",
"$effect.pending",
"$inspect",
"$inspect().with",
"$inspect.trace",
"$host"
]
);
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/render.js
var should_intro = true;
function set_text(text2, value) {
var _a2;
var str = value == null ? "" : typeof value === "object" ? `${value}` : value;
if (str !== /** @type {any} */
(text2[_a2 = TEXT_CACHE] ?? (text2[_a2] = text2.nodeValue))) {
text2[TEXT_CACHE] = str;
text2.nodeValue = `${str}`;
}
}
function mount(component2, options) {
return _mount(component2, options);
}
function hydrate(component2, options) {
init_operations();
options.intro = options.intro ?? false;
const target = options.target;
const was_hydrating = hydrating;
const previous_hydrate_node = hydrate_node;
try {
var anchor = get_first_child(target);
while (anchor && (anchor.nodeType !== COMMENT_NODE || /** @type {Comment} */
anchor.data !== HYDRATION_START)) {
anchor = get_next_sibling(anchor);
}
if (!anchor) {
throw HYDRATION_ERROR;
}
set_hydrating(true);
set_hydrate_node(
/** @type {Comment} */
anchor
);
const instance = _mount(component2, { ...options, anchor });
set_hydrating(false);
return (
/** @type {Exports} */
instance
);
} catch (error) {
if (error instanceof Error && error.message.split("\n").some((line) => line.startsWith("https://svelte.dev/e/"))) {
throw error;
}
if (error !== HYDRATION_ERROR) {
console.warn("Failed to hydrate: ", error);
}
if (options.recover === false) {
hydration_failed();
}
init_operations();
clear_text_content(target);
set_hydrating(false);
return mount(component2, options);
} finally {
set_hydrating(was_hydrating);
set_hydrate_node(previous_hydrate_node);
}
}
var listeners = /* @__PURE__ */ new Map();
function _mount(Component, { target, anchor, props = {}, events, context, intro = true, transformError }) {
init_operations();
var component2 = void 0;
var unmount2 = component_root(() => {
var anchor_node = anchor ?? target.appendChild(create_text());
boundary(
/** @type {TemplateNode} */
anchor_node,
{
pending: () => {
}
},
(anchor_node2) => {
push({});
var ctx = (
/** @type {ComponentContext} */
component_context
);
if (context) ctx.c = context;
if (events) {
props.$$events = events;
}
if (hydrating) {
assign_nodes(
/** @type {TemplateNode} */
anchor_node2,
null
);
}
should_intro = intro;
component2 = Component(anchor_node2, props) || {};
should_intro = true;
if (hydrating) {
active_effect.nodes.end = hydrate_node;
if (hydrate_node === null || hydrate_node.nodeType !== COMMENT_NODE || /** @type {Comment} */
hydrate_node.data !== HYDRATION_END) {
hydration_mismatch();
throw HYDRATION_ERROR;
}
}
pop();
},
transformError
);
var registered_events = /* @__PURE__ */ new Set();
var event_handle = (events2) => {
for (var i = 0; i < events2.length; i++) {
var event_name = events2[i];
if (registered_events.has(event_name)) continue;
registered_events.add(event_name);
var passive2 = is_passive_event(event_name);
for (const node of [target, document]) {
var counts = listeners.get(node);
if (counts === void 0) {
counts = /* @__PURE__ */ new Map();
listeners.set(node, counts);
}
var count = counts.get(event_name);
if (count === void 0) {
node.addEventListener(event_name, handle_event_propagation, { passive: passive2 });
counts.set(event_name, 1);
} else {
counts.set(event_name, count + 1);
}
}
}
};
event_handle(array_from(all_registered_events));
root_event_handles.add(event_handle);
return () => {
for (var event_name of registered_events) {
for (const node of [target, document]) {
var counts = (
/** @type {Map<string, number>} */
listeners.get(node)
);
var count = (
/** @type {number} */
counts.get(event_name)
);
if (--count == 0) {
node.removeEventListener(event_name, handle_event_propagation);
counts.delete(event_name);
if (counts.size === 0) {
listeners.delete(node);
}
} else {
counts.set(event_name, count);
}
}
}
root_event_handles.delete(event_handle);
if (anchor_node !== anchor) {
anchor_node.parentNode?.removeChild(anchor_node);
}
};
});
mounted_components.set(component2, unmount2);
return component2;
}
var mounted_components = /* @__PURE__ */ new WeakMap();
function unmount(component2, options) {
const fn = mounted_components.get(component2);
if (fn) {
mounted_components.delete(component2);
return fn(options);
}
if (dev_fallback_default) {
if (STATE_SYMBOL in component2) {
state_proxy_unmount();
} else {
lifecycle_double_unmount();
}
}
return Promise.resolve();
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/blocks/branches.js
var _batches, _onscreen, _offscreen, _outroing, _transition, _commit, _discard;
var BranchManager = class {
/**
* @param {TemplateNode} anchor
* @param {boolean} transition
*/
constructor(anchor, transition2 = true) {
/** @type {TemplateNode} */
__publicField(this, "anchor");
/** @type {Map<Batch, Key>} */
__privateAdd(this, _batches, /* @__PURE__ */ new Map());
/**
* Map of keys to effects that are currently rendered in the DOM.
* These effects are visible and actively part of the document tree.
* Example:
* ```
* {#if condition}
* foo
* {:else}
* bar
* {/if}
* ```
* Can result in the entries `true->Effect` and `false->Effect`
* @type {Map<Key, Effect>}
*/
__privateAdd(this, _onscreen, /* @__PURE__ */ new Map());
/**
* Similar to #onscreen with respect to the keys, but contains branches that are not yet
* in the DOM, because their insertion is deferred.
* @type {Map<Key, Branch>}
*/
__privateAdd(this, _offscreen, /* @__PURE__ */ new Map());
/**
* Keys of effects that are currently outroing
* @type {Set<Key>}
*/
__privateAdd(this, _outroing, /* @__PURE__ */ new Set());
/**
* Whether to pause (i.e. outro) on change, or destroy immediately.
* This is necessary for `<svelte:element>`
*/
__privateAdd(this, _transition, true);
/**
* @param {Batch} batch
*/
__privateAdd(this, _commit, (batch) => {
if (!__privateGet(this, _batches).has(batch)) return;
var key2 = (
/** @type {Key} */
__privateGet(this, _batches).get(batch)
);
var onscreen = __privateGet(this, _onscreen).get(key2);
if (onscreen) {
resume_effect(onscreen);
__privateGet(this, _outroing).delete(key2);
} else {
var offscreen = __privateGet(this, _offscreen).get(key2);
if (offscreen) {
resume_effect(offscreen.effect);
__privateGet(this, _onscreen).set(key2, offscreen.effect);
__privateGet(this, _offscreen).delete(key2);
if (dev_fallback_default) {
offscreen.fragment.lastChild[HMR_ANCHOR] = this.anchor;
}
offscreen.fragment.lastChild.remove();
this.anchor.before(offscreen.fragment);
onscreen = offscreen.effect;
}
}
for (const [b, k] of __privateGet(this, _batches)) {
__privateGet(this, _batches).delete(b);
if (b === batch) {
break;
}
const offscreen2 = __privateGet(this, _offscreen).get(k);
if (offscreen2) {
destroy_effect(offscreen2.effect);
__privateGet(this, _offscreen).delete(k);
}
}
for (const [k, effect2] of __privateGet(this, _onscreen)) {
if (k === key2 || __privateGet(this, _outroing).has(k)) continue;
const on_destroy = () => {
const keys = Array.from(__privateGet(this, _batches).values());
if (keys.includes(k)) {
var fragment = document.createDocumentFragment();
move_effect(effect2, fragment);
fragment.append(create_text());
__privateGet(this, _offscreen).set(k, { effect: effect2, fragment });
} else {
destroy_effect(effect2);
}
__privateGet(this, _outroing).delete(k);
__privateGet(this, _onscreen).delete(k);
};
if (__privateGet(this, _transition) || !onscreen) {
__privateGet(this, _outroing).add(k);
pause_effect(effect2, on_destroy, false);
} else {
on_destroy();
}
}
});
/**
* @param {Batch} batch
*/
__privateAdd(this, _discard, (batch) => {
__privateGet(this, _batches).delete(batch);
const keys = Array.from(__privateGet(this, _batches).values());
for (const [k, branch2] of __privateGet(this, _offscreen)) {
if (!keys.includes(k)) {
destroy_effect(branch2.effect);
__privateGet(this, _offscreen).delete(k);
}
}
});
this.anchor = anchor;
__privateSet(this, _transition, transition2);
}
/**
*
* @param {any} key
* @param {null | ((target: TemplateNode) => void)} fn
*/
ensure(key2, fn) {
var batch = (
/** @type {Batch} */
current_batch
);
var defer = should_defer_append();
if (fn && !__privateGet(this, _onscreen).has(key2) && !__privateGet(this, _offscreen).has(key2)) {
if (defer) {
var fragment = document.createDocumentFragment();
var target = create_text();
fragment.append(target);
__privateGet(this, _offscreen).set(key2, {
effect: branch(() => fn(target)),
fragment
});
} else {
__privateGet(this, _onscreen).set(
key2,
branch(() => fn(this.anchor))
);
}
}
__privateGet(this, _batches).set(batch, key2);
if (defer) {
for (const [k, effect2] of __privateGet(this, _onscreen)) {
if (k === key2) {
batch.unskip_effect(effect2);
} else {
batch.skip_effect(effect2);
}
}
for (const [k, branch2] of __privateGet(this, _offscreen)) {
if (k === key2) {
batch.unskip_effect(branch2.effect);
} else {
batch.skip_effect(branch2.effect);
}
}
batch.oncommit(__privateGet(this, _commit));
batch.ondiscard(__privateGet(this, _discard));
} else {
if (hydrating) {
this.anchor = hydrate_node;
}
__privateGet(this, _commit).call(this, batch);
}
}
};
_batches = new WeakMap();
_onscreen = new WeakMap();
_offscreen = new WeakMap();
_outroing = new WeakMap();
_transition = new WeakMap();
_commit = new WeakMap();
_discard = new WeakMap();
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/index-client.js
if (dev_fallback_default) {
let throw_rune_error = function(rune) {
if (!(rune in globalThis)) {
let value;
Object.defineProperty(globalThis, rune, {
configurable: true,
// eslint-disable-next-line getter-return
get: () => {
if (value !== void 0) {
return value;
}
rune_outside_svelte(rune);
},
set: (v) => {
value = v;
}
});
}
};
throw_rune_error("$state");
throw_rune_error("$effect");
throw_rune_error("$derived");
throw_rune_error("$inspect");
throw_rune_error("$props");
throw_rune_error("$bindable");
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dev/css.js
var all_styles = /* @__PURE__ */ new Map();
function register_style(hash2, style) {
var styles = all_styles.get(hash2);
if (!styles) {
styles = /* @__PURE__ */ new Set();
all_styles.set(hash2, styles);
}
styles.add(style);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/blocks/if.js
function if_block(node, fn, elseif = false) {
var marker;
if (hydrating) {
marker = hydrate_node;
hydrate_next();
}
var branches = new BranchManager(node);
var flags2 = elseif ? EFFECT_TRANSPARENT : 0;
function update_branch(key2, fn2) {
if (hydrating) {
var data = read_hydration_instruction(
/** @type {TemplateNode} */
marker
);
if (key2 !== parseInt(data.substring(1))) {
var anchor = skip_nodes();
set_hydrate_node(anchor);
branches.anchor = anchor;
set_hydrating(false);
branches.ensure(key2, fn2);
set_hydrating(true);
return;
}
}
branches.ensure(key2, fn2);
}
block(() => {
var has_branch = false;
fn((fn2, key2 = 0) => {
has_branch = true;
update_branch(key2, fn2);
});
if (!has_branch) {
update_branch(-1, null);
}
}, flags2);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/blocks/each.js
function pause_effects(state2, to_destroy, controlled_anchor) {
var transitions = [];
var length = to_destroy.length;
var group;
var remaining = to_destroy.length;
for (var i = 0; i < length; i++) {
let effect2 = to_destroy[i];
pause_effect(
effect2,
() => {
if (group) {
group.pending.delete(effect2);
group.done.add(effect2);
if (group.pending.size === 0) {
var groups = (
/** @type {Set<EachOutroGroup>} */
state2.outrogroups
);
destroy_effects(state2, array_from(group.done));
groups.delete(group);
if (groups.size === 0) {
state2.outrogroups = null;
}
}
} else {
remaining -= 1;
}
},
false
);
}
if (remaining === 0) {
var fast_path = transitions.length === 0 && controlled_anchor !== null;
if (fast_path) {
var anchor = (
/** @type {Element} */
controlled_anchor
);
var parent_node = (
/** @type {Element} */
anchor.parentNode
);
clear_text_content(parent_node);
parent_node.append(anchor);
state2.items.clear();
}
destroy_effects(state2, to_destroy, !fast_path);
} else {
group = {
pending: new Set(to_destroy),
done: /* @__PURE__ */ new Set()
};
(state2.outrogroups ?? (state2.outrogroups = /* @__PURE__ */ new Set())).add(group);
}
}
function destroy_effects(state2, to_destroy, remove_dom = true) {
var preserved_effects;
if (state2.pending.size > 0) {
preserved_effects = /* @__PURE__ */ new Set();
for (const keys of state2.pending.values()) {
for (const key2 of keys) {
preserved_effects.add(
/** @type {EachItem} */
state2.items.get(key2).e
);
}
}
}
for (var i = 0; i < to_destroy.length; i++) {
var e = to_destroy[i];
if (preserved_effects?.has(e)) {
e.f |= EFFECT_OFFSCREEN;
const fragment = document.createDocumentFragment();
move_effect(e, fragment);
} else {
destroy_effect(to_destroy[i], remove_dom);
}
}
}
var offscreen_anchor;
function each(node, flags2, get_collection, get_key, render_fn2, fallback_fn = null) {
var anchor = node;
var items = /* @__PURE__ */ new Map();
var is_controlled = (flags2 & EACH_IS_CONTROLLED) !== 0;
if (is_controlled) {
var parent_node = (
/** @type {Element} */
node
);
anchor = hydrating ? set_hydrate_node(get_first_child(parent_node)) : parent_node.appendChild(create_text());
}
if (hydrating) {
hydrate_next();
}
var fallback2 = null;
var each_array = derived_safe_equal(() => {
var collection = get_collection();
return (
/** @type {V[]} */
is_array(collection) ? collection : collection == null ? [] : array_from(collection)
);
});
if (dev_fallback_default) {
tag(each_array, "{#each ...}");
}
var array;
var pending3 = /* @__PURE__ */ new Map();
var first_run = true;
function commit(batch) {
if ((state2.effect.f & DESTROYED) !== 0) {
return;
}
state2.pending.delete(batch);
state2.fallback = fallback2;
reconcile(state2, array, anchor, flags2, get_key);
if (fallback2 !== null) {
if (array.length === 0) {
if ((fallback2.f & EFFECT_OFFSCREEN) === 0) {
resume_effect(fallback2);
} else {
fallback2.f ^= EFFECT_OFFSCREEN;
move(fallback2, null, anchor);
}
} else {
pause_effect(fallback2, () => {
fallback2 = null;
});
}
}
}
function discard(batch) {
state2.pending.delete(batch);
}
var effect2 = block(() => {
array = /** @type {V[]} */
get2(each_array);
var length = array.length;
let mismatch = false;
if (hydrating) {
var is_else = read_hydration_instruction(anchor) === HYDRATION_START_ELSE;
if (is_else !== (length === 0)) {
anchor = skip_nodes();
set_hydrate_node(anchor);
set_hydrating(false);
mismatch = true;
}
}
var keys = /* @__PURE__ */ new Set();
var batch = (
/** @type {Batch} */
current_batch
);
var defer = should_defer_append();
for (var index2 = 0; index2 < length; index2 += 1) {
if (hydrating && hydrate_node.nodeType === COMMENT_NODE && /** @type {Comment} */
hydrate_node.data === HYDRATION_END) {
anchor = /** @type {Comment} */
hydrate_node;
mismatch = true;
set_hydrating(false);
}
var value = array[index2];
var key2 = get_key(value, index2);
if (dev_fallback_default) {
var key_again = get_key(value, index2);
if (key2 !== key_again) {
each_key_volatile(String(index2), String(key2), String(key_again));
}
}
var item = first_run ? null : items.get(key2);
if (item) {
if (item.v) internal_set(item.v, value);
if (item.i) internal_set(item.i, index2);
if (defer) {
batch.unskip_effect(item.e);
}
} else {
item = create_item(
items,
first_run ? anchor : offscreen_anchor ?? (offscreen_anchor = create_text()),
value,
key2,
index2,
render_fn2,
flags2,
get_collection
);
if (!first_run) {
item.e.f |= EFFECT_OFFSCREEN;
}
items.set(key2, item);
}
keys.add(key2);
}
if (length === 0 && fallback_fn && !fallback2) {
if (first_run) {
fallback2 = branch(() => fallback_fn(anchor));
} else {
fallback2 = branch(() => fallback_fn(offscreen_anchor ?? (offscreen_anchor = create_text())));
fallback2.f |= EFFECT_OFFSCREEN;
}
}
if (length > keys.size) {
if (dev_fallback_default) {
validate_each_keys(array, get_key);
} else {
each_key_duplicate("", "", "");
}
}
if (hydrating && length > 0) {
set_hydrate_node(skip_nodes());
}
if (!first_run) {
pending3.set(batch, keys);
if (defer) {
for (const [key3, item2] of items) {
if (!keys.has(key3)) {
batch.skip_effect(item2.e);
}
}
batch.oncommit(commit);
batch.ondiscard(discard);
} else {
commit(batch);
}
}
if (mismatch) {
set_hydrating(true);
}
get2(each_array);
});
var state2 = { effect: effect2, flags: flags2, items, pending: pending3, outrogroups: null, fallback: fallback2 };
first_run = false;
if (hydrating) {
anchor = hydrate_node;
}
}
function skip_to_branch(effect2) {
while (effect2 !== null && (effect2.f & BRANCH_EFFECT) === 0) {
effect2 = effect2.next;
}
return effect2;
}
function reconcile(state2, array, anchor, flags2, get_key) {
var is_animated = (flags2 & EACH_IS_ANIMATED) !== 0;
var length = array.length;
var items = state2.items;
var current = skip_to_branch(state2.effect.first);
var seen;
var prev = null;
var to_animate;
var matched = [];
var stashed = [];
var value;
var key2;
var effect2;
var i;
if (is_animated) {
for (i = 0; i < length; i += 1) {
value = array[i];
key2 = get_key(value, i);
effect2 = /** @type {EachItem} */
items.get(key2).e;
if ((effect2.f & EFFECT_OFFSCREEN) === 0) {
effect2.nodes?.a?.measure();
(to_animate ?? (to_animate = /* @__PURE__ */ new Set())).add(effect2);
}
}
}
for (i = 0; i < length; i += 1) {
value = array[i];
key2 = get_key(value, i);
effect2 = /** @type {EachItem} */
items.get(key2).e;
if (state2.outrogroups !== null) {
for (const group of state2.outrogroups) {
group.pending.delete(effect2);
group.done.delete(effect2);
}
}
if ((effect2.f & INERT) !== 0) {
resume_effect(effect2);
if (is_animated) {
effect2.nodes?.a?.unfix();
(to_animate ?? (to_animate = /* @__PURE__ */ new Set())).delete(effect2);
}
}
if ((effect2.f & EFFECT_OFFSCREEN) !== 0) {
effect2.f ^= EFFECT_OFFSCREEN;
if (effect2 === current) {
move(effect2, null, anchor);
} else {
var next2 = prev ? prev.next : current;
if (effect2 === state2.effect.last) {
state2.effect.last = effect2.prev;
}
if (effect2.prev) effect2.prev.next = effect2.next;
if (effect2.next) effect2.next.prev = effect2.prev;
link(state2, prev, effect2);
link(state2, effect2, next2);
move(effect2, next2, anchor);
prev = effect2;
matched = [];
stashed = [];
current = skip_to_branch(prev.next);
continue;
}
}
if (effect2 !== current) {
if (seen !== void 0 && seen.has(effect2)) {
if (matched.length < stashed.length) {
var start = stashed[0];
var j;
prev = start.prev;
var a = matched[0];
var b = matched[matched.length - 1];
for (j = 0; j < matched.length; j += 1) {
move(matched[j], start, anchor);
}
for (j = 0; j < stashed.length; j += 1) {
seen.delete(stashed[j]);
}
link(state2, a.prev, b.next);
link(state2, prev, a);
link(state2, b, start);
current = start;
prev = b;
i -= 1;
matched = [];
stashed = [];
} else {
seen.delete(effect2);
move(effect2, current, anchor);
link(state2, effect2.prev, effect2.next);
link(state2, effect2, prev === null ? state2.effect.first : prev.next);
link(state2, prev, effect2);
prev = effect2;
}
continue;
}
matched = [];
stashed = [];
while (current !== null && current !== effect2) {
(seen ?? (seen = /* @__PURE__ */ new Set())).add(current);
stashed.push(current);
current = skip_to_branch(current.next);
}
if (current === null) {
continue;
}
}
if ((effect2.f & EFFECT_OFFSCREEN) === 0) {
matched.push(effect2);
}
prev = effect2;
current = skip_to_branch(effect2.next);
}
if (state2.outrogroups !== null) {
for (const group of state2.outrogroups) {
if (group.pending.size === 0) {
destroy_effects(state2, array_from(group.done));
state2.outrogroups?.delete(group);
}
}
if (state2.outrogroups.size === 0) {
state2.outrogroups = null;
}
}
if (current !== null || seen !== void 0) {
var to_destroy = [];
if (seen !== void 0) {
for (effect2 of seen) {
if ((effect2.f & INERT) === 0) {
to_destroy.push(effect2);
}
}
}
while (current !== null) {
if ((current.f & INERT) === 0 && current !== state2.fallback) {
to_destroy.push(current);
}
current = skip_to_branch(current.next);
}
var destroy_length = to_destroy.length;
if (destroy_length > 0) {
var controlled_anchor = (flags2 & EACH_IS_CONTROLLED) !== 0 && length === 0 ? anchor : null;
if (is_animated) {
for (i = 0; i < destroy_length; i += 1) {
to_destroy[i].nodes?.a?.measure();
}
for (i = 0; i < destroy_length; i += 1) {
to_destroy[i].nodes?.a?.fix();
}
}
pause_effects(state2, to_destroy, controlled_anchor);
}
}
if (is_animated) {
queue_micro_task(() => {
if (to_animate === void 0) return;
for (effect2 of to_animate) {
effect2.nodes?.a?.apply();
}
});
}
}
function create_item(items, anchor, value, key2, index2, render_fn2, flags2, get_collection) {
var v = (flags2 & EACH_ITEM_REACTIVE) !== 0 ? (flags2 & EACH_ITEM_IMMUTABLE) === 0 ? mutable_source(value, false, false) : source(value) : null;
var i = (flags2 & EACH_INDEX_REACTIVE) !== 0 ? source(index2) : null;
if (dev_fallback_default && v) {
v.trace = () => {
get_collection()[i?.v ?? index2];
};
}
return {
v,
i,
e: branch(() => {
render_fn2(anchor, v ?? value, i ?? index2, get_collection);
return () => {
items.delete(key2);
};
})
};
}
function move(effect2, next2, anchor) {
if (!effect2.nodes) return;
var node = effect2.nodes.start;
var end = effect2.nodes.end;
var dest = next2 && (next2.f & EFFECT_OFFSCREEN) === 0 ? (
/** @type {EffectNodes} */
next2.nodes.start
) : anchor;
while (node !== null) {
var next_node = (
/** @type {TemplateNode} */
get_next_sibling(node)
);
dest.before(node);
if (node === end) {
return;
}
node = next_node;
}
}
function link(state2, prev, next2) {
if (prev === null) {
state2.effect.first = next2;
} else {
prev.next = next2;
}
if (next2 === null) {
state2.effect.last = prev;
} else {
next2.prev = prev;
}
}
function validate_each_keys(array, key_fn) {
const keys = /* @__PURE__ */ new Map();
const length = array.length;
for (let i = 0; i < length; i++) {
const key2 = key_fn(array[i], i);
if (keys.has(key2)) {
const a = String(keys.get(key2));
const b = String(i);
let k = String(key2);
if (k.startsWith("[object ")) k = null;
each_key_duplicate(a, b, k);
}
keys.set(key2, i);
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/css.js
function append_styles(anchor, css) {
effect(() => {
var root7 = anchor.getRootNode();
var target = (
/** @type {ShadowRoot} */
root7.host ? (
/** @type {ShadowRoot} */
root7
) : (
/** @type {Document} */
root7.head ?? /** @type {Document} */
root7.ownerDocument.head
)
);
if (!target.querySelector("#" + css.hash)) {
const style = create_element("style");
style.id = css.hash;
style.textContent = css.code;
target.appendChild(style);
if (dev_fallback_default) {
register_style(css.hash, style);
}
}
});
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/actions.js
function action(dom, action2, get_value) {
effect(() => {
var payload = untrack(() => action2(dom, get_value?.()) || {});
if (get_value && payload?.update) {
var inited = false;
var prev = (
/** @type {any} */
{}
);
render_effect(() => {
var value = get_value();
deep_read_state(value);
if (inited && safe_not_equal(prev, value)) {
prev = value;
payload.update(value);
}
});
inited = true;
}
if (payload?.destroy) {
return () => (
/** @type {Function} */
payload.destroy()
);
}
});
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/shared/attributes.js
var whitespace = [..." \n\r\f\xA0\v\uFEFF"];
function to_class(value, hash2, directives) {
var classname = value == null ? "" : "" + value;
if (hash2) {
classname = classname ? classname + " " + hash2 : hash2;
}
if (directives) {
for (var key2 of Object.keys(directives)) {
if (directives[key2]) {
classname = classname ? classname + " " + key2 : key2;
} else if (classname.length) {
var len = key2.length;
var a = 0;
while ((a = classname.indexOf(key2, a)) >= 0) {
var b = a + len;
if ((a === 0 || whitespace.includes(classname[a - 1])) && (b === classname.length || whitespace.includes(classname[b]))) {
classname = (a === 0 ? "" : classname.substring(0, a)) + classname.substring(b + 1);
} else {
a = b;
}
}
}
}
}
return classname === "" ? null : classname;
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/class.js
function set_class(dom, is_html, value, hash2, prev_classes, next_classes) {
var prev = (
/** @type {any} */
dom[CLASS_CACHE]
);
if (hydrating || prev !== value || prev === void 0) {
var next_class_name = to_class(value, hash2, next_classes);
if (!hydrating || next_class_name !== dom.getAttribute("class")) {
if (next_class_name == null) {
dom.removeAttribute("class");
} else if (is_html) {
dom.className = next_class_name;
} else {
dom.setAttribute("class", next_class_name);
}
}
dom[CLASS_CACHE] = value;
} else if (next_classes && prev_classes !== next_classes) {
for (var key2 in next_classes) {
var is_present = !!next_classes[key2];
if (prev_classes == null || is_present !== !!prev_classes[key2]) {
dom.classList.toggle(key2, is_present);
}
}
}
return next_classes;
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/bindings/select.js
function select_option(select, value, mounting = false) {
if (select.multiple) {
if (value == void 0) {
return;
}
if (!is_array(value)) {
return select_multiple_invalid_value();
}
for (var option of select.options) {
option.selected = value.includes(get_option_value(option));
}
return;
}
for (option of select.options) {
var option_value = get_option_value(option);
if (is(option_value, value)) {
option.selected = true;
return;
}
}
if (!mounting || value !== void 0) {
select.selectedIndex = -1;
}
}
function init_select(select) {
var observer = new MutationObserver(() => {
select_option(select, select.__value);
});
observer.observe(select, {
// Listen to option element changes
childList: true,
subtree: true,
// because of <optgroup>
// Listen to option element value attribute changes
// (doesn't get notified of select value changes,
// because that property is not reflected as an attribute)
attributes: true,
attributeFilter: ["value"]
});
teardown(() => {
observer.disconnect();
});
}
function bind_select_value(select, get3, set2 = get3) {
var batches = /* @__PURE__ */ new WeakSet();
var mounting = true;
listen_to_event_and_reset_event(select, "change", (is_reset) => {
var query = is_reset ? "[selected]" : ":checked";
var value;
if (select.multiple) {
value = [].map.call(select.querySelectorAll(query), get_option_value);
} else {
var selected_option = select.querySelector(query) ?? // will fall back to first non-disabled option if no option is selected
select.querySelector("option:not([disabled])");
value = selected_option && get_option_value(selected_option);
}
set2(value);
select.__value = value;
if (current_batch !== null) {
batches.add(current_batch);
}
});
effect(() => {
var value = get3();
if (select === document.activeElement) {
var batch = (
/** @type {Batch} */
async_mode_flag ? previous_batch : current_batch
);
if (batches.has(batch)) {
return;
}
}
select_option(select, value, mounting);
if (mounting && value === void 0) {
var selected_option = select.querySelector(":checked");
if (selected_option !== null) {
value = get_option_value(selected_option);
set2(value);
}
}
select.__value = value;
mounting = false;
});
init_select(select);
}
function get_option_value(option) {
if ("__value" in option) {
return option.__value;
} else {
return option.value;
}
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/attributes.js
var IS_CUSTOM_ELEMENT = /* @__PURE__ */ Symbol("is custom element");
var IS_HTML = /* @__PURE__ */ Symbol("is html");
var LINK_TAG = IS_XHTML ? "link" : "LINK";
var PROGRESS_TAG = IS_XHTML ? "progress" : "PROGRESS";
function remove_input_defaults(input) {
if (!hydrating) return;
var already_removed = false;
var remove_defaults = () => {
if (already_removed) return;
already_removed = true;
if (input.hasAttribute("value")) {
var value = input.value;
set_attribute2(input, "value", null);
input.value = value;
}
if (input.hasAttribute("checked")) {
var checked = input.checked;
set_attribute2(input, "checked", null);
input.checked = checked;
}
};
input[FORM_RESET_HANDLER] = remove_defaults;
queue_micro_task(remove_defaults);
add_form_reset_listener();
}
function set_value(element2, value) {
var attributes = get_attributes(element2);
if (attributes.value === (attributes.value = // treat null and undefined the same for the initial value
value ?? void 0) || // @ts-expect-error
// `progress` elements always need their value set when it's `0`
element2.value === value && (value !== 0 || element2.nodeName !== PROGRESS_TAG)) {
return;
}
element2.value = value ?? "";
}
function set_checked(element2, checked) {
var attributes = get_attributes(element2);
if (attributes.checked === (attributes.checked = // treat null and undefined the same for the initial value
checked ?? void 0)) {
return;
}
element2.checked = checked;
}
function set_selected(element2, selected) {
if (selected) {
if (!element2.hasAttribute("selected")) {
element2.setAttribute("selected", "");
}
} else {
element2.removeAttribute("selected");
}
}
function set_attribute2(element2, attribute, value, skip_warning) {
var attributes = get_attributes(element2);
if (hydrating) {
attributes[attribute] = element2.getAttribute(attribute);
if (attribute === "src" || attribute === "srcset" || attribute === "href" && element2.nodeName === LINK_TAG) {
if (!skip_warning) {
check_src_in_dev_hydration(element2, attribute, value ?? "");
}
return;
}
}
if (attributes[attribute] === (attributes[attribute] = value)) return;
if (attribute === "loading") {
element2[LOADING_ATTR_SYMBOL] = value;
}
if (value == null) {
element2.removeAttribute(attribute);
} else if (typeof value !== "string" && get_setters(element2).includes(attribute)) {
element2[attribute] = value;
} else {
element2.setAttribute(attribute, value);
}
}
function get_attributes(element2) {
var _a2;
return (
/** @type {Record<string | symbol, unknown>} **/
/** @type {any} */
element2[_a2 = ATTRIBUTES_CACHE] ?? (element2[_a2] = {
[IS_CUSTOM_ELEMENT]: element2.nodeName.includes("-"),
[IS_HTML]: element2.namespaceURI === NAMESPACE_HTML
})
);
}
var setters_cache = /* @__PURE__ */ new Map();
function get_setters(element2) {
var cache_key = element2.getAttribute("is") || element2.nodeName;
var setters = setters_cache.get(cache_key);
if (setters) return setters;
setters_cache.set(cache_key, setters = []);
var descriptors;
var proto = element2;
var element_proto = Element.prototype;
while (element_proto !== proto) {
descriptors = get_descriptors(proto);
for (var key2 in descriptors) {
if (descriptors[key2].set && // better safe than sorry, we don't want spread attributes to mess with HTML content
key2 !== "innerHTML" && key2 !== "textContent" && key2 !== "innerText") {
setters.push(key2);
}
}
proto = get_prototype_of(proto);
}
return setters;
}
function check_src_in_dev_hydration(element2, attribute, value) {
if (!dev_fallback_default) return;
if (attribute === "srcset" && srcset_url_equal(element2, value)) return;
if (src_url_equal(element2.getAttribute(attribute) ?? "", value)) return;
hydration_attribute_changed(
attribute,
element2.outerHTML.replace(element2.innerHTML, element2.innerHTML && "..."),
String(value)
);
}
function src_url_equal(element_src, url) {
if (element_src === url) return true;
return new URL(element_src, document.baseURI).href === new URL(url, document.baseURI).href;
}
function split_srcset(srcset) {
return srcset.split(",").map((src) => src.trim().split(" ").filter(Boolean));
}
function srcset_url_equal(element2, srcset) {
var element_urls = split_srcset(element2.srcset);
var urls = split_srcset(srcset);
return urls.length === element_urls.length && urls.every(
([url, width], i) => width === element_urls[i][1] && // We need to test both ways because Vite will create an a full URL with
// `new URL(asset, import.meta.url).href` for the client when `base: './'`, and the
// relative URLs inside srcset are not automatically resolved to absolute URLs by
// browsers (in contrast to img.src). This means both SSR and DOM code could
// contain relative or absolute URLs.
(src_url_equal(element_urls[i][0], url) || src_url_equal(url, element_urls[i][0]))
);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/bindings/input.js
function bind_value(input, get3, set2 = get3) {
var batches = /* @__PURE__ */ new WeakSet();
listen_to_event_and_reset_event(input, "input", async (is_reset) => {
if (dev_fallback_default && input.type === "checkbox") {
bind_invalid_checkbox_value();
}
var value = is_reset ? input.defaultValue : input.value;
value = is_numberlike_input(input) ? to_number(value) : value;
set2(value);
if (current_batch !== null) {
batches.add(current_batch);
}
await tick();
if (value !== (value = get3())) {
var start = input.selectionStart;
var end = input.selectionEnd;
var length = input.value.length;
input.value = value ?? "";
if (end !== null) {
var new_length = input.value.length;
if (start === end && end === length && new_length > length) {
input.selectionStart = new_length;
input.selectionEnd = new_length;
} else {
input.selectionStart = start;
input.selectionEnd = Math.min(end, new_length);
}
}
}
});
if (
// If we are hydrating and the value has since changed,
// then use the updated value from the input instead.
hydrating && input.defaultValue !== input.value || // If defaultValue is set, then value == defaultValue
// TODO Svelte 6: remove input.value check and set to empty string?
untrack(get3) == null && input.value
) {
set2(is_numberlike_input(input) ? to_number(input.value) : input.value);
if (current_batch !== null) {
batches.add(current_batch);
}
}
render_effect(() => {
if (dev_fallback_default && input.type === "checkbox") {
bind_invalid_checkbox_value();
}
var value = get3();
if (input === document.activeElement) {
var batch = (
/** @type {Batch} */
async_mode_flag ? previous_batch : current_batch
);
if (batches.has(batch)) {
return;
}
}
if (is_numberlike_input(input) && value === to_number(input.value)) {
return;
}
if (input.type === "date" && !value && !input.value) {
return;
}
if (value !== input.value) {
input.value = value ?? "";
}
});
}
function bind_checked(input, get3, set2 = get3) {
listen_to_event_and_reset_event(input, "change", (is_reset) => {
var value = is_reset ? input.defaultChecked : input.checked;
set2(value);
});
if (
// If we are hydrating and the value has since changed,
// then use the update value from the input instead.
hydrating && input.defaultChecked !== input.checked || // If defaultChecked is set, then checked == defaultChecked
untrack(get3) == null
) {
set2(input.checked);
}
render_effect(() => {
var value = get3();
input.checked = Boolean(value);
});
}
function is_numberlike_input(input) {
var type = input.type;
return type === "number" || type === "range";
}
function to_number(value) {
return value === "" ? null : +value;
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/bindings/this.js
function is_bound_this(bound_value, element_or_component) {
return bound_value === element_or_component || bound_value?.[STATE_SYMBOL] === element_or_component;
}
function bind_this(element_or_component = {}, update2, get_value, get_parts) {
var component_effect = (
/** @type {ComponentContext} */
component_context.r
);
var parent = (
/** @type {Effect} */
active_effect
);
effect(() => {
var old_parts;
var parts;
render_effect(() => {
old_parts = parts;
parts = get_parts?.() || [];
untrack(() => {
if (!is_bound_this(get_value(...parts), element_or_component)) {
update2(element_or_component, ...parts);
if (old_parts && is_bound_this(get_value(...old_parts), element_or_component)) {
update2(null, ...old_parts);
}
}
});
});
return () => {
let p = parent;
while (p !== component_effect && p.parent !== null && p.parent.f & DESTROYING) {
p = p.parent;
}
const teardown2 = () => {
if (parts && is_bound_this(get_value(...parts), element_or_component)) {
update2(null, ...parts);
}
};
const original_teardown = p.teardown;
p.teardown = () => {
teardown2();
original_teardown?.();
};
};
});
return element_or_component;
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/reactivity/props.js
function prop(props, key2, flags2, fallback2) {
var runes = !legacy_mode_flag || (flags2 & PROPS_IS_RUNES) !== 0;
var bindable = (flags2 & PROPS_IS_BINDABLE) !== 0;
var lazy = (flags2 & PROPS_IS_LAZY_INITIAL) !== 0;
var fallback_value = (
/** @type {V} */
fallback2
);
var fallback_dirty = true;
var fallback_signal = (
/** @type {Derived<V> | undefined} */
void 0
);
var get_fallback = () => {
if (lazy && runes) {
fallback_signal ?? (fallback_signal = derived(
/** @type {() => V} */
fallback2
));
return get2(fallback_signal);
}
if (fallback_dirty) {
fallback_dirty = false;
fallback_value = lazy ? untrack(
/** @type {() => V} */
fallback2
) : (
/** @type {V} */
fallback2
);
}
return fallback_value;
};
let setter;
if (bindable) {
var is_entry_props = STATE_SYMBOL in props || LEGACY_PROPS in props;
setter = get_descriptor(props, key2)?.set ?? (is_entry_props && key2 in props ? (v) => props[key2] = v : void 0);
}
var initial_value;
var is_store_sub = false;
if (bindable) {
[initial_value, is_store_sub] = capture_store_binding(() => (
/** @type {V} */
props[key2]
));
} else {
initial_value = /** @type {V} */
props[key2];
}
if (initial_value === void 0 && fallback2 !== void 0) {
initial_value = get_fallback();
if (setter) {
if (runes) props_invalid_value(key2);
setter(initial_value);
}
}
var getter;
if (runes) {
getter = () => {
var value = (
/** @type {V} */
props[key2]
);
if (value === void 0) return get_fallback();
fallback_dirty = true;
return value;
};
} else {
getter = () => {
var value = (
/** @type {V} */
props[key2]
);
if (value !== void 0) {
fallback_value = /** @type {V} */
void 0;
}
return value === void 0 ? fallback_value : value;
};
}
if (runes && (flags2 & PROPS_IS_UPDATED) === 0) {
return getter;
}
if (setter) {
var legacy_parent = props.$$legacy;
return (
/** @type {() => V} */
(function(value, mutation) {
if (arguments.length > 0) {
if (!runes || !mutation || legacy_parent || is_store_sub) {
setter(mutation ? getter() : value);
}
return value;
}
return getter();
})
);
}
var overridden = false;
var d = ((flags2 & PROPS_IS_IMMUTABLE) !== 0 ? derived : derived_safe_equal)(() => {
overridden = false;
return getter();
});
if (dev_fallback_default) {
d.label = key2;
}
if (bindable) get2(d);
var parent_effect = (
/** @type {Effect} */
active_effect
);
return (
/** @type {() => V} */
(function(value, mutation) {
if (arguments.length > 0) {
const new_value = mutation ? get2(d) : runes && bindable ? proxy(value) : value;
set(d, new_value);
overridden = true;
if (fallback_value !== void 0) {
fallback_value = new_value;
}
return value;
}
if (is_destroying_effect && overridden || (parent_effect.f & DESTROYED) !== 0) {
return d.v;
}
return get2(d);
})
);
}
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/legacy/legacy-client.js
function createClassComponent(options) {
return new Svelte4Component(options);
}
var _events, _instance;
var Svelte4Component = class {
/**
* @param {ComponentConstructorOptions & {
* component: any;
* }} options
*/
constructor(options) {
/** @type {any} */
__privateAdd(this, _events);
/** @type {Record<string, any>} */
__privateAdd(this, _instance);
var sources = /* @__PURE__ */ new Map();
var add_source = (key2, value) => {
var s = mutable_source(value, false, false);
sources.set(key2, s);
return s;
};
const props = new Proxy(
{ ...options.props || {}, $$events: {} },
{
get(target, prop2) {
return get2(sources.get(prop2) ?? add_source(prop2, Reflect.get(target, prop2)));
},
has(target, prop2) {
if (prop2 === LEGACY_PROPS) return true;
get2(sources.get(prop2) ?? add_source(prop2, Reflect.get(target, prop2)));
return Reflect.has(target, prop2);
},
set(target, prop2, value) {
set(sources.get(prop2) ?? add_source(prop2, value), value);
return Reflect.set(target, prop2, value);
}
}
);
__privateSet(this, _instance, (options.hydrate ? hydrate : mount)(options.component, {
target: options.target,
anchor: options.anchor,
props,
context: options.context,
intro: options.intro ?? false,
recover: options.recover,
transformError: options.transformError
}));
if (!async_mode_flag && (!options?.props?.$$host || options.sync === false)) {
flushSync();
}
__privateSet(this, _events, props.$$events);
for (const key2 of Object.keys(__privateGet(this, _instance))) {
if (key2 === "$set" || key2 === "$destroy" || key2 === "$on") continue;
define_property(this, key2, {
get() {
return __privateGet(this, _instance)[key2];
},
/** @param {any} value */
set(value) {
__privateGet(this, _instance)[key2] = value;
},
enumerable: true
});
}
__privateGet(this, _instance).$set = /** @param {Record<string, any>} next */
(next2) => {
Object.assign(props, next2);
};
__privateGet(this, _instance).$destroy = () => {
unmount(__privateGet(this, _instance));
};
}
/** @param {Record<string, any>} props */
$set(props) {
__privateGet(this, _instance).$set(props);
}
/**
* @param {string} event
* @param {(...args: any[]) => any} callback
* @returns {any}
*/
$on(event2, callback) {
__privateGet(this, _events)[event2] = __privateGet(this, _events)[event2] || [];
const cb = (...args) => callback.call(this, ...args);
__privateGet(this, _events)[event2].push(cb);
return () => {
__privateGet(this, _events)[event2] = __privateGet(this, _events)[event2].filter(
/** @param {any} fn */
(fn) => fn !== cb
);
};
}
$destroy() {
__privateGet(this, _instance).$destroy();
}
};
_events = new WeakMap();
_instance = new WeakMap();
// node_modules/.pnpm/svelte@5.56.4_@typescript-eslint+types@8.62.0/node_modules/svelte/src/internal/client/dom/elements/custom-element.js
var SvelteElement;
if (typeof HTMLElement === "function") {
SvelteElement = class extends HTMLElement {
/**
* @param {*} $$componentCtor
* @param {*} $$slots
* @param {ShadowRootInit | undefined} shadow_root_init
*/
constructor($$componentCtor, $$slots, shadow_root_init) {
super();
/** The Svelte component constructor */
__publicField(this, "$$ctor");
/** Slots */
__publicField(this, "$$s");
/** @type {any} The Svelte component instance */
__publicField(this, "$$c");
/** Whether or not the custom element is connected */
__publicField(this, "$$cn", false);
/** @type {Record<string, any>} Component props data */
__publicField(this, "$$d", {});
/** `true` if currently in the process of reflecting component props back to attributes */
__publicField(this, "$$r", false);
/** @type {Record<string, CustomElementPropDefinition>} Props definition (name, reflected, type etc) */
__publicField(this, "$$p_d", {});
/** @type {Record<string, EventListenerOrEventListenerObject[]>} Event listeners */
__publicField(this, "$$l", {});
/** @type {Map<EventListenerOrEventListenerObject, Function>} Event listener unsubscribe functions */
__publicField(this, "$$l_u", /* @__PURE__ */ new Map());
/** @type {any} The managed render effect for reflecting attributes */
__publicField(this, "$$me");
/** @type {ShadowRoot | null} The ShadowRoot of the custom element */
__publicField(this, "$$shadowRoot", null);
this.$$ctor = $$componentCtor;
this.$$s = $$slots;
if (shadow_root_init) {
this.$$shadowRoot = this.attachShadow(shadow_root_init);
}
}
/**
* @param {string} type
* @param {EventListenerOrEventListenerObject} listener
* @param {boolean | AddEventListenerOptions} [options]
*/
addEventListener(type, listener, options) {
this.$$l[type] = this.$$l[type] || [];
this.$$l[type].push(listener);
if (this.$$c) {
const unsub = this.$$c.$on(type, listener);
this.$$l_u.set(listener, unsub);
}
super.addEventListener(type, listener, options);
}
/**
* @param {string} type
* @param {EventListenerOrEventListenerObject} listener
* @param {boolean | AddEventListenerOptions} [options]
*/
removeEventListener(type, listener, options) {
super.removeEventListener(type, listener, options);
if (this.$$c) {
const unsub = this.$$l_u.get(listener);
if (unsub) {
unsub();
this.$$l_u.delete(listener);
}
}
}
async connectedCallback() {
this.$$cn = true;
if (!this.$$c) {
let create_slot = function(name) {
return (anchor) => {
const slot2 = create_element("slot");
if (name !== "default") slot2.name = name;
append(anchor, slot2);
};
};
await Promise.resolve();
if (!this.$$cn || this.$$c) {
return;
}
const $$slots = {};
const existing_slots = get_custom_elements_slots(this);
for (const name of this.$$s) {
if (name in existing_slots) {
if (name === "default" && !this.$$d.children) {
this.$$d.children = create_slot(name);
$$slots.default = true;
} else {
$$slots[name] = create_slot(name);
}
}
}
for (const attribute of this.attributes) {
const name = this.$$g_p(attribute.name);
if (!(name in this.$$d)) {
this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, "toProp");
}
}
for (const key2 in this.$$p_d) {
if (!(key2 in this.$$d) && this[key2] !== void 0) {
this.$$d[key2] = this[key2];
delete this[key2];
}
}
this.$$c = createClassComponent({
component: this.$$ctor,
target: this.$$shadowRoot || this,
props: {
...this.$$d,
$$slots,
$$host: this
}
});
this.$$me = effect_root(() => {
render_effect(() => {
this.$$r = true;
for (const key2 of object_keys(this.$$c)) {
if (!this.$$p_d[key2]?.reflect) continue;
this.$$d[key2] = this.$$c[key2];
const attribute_value = get_custom_element_value(
key2,
this.$$d[key2],
this.$$p_d,
"toAttribute"
);
if (attribute_value == null) {
this.removeAttribute(this.$$p_d[key2].attribute || key2);
} else {
this.setAttribute(this.$$p_d[key2].attribute || key2, attribute_value);
}
}
this.$$r = false;
});
});
for (const type in this.$$l) {
for (const listener of this.$$l[type]) {
const unsub = this.$$c.$on(type, listener);
this.$$l_u.set(listener, unsub);
}
}
this.$$l = {};
}
}
// We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte
// and setting attributes through setAttribute etc, this is helpful
/**
* @param {string} attr
* @param {string} _oldValue
* @param {string} newValue
*/
attributeChangedCallback(attr2, _oldValue, newValue) {
if (this.$$r) return;
attr2 = this.$$g_p(attr2);
this.$$d[attr2] = get_custom_element_value(attr2, newValue, this.$$p_d, "toProp");
this.$$c?.$set({ [attr2]: this.$$d[attr2] });
}
disconnectedCallback() {
this.$$cn = false;
Promise.resolve().then(() => {
if (!this.$$cn && this.$$c) {
this.$$c.$destroy();
this.$$me();
this.$$c = void 0;
}
});
}
/**
* @param {string} attribute_name
*/
$$g_p(attribute_name) {
return object_keys(this.$$p_d).find(
(key2) => this.$$p_d[key2].attribute === attribute_name || !this.$$p_d[key2].attribute && key2.toLowerCase() === attribute_name
) || attribute_name;
}
};
}
function get_custom_element_value(prop2, value, props_definition, transform) {
const type = props_definition[prop2]?.type;
value = type === "Boolean" && typeof value !== "boolean" ? value != null : value;
if (!transform || !props_definition[prop2]) {
return value;
} else if (transform === "toAttribute") {
switch (type) {
case "Object":
case "Array":
return value == null ? null : JSON.stringify(value);
case "Boolean":
return value ? "" : null;
case "Number":
return value == null ? null : value;
default:
return value;
}
} else {
switch (type) {
case "Object":
case "Array":
return value && JSON.parse(value);
case "Boolean":
return value;
// conversion already handled above
case "Number":
return value != null ? +value : value;
default:
return value;
}
}
}
function get_custom_elements_slots(element2) {
const result = {};
element2.childNodes.forEach((node) => {
result[
/** @type {Element} node */
node.slot || "default"
] = true;
});
return result;
}
// src/Types/progressPropertyOptions.ts
var ProgressPropertyOptions = /* @__PURE__ */ ((ProgressPropertyOptions2) => {
ProgressPropertyOptions2["TaskTotal"] = "Total Tasks";
ProgressPropertyOptions2["TaskComplete"] = "Completed Tasks";
ProgressPropertyOptions2["TaskIncomplete"] = "Incomplete Tasks";
return ProgressPropertyOptions2;
})(ProgressPropertyOptions || {});
// src/Modals/ProgressPropertiesSettingModal/ProgressPropertiesModalContent.svelte
var root = from_html(`<option></option>`);
var root_1 = from_html(`<tr><td><input type="text" placeholder="Property name"/></td><td><select class="svelte-1eh4i7q"></select></td><td><input type="button" class="not-a-button" value="\u274C"/></td></tr>`);
var root_2 = from_html(`<div class="centerSettingContent"><table style="width: 100%"><thead><tr><th>Name</th><th>Type</th></tr></thead><tbody></tbody></table> <div class="buttonContainer svelte-1eh4i7q"><button class="mod-cta svelte-1eh4i7q">Add</button></div></div>`);
var $$css = {
hash: "svelte-1eh4i7q",
code: ".buttonContainer.svelte-1eh4i7q {display:flex;justify-content:center;margin-top:1rem;}select.svelte-1eh4i7q {border-radius:4px;width:100%;height:30px;border:1px solid #dbdbdc;color:#383a42;background-color:#fff;padding:3px;}button.svelte-1eh4i7q {margin-left:5px;margin-right:5px;font-size:15px;}"
};
function ProgressPropertiesModalContent($$anchor, $$props) {
push($$props, true);
append_styles($$anchor, $$css);
const options = Object.keys(ProgressPropertyOptions).map((k) => ProgressPropertyOptions[k]);
let initialProperties = prop($$props, "properties", 19, () => []);
let properties = state(proxy(untrack(() => initialProperties().map((property) => ({ ...property })))));
function saveProperties() {
$$props.save(snapshot(get2(properties)));
}
function addNewProperty() {
const newProp = { name: "", type: "Total Tasks" /* TaskTotal */ };
set(properties, [...get2(properties), newProp], true);
saveProperties();
}
function removeProperty(property) {
set(properties, get2(properties).filter((prop2) => prop2 !== property), true);
saveProperties();
}
var div = root_2();
var table = child(div);
var tbody = sibling(child(table));
each(tbody, 20, () => get2(properties), (property) => property, ($$anchor2, property, $$index_1) => {
var tr = root_1();
var td = child(tr);
var input = child(td);
remove_input_defaults(input);
reset(td);
var td_1 = sibling(td);
var select = child(td_1);
each(select, 20, () => options, (text2) => text2, ($$anchor3, text2) => {
var option = root();
var option_value = {};
template_effect(() => {
set_attribute2(option, "label", text2);
if (option_value !== (option_value = text2)) {
option.value = (option.__value = text2) ?? "";
}
});
append($$anchor3, option);
});
reset(select);
reset(td_1);
var td_2 = sibling(td_1);
var input_1 = child(td_2);
reset(td_2);
reset(tr);
delegated("change", input, saveProperties);
bind_value(input, () => property.name, ($$value) => property.name = $$value);
delegated("change", select, saveProperties);
bind_select_value(select, () => property.type, ($$value) => property.type = $$value);
delegated("click", input_1, () => removeProperty(property));
append($$anchor2, tr);
});
reset(tbody);
reset(table);
var div_1 = sibling(table, 2);
var button = child(div_1);
reset(div_1);
reset(div);
delegated("click", button, addNewProperty);
append($$anchor, div);
pop();
}
delegate(["change", "click"]);
// src/Modals/AutoPropertiesSettingModal/AutoPropertiesModalContent.svelte
var import_obsidian = require("obsidian");
// src/autoProperties.ts
function findAutoProperty(properties, propertyName) {
return properties?.find((a) => a.name === propertyName);
}
function isMultiAutoProperty(autoProp, editMode, propertyName) {
if (autoProp.type === "Multi") return true;
if (autoProp.type === "Single") return false;
if (editMode.mode === "All Multi" /* AllMulti */) return true;
if (editMode.mode === "Some Multi" /* SomeMulti */ && editMode.properties.includes(propertyName)) {
return true;
}
return false;
}
function normalizeChoices(choices) {
if (!choices) return [];
const seen = /* @__PURE__ */ new Set();
const out = [];
for (const raw of choices) {
const choice = (raw ?? "").trim();
if (choice === "" || seen.has(choice)) continue;
seen.add(choice);
out.push(choice);
}
return out;
}
function splitPastedChoices(text2) {
if (!text2) return [];
const parts = /[\r\n]/.test(text2) ? text2.split(/\r\n|\r|\n/) : text2.split(",");
return parts.map((p) => p.trim()).filter((p) => p !== "");
}
function withChoicesPasted(choices, index2, tokens) {
const before = choices.slice(0, index2);
const after = choices.slice(index2 + 1);
const taken = new Set(
[...before, ...after].map((c) => (c ?? "").trim()).filter((c) => c !== "")
);
const inserted = [];
for (const raw of tokens) {
const choice = (raw ?? "").trim();
if (choice === "" || taken.has(choice)) continue;
taken.add(choice);
inserted.push(choice);
}
return [...before, ...inserted, ...after];
}
function cloneAutoProperty(property) {
const clone2 = {
name: property.name,
choices: Array.isArray(property.choices) ? [...property.choices] : []
};
if (property.description !== void 0) clone2.description = property.description;
if (property.type !== void 0) clone2.type = property.type;
return clone2;
}
function cloneAutoProperties(properties) {
if (!Array.isArray(properties)) return [];
return properties.map(cloneAutoProperty);
}
function applyAutoPropertySettingsOperation(properties, operation) {
const next2 = cloneAutoProperties(properties);
switch (operation.kind) {
case "addProperty": {
const index2 = boundedInsertIndex(operation.index, next2.length);
next2.splice(index2, 0, cloneAutoProperty(operation.property));
return next2;
}
case "removeProperty": {
const index2 = findAutoPropertyOperationTargetIndex(next2, operation.target);
if (index2 === -1) return false;
next2.splice(index2, 1);
return next2;
}
case "setName":
case "setDescription":
case "setType": {
const index2 = findAutoPropertyOperationTargetIndex(next2, operation.target);
if (index2 === -1) return false;
const current = next2[index2];
if (operation.kind === "setName") {
if (current.name === operation.value) return false;
current.name = operation.value;
} else if (operation.kind === "setDescription") {
if ((current.description ?? "") === operation.value) return false;
current.description = operation.value;
} else {
if ((current.type ?? "Single") === operation.value) return false;
current.type = operation.value;
}
return next2;
}
case "addChoice": {
const property = findAutoPropertyOperationTarget(next2, operation.target);
if (!property) return false;
property.choices.splice(boundedInsertIndex(operation.index, property.choices.length), 0, operation.value);
return next2;
}
case "removeChoice": {
const property = findAutoPropertyOperationTarget(next2, operation.target);
if (!property) return false;
const choiceIndex = findExistingChoiceIndex(property.choices, operation.index, operation.value);
if (choiceIndex === -1) return false;
property.choices.splice(choiceIndex, 1);
return next2;
}
case "setChoice": {
const property = findAutoPropertyOperationTarget(next2, operation.target);
if (!property) return false;
if (operation.previousValue === operation.value) return false;
const choiceIndex = findWritableChoiceIndex(property.choices, operation.index, operation.previousValue);
property.choices.splice(choiceIndex, choiceIndex < property.choices.length ? 1 : 0, operation.value);
return next2;
}
case "replaceChoiceWithChoices": {
const property = findAutoPropertyOperationTarget(next2, operation.target);
if (!property) return false;
const choiceIndex = findExistingChoiceIndex(property.choices, operation.index, operation.previousValue);
if (choiceIndex === -1) {
property.choices = withChoicesInserted(property.choices, operation.index, operation.values);
} else {
property.choices = withChoicesPasted(property.choices, choiceIndex, operation.values);
}
return next2;
}
}
}
function boundedInsertIndex(index2, length) {
if (!Number.isFinite(index2)) return length;
return Math.max(0, Math.min(index2, length));
}
function findAutoPropertyOperationTarget(properties, target) {
const index2 = findAutoPropertyOperationTargetIndex(properties, target);
return index2 === -1 ? void 0 : properties[index2];
}
function findAutoPropertyOperationTargetIndex(properties, target) {
if (isValidIndex(target.index, properties.length) && properties[target.index].name === target.name) {
return target.index;
}
if (target.name !== "") {
const namedIndex = properties.findIndex((property) => property.name === target.name);
if (namedIndex !== -1) return namedIndex;
}
if (target.name === "" && isValidIndex(target.index, properties.length)) return target.index;
return -1;
}
function findExistingChoiceIndex(choices, index2, value) {
if (isValidIndex(index2, choices.length) && choices[index2] === value) return index2;
return choices.findIndex((choice) => choice === value);
}
function findWritableChoiceIndex(choices, index2, value) {
const existingIndex = findExistingChoiceIndex(choices, index2, value);
if (existingIndex !== -1) return existingIndex;
return boundedInsertIndex(index2, choices.length);
}
function withChoicesInserted(choices, index2, tokens) {
const next2 = [...choices];
const taken = new Set(next2.map((c) => (c ?? "").trim()).filter((c) => c !== ""));
const inserted = [];
for (const raw of tokens) {
const choice = (raw ?? "").trim();
if (choice === "" || taken.has(choice)) continue;
taken.add(choice);
inserted.push(choice);
}
next2.splice(boundedInsertIndex(index2, next2.length), 0, ...inserted);
return next2;
}
function isValidIndex(index2, length) {
return Number.isInteger(index2) && index2 >= 0 && index2 < length;
}
function splitCommaSeparatedValues(value) {
const parts = [];
let start = 0;
let wikilinkDepth = 0;
for (let i = 0; i < value.length; i++) {
if (value.startsWith("[[", i)) {
wikilinkDepth++;
i++;
continue;
}
if (wikilinkDepth > 0 && value.startsWith("]]", i)) {
wikilinkDepth--;
i++;
continue;
}
if (value[i] === "," && wikilinkDepth === 0) {
parts.push(value.slice(start, i));
start = i + 1;
}
}
parts.push(value.slice(start));
return parts;
}
function matchingOuterBracketIndex(value) {
let depth = 0;
for (let i = 0; i < value.length; i++) {
const char = value[i];
if (char === "[") {
depth++;
} else if (char === "]") {
depth--;
if (depth === 0) return i;
if (depth < 0) return null;
}
}
return null;
}
function shouldUnwrapBracketedList(value) {
if (!value.startsWith("[") || !value.endsWith("]")) return false;
if (value.startsWith("[[")) return false;
if (matchingOuterBracketIndex(value) !== value.length - 1) return false;
const innerValue = value.slice(1, -1);
if (innerValue.trim() === "") return true;
return splitCommaSeparatedValues(innerValue).length > 1;
}
function toValueArray(content) {
if (content === null || content === void 0) return [];
if (Array.isArray(content)) {
return content.map((v) => (v ?? "").toString().trim()).filter(Boolean);
}
const value = content.toString().trim();
const splitValue = shouldUnwrapBracketedList(value) ? value.slice(1, -1) : value;
return splitCommaSeparatedValues(splitValue).map((s) => s.trim()).filter(Boolean);
}
function multiSelectOptions(autoProp, currentValue) {
const seen = /* @__PURE__ */ new Set();
const out = [];
for (const value of [...toValueArray(currentValue), ...normalizeChoices(autoProp.choices)]) {
if (!seen.has(value)) {
seen.add(value);
out.push(value);
}
}
return out;
}
function isNewChoice(autoProp, value) {
const trimmed = value.trim();
if (trimmed === "") return false;
return !(autoProp.choices ?? []).some((c) => (c ?? "").trim() === trimmed);
}
function withChoiceAdded(autoProp, value) {
if (!isNewChoice(autoProp, value)) return autoProp;
return { ...autoProp, choices: [...autoProp.choices ?? [], value.trim()] };
}
// src/Modals/AutoPropertiesSettingModal/AutoPropertiesModalContent.svelte
var root2 = from_html(`<p class="metaedit-empty svelte-1i9u2va">No auto properties yet. Add one to define a reusable set of values for a property.</p>`);
var root_12 = from_html(`<option> </option>`);
var root_22 = from_html(`<div class="metaedit-ap-choice svelte-1i9u2va"><input type="text" placeholder="Value (or paste a list)" class="svelte-1i9u2va"/> <button class="clickable-icon metaedit-ap-icon svelte-1i9u2va" aria-label="Remove value"><span></span></button></div>`);
var root_3 = from_html(`<div class="metaedit-ap-card svelte-1i9u2va"><div class="metaedit-ap-header svelte-1i9u2va"><input class="metaedit-ap-name svelte-1i9u2va" type="text" placeholder="Property name"/> <select class="dropdown metaedit-ap-type svelte-1i9u2va" aria-label="How many values this property holds"></select> <button class="clickable-icon metaedit-ap-icon svelte-1i9u2va" aria-label="Remove this auto property"><span></span></button></div> <input class="metaedit-ap-description svelte-1i9u2va" type="text" placeholder="Description (shown when you pick a value) - optional"/> <div class="metaedit-ap-values svelte-1i9u2va"><span class="metaedit-ap-label svelte-1i9u2va">Values</span> <!> <button class="metaedit-ap-add-value svelte-1i9u2va"><span></span> Add value</button></div></div>`);
var root_4 = from_html(`<div class="metaedit-auto-properties svelte-1i9u2va"><!> <!> <div class="metaedit-ap-footer svelte-1i9u2va"><button class="mod-cta">Add auto property</button></div></div>`);
var $$css2 = {
hash: "svelte-1i9u2va",
code: ".metaedit-auto-properties.svelte-1i9u2va {display:flex;flex-direction:column;gap:0.75rem;margin-top:0.5rem;}.metaedit-empty.svelte-1i9u2va {color:var(--text-muted);text-align:center;margin:0.5rem 0;}.metaedit-ap-card.svelte-1i9u2va {display:flex;flex-direction:column;gap:0.5rem;padding:0.75rem;border:1px solid var(--background-modifier-border);border-radius:var(--radius-m, 8px);background-color:var(--background-secondary);}.metaedit-ap-header.svelte-1i9u2va {display:flex;gap:0.5rem;align-items:center;}.metaedit-ap-name.svelte-1i9u2va {flex:1 1 auto;min-width:0;font-weight:var(--font-semibold, 600);}.metaedit-ap-type.svelte-1i9u2va {flex:0 0 auto;}.metaedit-ap-description.svelte-1i9u2va {width:100%;}.metaedit-ap-values.svelte-1i9u2va {display:flex;flex-direction:column;gap:0.35rem;}.metaedit-ap-label.svelte-1i9u2va {color:var(--text-muted);font-size:var(--font-ui-smaller, 0.8em);}.metaedit-ap-choice.svelte-1i9u2va {display:flex;gap:0.5rem;align-items:center;}.metaedit-ap-choice.svelte-1i9u2va input:where(.svelte-1i9u2va) {flex:1 1 auto;min-width:0;}.metaedit-ap-icon.svelte-1i9u2va {flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;}.metaedit-ap-add-value.svelte-1i9u2va {display:inline-flex;align-items:center;gap:0.35rem;align-self:flex-start;background:transparent;box-shadow:none;color:var(--text-muted);padding:0.25rem 0.4rem;cursor:pointer;}.metaedit-ap-add-value.svelte-1i9u2va:hover {color:var(--text-normal);}.metaedit-ap-footer.svelte-1i9u2va {display:flex;justify-content:center;margin-top:0.25rem;}"
};
function AutoPropertiesModalContent($$anchor, $$props) {
push($$props, true);
append_styles($$anchor, $$css2);
let initialAutoProperties = prop($$props, "autoProperties", 19, () => []);
const types = ["Single", "Multi"];
let nextPropertyId = 0;
let autoProperties = state(proxy(untrack(() => createEditableAutoProperties(initialAutoProperties()))));
function icon(node, name) {
const render = (n) => {
node.textContent = "";
(0, import_obsidian.setIcon)(node, n);
};
render(name);
return { update: render };
}
function indexes(values) {
return values.map((_, i) => i);
}
function createEditableAutoProperties(properties) {
return cloneAutoProperties(properties).map((property) => createEditableAutoProperty(property));
}
function createEditableAutoProperty(property) {
return {
id: nextPropertyId++,
property,
targetName: property.name,
choiceTargets: [...property.choices]
};
}
function targetFor(entry, index2) {
return { name: entry.targetName, index: index2 };
}
function persist(operation) {
void Promise.resolve($$props.save(operation)).catch((error) => {
console.error("MetaEdit could not save Auto Properties settings.", error);
});
}
function addNewProperty() {
const property = { name: "", choices: [""], type: "Single" };
const entry = createEditableAutoProperty(cloneAutoProperty(property));
const index2 = get2(autoProperties).length;
set(autoProperties, [...get2(autoProperties), entry], true);
persist({ kind: "addProperty", index: index2, property });
}
function removeProperty(entry, index2) {
const target = targetFor(entry, index2);
set(autoProperties, get2(autoProperties).filter((candidate) => candidate !== entry), true);
persist({ kind: "removeProperty", target });
}
function removeChoice(entry, propertyIndex, choiceIndex) {
const value = entry.choiceTargets[choiceIndex] ?? entry.property.choices[choiceIndex] ?? "";
entry.property.choices = entry.property.choices.filter((_, index2) => index2 !== choiceIndex);
entry.choiceTargets = entry.choiceTargets.filter((_, index2) => index2 !== choiceIndex);
persist({
kind: "removeChoice",
target: targetFor(entry, propertyIndex),
index: choiceIndex,
value
});
}
function addChoice(entry, propertyIndex) {
const index2 = entry.property.choices.length;
entry.property.choices = [...entry.property.choices, ""];
entry.choiceTargets = [...entry.choiceTargets, ""];
persist({
kind: "addChoice",
target: targetFor(entry, propertyIndex),
index: index2,
value: ""
});
}
function pasteChoices(entry, propertyIndex, index2, event2) {
const tokens = splitPastedChoices(event2.clipboardData?.getData("text") ?? "");
if (tokens.length < 2) return;
event2.preventDefault();
const previousValue = entry.choiceTargets[index2] ?? entry.property.choices[index2] ?? "";
entry.property.choices = withChoicesPasted(entry.property.choices, index2, tokens);
entry.choiceTargets = withChoicesPasted(entry.choiceTargets, index2, tokens);
persist({
kind: "replaceChoiceWithChoices",
target: targetFor(entry, propertyIndex),
index: index2,
previousValue,
values: tokens
});
}
function setName(entry, index2, value) {
const target = targetFor(entry, index2);
entry.property.name = value;
entry.targetName = value;
persist({ kind: "setName", target, value });
}
function setDescription(entry, index2, value) {
entry.property.description = value;
persist({
kind: "setDescription",
target: targetFor(entry, index2),
value
});
}
function setType(entry, index2, value) {
const type = value;
entry.property.type = type;
persist({
kind: "setType",
target: targetFor(entry, index2),
value: type
});
}
function setChoice(entry, propertyIndex, choiceIndex, value) {
const previousValue = entry.choiceTargets[choiceIndex] ?? entry.property.choices[choiceIndex] ?? "";
entry.property.choices[choiceIndex] = value;
entry.choiceTargets[choiceIndex] = value;
persist({
kind: "setChoice",
target: targetFor(entry, propertyIndex),
index: choiceIndex,
previousValue,
value
});
}
var div = root_4();
var node_1 = child(div);
{
var consequent = ($$anchor2) => {
var p = root2();
append($$anchor2, p);
};
if_block(node_1, ($$render) => {
if (get2(autoProperties).length === 0) $$render(consequent);
});
}
var node_2 = sibling(node_1, 2);
each(node_2, 19, () => get2(autoProperties), (entry) => entry.id, ($$anchor2, entry, propertyIndex) => {
const property = user_derived(() => get2(entry).property);
var div_1 = root_3();
var div_2 = child(div_1);
var input = child(div_2);
remove_input_defaults(input);
var select = sibling(input, 2);
each(select, 20, () => types, (t) => t, ($$anchor3, t) => {
var option = root_12();
var text2 = child(option, true);
reset(option);
var option_value = {};
template_effect(() => {
set_selected(option, (get2(property).type ?? "Single") === t);
set_text(text2, t);
if (option_value !== (option_value = t)) {
option.value = (option.__value = t) ?? "";
}
});
append($$anchor3, option);
});
reset(select);
var button = sibling(select, 2);
var span = child(button);
action(span, ($$node, $$action_arg) => icon?.($$node, $$action_arg), () => "trash-2");
reset(button);
reset(div_2);
var input_1 = sibling(div_2, 2);
remove_input_defaults(input_1);
var div_3 = sibling(input_1, 2);
var node_3 = sibling(child(div_3), 2);
each(node_3, 16, () => indexes(get2(property).choices), (i) => i, ($$anchor3, i) => {
var div_4 = root_22();
var input_2 = child(div_4);
remove_input_defaults(input_2);
var button_1 = sibling(input_2, 2);
var span_1 = child(button_1);
action(span_1, ($$node, $$action_arg) => icon?.($$node, $$action_arg), () => "x");
reset(button_1);
reset(div_4);
template_effect(() => set_value(input_2, get2(property).choices[i]));
delegated("input", input_2, (e) => get2(property).choices[i] = e.currentTarget.value);
delegated("change", input_2, (e) => setChoice(get2(entry), get2(propertyIndex), i, e.currentTarget.value));
event("paste", input_2, (e) => pasteChoices(get2(entry), get2(propertyIndex), i, e));
delegated("click", button_1, () => removeChoice(get2(entry), get2(propertyIndex), i));
append($$anchor3, div_4);
});
var button_2 = sibling(node_3, 2);
var span_2 = child(button_2);
action(span_2, ($$node, $$action_arg) => icon?.($$node, $$action_arg), () => "plus");
next();
reset(button_2);
reset(div_3);
reset(div_1);
template_effect(() => {
set_value(input, get2(property).name);
set_value(input_1, get2(property).description ?? "");
});
delegated("input", input, (e) => get2(property).name = e.currentTarget.value);
delegated("change", input, (e) => setName(get2(entry), get2(propertyIndex), e.currentTarget.value));
delegated("change", select, (e) => setType(get2(entry), get2(propertyIndex), e.currentTarget.value));
delegated("click", button, () => removeProperty(get2(entry), get2(propertyIndex)));
delegated("input", input_1, (e) => get2(property).description = e.currentTarget.value);
delegated("change", input_1, (e) => setDescription(get2(entry), get2(propertyIndex), e.currentTarget.value));
delegated("click", button_2, () => addChoice(get2(entry), get2(propertyIndex)));
append($$anchor2, div_1);
});
var div_5 = sibling(node_2, 2);
var button_3 = child(div_5);
reset(div_5);
reset(div);
delegated("click", button_3, addNewProperty);
append($$anchor, div);
pop();
}
delegate(["input", "change", "click"]);
// src/Modals/KanbanHelperSetting/KanbanHelperSettingSuggester.ts
var import_obsidian2 = require("obsidian");
var KanbanHelperSettingSuggester = class extends import_obsidian2.AbstractInputSuggest {
constructor(app, inputEl, boards) {
super(app, inputEl);
this.inputEl = inputEl;
this.boards = boards;
this.onSelect((item) => this.acceptSuggestion(item));
}
getSuggestions(inputStr) {
const inputLowerCase = inputStr.toLowerCase();
return this.boards.filter((board) => board.basename.toLowerCase().includes(inputLowerCase));
}
acceptSuggestion(item) {
this.setValue(item.basename);
this.inputEl.trigger("input");
this.close();
}
renderSuggestion(value, el) {
if (value)
el.setText(value.basename);
}
};
// src/logger/logManager.ts
var _LogManager = class _LogManager {
register(logger) {
_LogManager.loggers.push(logger);
return this;
}
logError(message) {
_LogManager.loggers.forEach((logger) => logger.logError(message));
throw new Error();
}
logWarning(message) {
_LogManager.loggers.forEach((logger) => logger.logError(message));
}
logMessage(message) {
_LogManager.loggers.forEach((logger) => logger.logMessage(message));
}
};
_LogManager.loggers = [];
var LogManager = _LogManager;
var log = new LogManager();
// src/Modals/KanbanHelperSetting/KanbanHelperSettingContent.svelte
var root3 = from_html(`<tr><td><input type="button" value="\u274C" class="not-a-button"/></td><td> </td><td><input type="text" placeholder="Property name"/></td><td> </td></tr>`);
var root_13 = from_html(`<div class="centerSettingContent"><table style="width: 100%"><thead><tr><th></th><th>Board</th><th>Property in link</th><th>Possible values</th></tr></thead><tbody></tbody></table> <input type="text"/> <div class="buttonContainer svelte-pptp52"><button class="mod-cta svelte-pptp52">Add</button></div></div>`);
var $$css3 = {
hash: "svelte-pptp52",
code: ".buttonContainer.svelte-pptp52 {display:flex;justify-content:center;margin-top:1rem;}button.svelte-pptp52 {margin-left:5px;margin-right:5px;font-size:15px;}"
};
function KanbanHelperSettingContent($$anchor, $$props) {
push($$props, true);
append_styles($$anchor, $$css3);
let initialKanbanProperties = prop($$props, "kanbanProperties", 19, () => []);
const initialApp = untrack(() => $$props.app);
const initialBoards = untrack(() => $$props.boards);
let kanbanProperties = state(proxy(untrack(() => initialKanbanProperties().map((property) => ({ ...property })))));
let suggestEl = state(void 0);
let suggester;
let inputValue = state("");
let didInitialise = false;
user_effect(() => {
const el = get2(suggestEl);
if (!el || didInitialise) return;
didInitialise = true;
suggester = new KanbanHelperSettingSuggester(initialApp, el, initialBoards);
return () => {
suggester?.close();
suggester = void 0;
};
});
function saveProperties() {
$$props.save(snapshot(get2(kanbanProperties)));
}
function addNewProperty() {
const board = initialBoards.find((board2) => board2.basename === get2(inputValue));
if (!board) return;
const exists = !!get2(kanbanProperties).find((kp) => kp.boardName === board.basename);
if (exists) return;
set(
kanbanProperties,
[
...get2(kanbanProperties),
{ property: "", boardName: board.basename }
],
true
);
saveProperties();
}
function removeProperty(i) {
set(kanbanProperties, get2(kanbanProperties).filter((_, index2) => index2 !== i), true);
saveProperties();
}
function getHeadingsInBoard(boardName) {
const file = initialBoards.find((board) => board.basename === boardName);
if (!file) {
log.logWarning(`file ${boardName} not found.`);
return "FILE NOT FOUND";
}
const headings = initialApp.metadataCache.getFileCache(file)?.headings;
if (!headings) return "";
return headings.map((heading) => heading.heading).join(", ");
}
var div = root_13();
var table = child(div);
var tbody = sibling(child(table));
each(tbody, 23, () => get2(kanbanProperties), (kanbanProperty) => kanbanProperty.boardName, ($$anchor2, kanbanProperty, i) => {
var tr = root3();
var td = child(tr);
var input = child(td);
reset(td);
var td_1 = sibling(td);
var text2 = child(td_1, true);
reset(td_1);
var td_2 = sibling(td_1);
var input_1 = child(td_2);
remove_input_defaults(input_1);
reset(td_2);
var td_3 = sibling(td_2);
var text_1 = child(td_3, true);
reset(td_3);
reset(tr);
template_effect(
($0) => {
set_text(text2, get2(kanbanProperty).boardName);
set_text(text_1, $0);
},
[() => getHeadingsInBoard(get2(kanbanProperty).boardName)]
);
delegated("click", input, () => removeProperty(get2(i)));
delegated("change", input_1, saveProperties);
bind_value(input_1, () => get2(kanbanProperty).property, ($$value) => get2(kanbanProperty).property = $$value);
append($$anchor2, tr);
});
reset(tbody);
reset(table);
var input_2 = sibling(table, 2);
remove_input_defaults(input_2);
bind_this(input_2, ($$value) => set(suggestEl, $$value), () => get2(suggestEl));
var div_1 = sibling(input_2, 2);
var button = child(div_1);
reset(div_1);
reset(div);
bind_value(input_2, () => get2(inputValue), ($$value) => set(inputValue, $$value));
delegated("click", button, addNewProperty);
append($$anchor, div);
pop();
}
delegate(["click", "change"]);
// src/Modals/shared/SingleValueTableEditorContent.svelte
var root4 = from_html(`<tr><td><input type="button" value="\u274C" class="not-a-button"/></td><td><input style="width: 100%;" type="text" placeholder="Property name"/></td></tr>`);
var root_14 = from_html(`<div class="centerSettingContent"><table style="width: 100%"><thead><tr><th></th><th>Property</th></tr></thead><tbody></tbody></table> <div class="buttonContainer svelte-158j4ih"><button class="mod-cta svelte-158j4ih">Add</button></div></div>`);
var $$css4 = {
hash: "svelte-158j4ih",
code: ".buttonContainer.svelte-158j4ih {display:flex;justify-content:center;margin-top:1rem;}button.svelte-158j4ih {margin-left:5px;margin-right:5px;font-size:15px;}"
};
function SingleValueTableEditorContent($$anchor, $$props) {
push($$props, true);
append_styles($$anchor, $$css4);
let initialProperties = prop($$props, "properties", 19, () => []);
let properties = state(proxy(untrack(() => [...initialProperties()])));
let propertyIndexes = user_derived(() => get2(properties).map((_, i) => i));
function saveProperties() {
$$props.save(snapshot(get2(properties)));
}
function addNewProperty() {
set(properties, [...get2(properties), ""], true);
saveProperties();
}
function removeProperty(i) {
set(properties, get2(properties).filter((_, index2) => index2 !== i), true);
saveProperties();
}
var div = root_14();
var table = child(div);
var tbody = sibling(child(table));
each(tbody, 20, () => get2(propertyIndexes), (i) => i, ($$anchor2, i) => {
var tr = root4();
var td = child(tr);
var input = child(td);
reset(td);
var td_1 = sibling(td);
var input_1 = child(td_1);
remove_input_defaults(input_1);
reset(td_1);
reset(tr);
delegated("click", input, () => removeProperty(i));
delegated("change", input_1, saveProperties);
bind_value(input_1, () => get2(properties)[i], ($$value) => get2(properties)[i] = $$value);
append($$anchor2, tr);
});
reset(tbody);
reset(table);
var div_1 = sibling(table, 2);
var button = child(div_1);
reset(div_1);
reset(div);
delegated("click", button, addNewProperty);
append($$anchor, div);
pop();
}
delegate(["click", "change"]);
// src/svelteMount.ts
function mountSvelteComponent(component2, target, props) {
return mount(
component2,
{ target, props }
);
}
function unmountSvelteComponent(component2) {
if (!component2) return;
void unmount(component2);
}
// src/Settings/metaEditSettingsTab.ts
function toggleHiddenEl(el, hidden) {
if (!el) return hidden;
el.classList.toggle("metaedit-hidden", !hidden);
return !hidden;
}
var MetaEditSettingsTab = class extends import_obsidian3.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.svelteElements = [];
this.plugin = plugin;
}
display() {
const { containerEl } = this;
this.destroySvelteElements();
containerEl.empty();
new import_obsidian3.Setting(containerEl).setName("MetaEdit Settings").setHeading();
this.addProgressPropertiesSetting(containerEl);
this.addAutoPropertiesSetting(containerEl);
this.addEditMetaMenuSetting(containerEl);
this.addEditModeSetting(containerEl);
this.addKanbanHelperSetting(containerEl);
this.addUIElementsSetting(containerEl);
}
addProgressPropertiesSetting(containerEl) {
let hidden = true;
const setting = new import_obsidian3.Setting(containerEl).setName("Progress Properties").setDesc("Update properties automatically.").addToggle((toggle) => {
toggle.setTooltip("Toggle Progress Properties").setValue(this.plugin.settings.ProgressProperties.enabled).onChange(async (value) => {
if (value === this.plugin.settings.ProgressProperties.enabled) return;
this.plugin.settings.ProgressProperties.enabled = value;
this.plugin.toggleAutomators();
await this.plugin.saveSettings();
});
});
const div = setting.settingEl.createDiv({ cls: "metaedit-hidden" });
setting.settingEl.classList.add("metaedit-setting-with-details");
setting.addExtraButton((button) => button.onClick(() => hidden = toggleHiddenEl(div, hidden)));
const modal = mountSvelteComponent(
ProgressPropertiesModalContent,
div,
{
properties: this.plugin.settings.ProgressProperties.properties,
save: async (progressProperties) => {
this.plugin.settings.ProgressProperties.properties = progressProperties;
await this.plugin.saveSettings();
}
}
);
this.svelteElements.push(modal);
}
addAutoPropertiesSetting(containerEl) {
let hidden = true;
const setting = new import_obsidian3.Setting(containerEl).setName("Auto Properties").setDesc("Quick switch for values you know the value of.").addToggle((toggle) => {
toggle.setTooltip("Toggle Auto Properties").setValue(this.plugin.settings.AutoProperties.enabled).onChange(async (value) => {
if (value === this.plugin.settings.AutoProperties.enabled) return;
this.plugin.settings.AutoProperties.enabled = value;
await this.plugin.saveSettings();
});
});
const div = setting.settingEl.createDiv({ cls: "metaedit-hidden" });
setting.settingEl.classList.add("metaedit-setting-with-details");
setting.addExtraButton((b) => b.onClick(() => hidden = toggleHiddenEl(div, hidden)));
const modal = mountSvelteComponent(
AutoPropertiesModalContent,
div,
{
autoProperties: this.plugin.settings.AutoProperties.properties,
save: (operation) => this.saveAutoPropertiesOperation(operation)
}
);
this.svelteElements.push(modal);
}
async saveAutoPropertiesOperation(operation) {
try {
await this.plugin.updateSettings(() => {
const previousAutoProperties = this.plugin.settings.AutoProperties.properties;
const nextAutoProperties = applyAutoPropertySettingsOperation(previousAutoProperties, operation);
if (nextAutoProperties === false) return false;
this.plugin.settings.AutoProperties.properties = nextAutoProperties;
return () => {
if (this.plugin.settings.AutoProperties.properties === nextAutoProperties) {
this.plugin.settings.AutoProperties.properties = previousAutoProperties;
}
};
});
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
new import_obsidian3.Notice(`MetaEdit could not save the Auto Properties setting: ${reason}`);
}
}
addEditMetaMenuSetting(containerEl) {
let hidden = true;
const setting = new import_obsidian3.Setting(containerEl).setName("Edit Meta menu").setDesc("Control what the 'Edit Meta' menu lists. Enable it, then use the gear to hide specific properties by name or all of a note's file tags.").addToggle((toggle) => {
toggle.setTooltip("Toggle menu filtering").setValue(this.plugin.settings.IgnoredProperties.enabled).onChange(async (value) => {
if (value === this.plugin.settings.IgnoredProperties.enabled) return;
this.plugin.settings.IgnoredProperties.enabled = value;
await this.plugin.saveSettings();
this.display();
});
});
const div = this.plugin.settings.IgnoredProperties.enabled ? setting.settingEl.createDiv({ cls: "metaedit-hidden" }) : void 0;
if (div) setting.settingEl.classList.add("metaedit-setting-with-details");
setting.addExtraButton((b) => b.onClick(() => hidden = toggleHiddenEl(div, hidden)));
if (div) {
new import_obsidian3.Setting(div).setName("Hide file tags").setDesc("Hide the note's #tags from the menu, leaving only frontmatter and inline fields. A frontmatter 'tags' property stays editable.").addToggle((toggle) => {
toggle.setTooltip("Toggle hiding file tags").setValue(this.plugin.settings.IgnoredProperties.hideFileTags).onChange(async (value) => {
if (value === this.plugin.settings.IgnoredProperties.hideFileTags) return;
this.plugin.settings.IgnoredProperties.hideFileTags = value;
await this.plugin.saveSettings();
});
});
div.createEl("p", { text: "Hide specific properties by name:", cls: "metaedit-table-label" });
const modal = mountSvelteComponent(
SingleValueTableEditorContent,
div,
{
properties: this.plugin.settings.IgnoredProperties.properties,
save: async (ignoredProperties) => {
this.plugin.settings.IgnoredProperties.properties = ignoredProperties;
await this.plugin.saveSettings();
}
}
);
this.svelteElements.push(modal);
}
}
addEditModeSetting(containerEl) {
let bDivToggle = true;
let extraButtonEl;
const df = new DocumentFragment();
df.createEl("p", { text: "Single: property values are just one value. " });
df.createEl("p", { text: "Multi: properties are arrays. " });
df.createEl("p", { text: "Some Multi: all options are single, except those specified in the settings (click button)." });
const setting = new import_obsidian3.Setting(containerEl).setName("Edit Mode").setDesc(df);
const div = setting.settingEl.createDiv({ cls: "metaedit-hidden" });
setting.settingEl.classList.add("metaedit-setting-with-details");
setting.addDropdown((dropdown) => {
dropdown.addOption("All Single" /* AllSingle */, "All Single" /* AllSingle */).addOption("All Multi" /* AllMulti */, "All Multi" /* AllMulti */).addOption("Some Multi" /* SomeMulti */, "Some Multi" /* SomeMulti */).setValue(this.plugin.settings.EditMode.mode).onChange(async (value) => {
switch (value) {
case "All Multi" /* AllMulti */:
this.plugin.settings.EditMode.mode = "All Multi" /* AllMulti */;
toggleHiddenEl(extraButtonEl, false);
bDivToggle = toggleHiddenEl(div, false);
break;
case "All Single" /* AllSingle */:
this.plugin.settings.EditMode.mode = "All Single" /* AllSingle */;
toggleHiddenEl(extraButtonEl, false);
bDivToggle = toggleHiddenEl(div, false);
break;
case "Some Multi" /* SomeMulti */:
this.plugin.settings.EditMode.mode = "Some Multi" /* SomeMulti */;
toggleHiddenEl(extraButtonEl, true);
break;
}
await this.plugin.saveSettings();
});
}).addExtraButton((b) => {
extraButtonEl = b.extraSettingsEl;
b.setTooltip("Configure which properties are Multi.");
return b.onClick(() => bDivToggle = toggleHiddenEl(div, bDivToggle));
});
if (this.plugin.settings.EditMode.mode != "Some Multi" /* SomeMulti */) {
toggleHiddenEl(extraButtonEl, false);
}
const modal = mountSvelteComponent(
SingleValueTableEditorContent,
div,
{
properties: this.plugin.settings.EditMode.properties,
save: async (properties) => {
this.plugin.settings.EditMode.properties = properties;
await this.plugin.saveSettings();
}
}
);
this.svelteElements.push(modal);
}
hide() {
this.destroySvelteElements();
return super.hide();
}
destroySvelteElements() {
this.svelteElements.forEach(unmountSvelteComponent);
this.svelteElements = [];
}
addKanbanHelperSetting(containerEl) {
let hidden = true;
const setting = new import_obsidian3.Setting(containerEl).setName("Kanban Board Helper").setDesc("Update properties in links in kanban boards automatically when a card is moved to a new lane.").addToggle((toggle) => {
toggle.setTooltip("Toggle Kanban Helper").setValue(this.plugin.settings.KanbanHelper.enabled).onChange(async (value) => {
if (value === this.plugin.settings.KanbanHelper.enabled) return;
this.plugin.settings.KanbanHelper.enabled = value;
this.plugin.toggleAutomators();
await this.plugin.saveSettings();
});
});
const div = setting.settingEl.createDiv({ cls: "metaedit-hidden" });
setting.settingEl.classList.add("metaedit-setting-with-details");
setting.addExtraButton((button) => button.onClick(() => hidden = toggleHiddenEl(div, hidden)));
const modal = mountSvelteComponent(
KanbanHelperSettingContent,
div,
{
kanbanProperties: this.plugin.settings.KanbanHelper.boards,
boards: this.plugin.getFilesWithProperty("kanban-plugin"),
app: this.app,
save: async (kanbanProperties) => {
this.plugin.settings.KanbanHelper.boards = kanbanProperties;
await this.plugin.saveSettings();
}
}
);
this.svelteElements.push(modal);
}
addUIElementsSetting(containerEl) {
new import_obsidian3.Setting(containerEl).setName("UI Elements").setDesc("Toggle UI elements: the 'Edit Meta' right-click menu option.").addToggle((toggle) => {
toggle.setTooltip("Toggle UI elements").setValue(this.plugin.settings.UIElements.enabled).onChange(async (value) => {
if (value === this.plugin.settings.UIElements.enabled) return;
this.plugin.settings.UIElements.enabled = value;
if (value) {
this.plugin.linkMenu.registerEvent();
} else {
this.plugin.linkMenu.unregisterEvent();
}
await this.plugin.saveSettings();
});
});
}
};
// src/Modals/metaEditSuggester.ts
var import_obsidian4 = require("obsidian");
// src/constants.ts
var newDataView = "New Dataview field";
var newYaml = "New YAML property";
var MAIN_SUGGESTER_OPTIONS = [
{ key: newYaml, content: newYaml, type: 3 /* Option */ },
{ key: newDataView, content: newDataView, type: 3 /* Option */ }
];
// src/Modals/GenericPrompt/valueSuggest.ts
var ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
var ISO_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/;
var NATIVE_BUILT_IN_PROPERTY_NAMES = Object.freeze([
"aliases",
"cssclass",
"cssclasses",
"publish",
"tags"
]);
var MAX_RENDERED_SUGGESTIONS = 100;
function getValueSuggestions(app, key2, type, tagMode) {
if (!key2) return [];
try {
if (type === 2 /* Tag */) {
return tagMode === "leaf" ? rankByCount(collectTagLeafCounts(app)) : rankByCount(collectTagFullCounts(app));
}
if (type === 0 /* YAML */) {
return rankByCount(collectFrontmatterValueCounts(app, key2));
}
return [];
} catch {
return [];
}
}
function getDateInputType(app, key2, currentValue, type) {
if (type !== 0 /* YAML */ || !key2) return null;
let obsidianType;
try {
obsidianType = readObsidianType(app, key2);
} catch {
return null;
}
if (obsidianType !== "date" && obsidianType !== "datetime") return null;
const value = currentValue === null || currentValue === void 0 ? "" : String(currentValue).trim();
if (value === "") return obsidianType;
if (obsidianType === "date" && ISO_DATE.test(value)) return "date";
if (obsidianType === "datetime" && ISO_DATETIME.test(value)) return "datetime";
return null;
}
function getKnownPropertyNames(app) {
const names = /* @__PURE__ */ new Set();
for (const name of NATIVE_BUILT_IN_PROPERTY_NAMES) names.add(name);
try {
const all = getMetadataTypeManager(app)?.getAllProperties?.();
if (!all) return [...names];
for (const [key2, info] of Object.entries(all)) {
addPropertyName(names, key2);
addPropertyName(names, info?.name);
}
} catch {
return [...names];
}
return [...names];
}
function filterSuggestions(items, inputStr) {
const query = inputStr.toLowerCase();
const filtered = items.filter((item) => item.toLowerCase().includes(query));
if (filtered.length === 0) return [];
if (filtered.length === 1 && filtered[0] === inputStr) return [];
return filtered.slice(0, MAX_RENDERED_SUGGESTIONS);
}
function collectTagLeafCounts(app) {
const counts = /* @__PURE__ */ new Map();
for (const [tag2, count] of Object.entries(readVaultTags(app))) {
const leaf = tag2.replace(/^#/, "").split("/").pop()?.trim();
if (!leaf) continue;
counts.set(leaf, (counts.get(leaf) ?? 0) + (count ?? 1));
}
return counts;
}
function collectTagFullCounts(app) {
const counts = /* @__PURE__ */ new Map();
for (const [tag2, count] of Object.entries(readVaultTags(app))) {
const full = tag2.replace(/^#/, "").trim();
if (!full) continue;
counts.set(full, (counts.get(full) ?? 0) + (count ?? 1));
}
return counts;
}
function readVaultTags(app) {
const metadataCache = app.metadataCache;
return metadataCache.getTags?.() ?? {};
}
function collectFrontmatterValueCounts(app, key2) {
const counts = /* @__PURE__ */ new Map();
for (const file of app.vault.getMarkdownFiles()) {
const frontmatter = app.metadataCache.getFileCache(file)?.frontmatter;
if (!frontmatter || !Object.prototype.hasOwnProperty.call(frontmatter, key2)) continue;
for (const value of flattenValues(frontmatter[key2])) {
counts.set(value, (counts.get(value) ?? 0) + 1);
}
}
return counts;
}
function flattenValues(raw) {
const values = Array.isArray(raw) ? raw : [raw];
const out = [];
for (const value of values) {
if (value === null || value === void 0) continue;
if (typeof value === "object") continue;
const text2 = String(value).trim();
if (text2) out.push(text2);
}
return out;
}
function rankByCount(counts) {
return [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([value]) => value);
}
function readObsidianType(app, key2) {
const typeManager = getMetadataTypeManager(app);
if (!typeManager) return null;
const assigned = typeManager.getAssignedWidget?.(key2);
if (typeof assigned === "string") return assigned;
const registered = typeManager.getAllProperties?.()?.[key2]?.widget;
if (typeof registered === "string") return registered;
const inferred = typeManager.getTypeInfo?.(key2)?.expected?.type;
return typeof inferred === "string" ? inferred : null;
}
function addPropertyName(names, value) {
if (typeof value !== "string") return;
const trimmed = value.trim();
if (trimmed) names.add(trimmed);
}
function getMetadataTypeManager(app) {
return app.metadataTypeManager ?? null;
}
// src/Modals/GenericPrompt/promptValueContext.ts
var pending2 = null;
function setPendingValueContext(context) {
pending2 = context;
}
function consumePendingValueContext() {
const context = pending2;
pending2 = null;
return context;
}
// src/Modals/menuFilter.ts
function filterMenuItems(data, opts) {
if (!opts.enabled) return [...data];
const ignored = new Set(opts.ignoredProperties);
return data.filter((item) => {
if (ignored.has(item.key)) return false;
if (opts.hideFileTags && item.type === 2 /* Tag */) return false;
return true;
});
}
function canStructureEditProperty(property) {
if (property.type === 2 /* Tag */) return false;
return !property.isNested && !property.isVirtual;
}
// src/yamlPath.ts
var YamlPathError = class extends Error {
constructor(message) {
super(message);
this.name = "YamlPathError";
}
};
function isReservedFrontmatterKey(key2) {
return key2 === "__proto__" || key2 === "constructor" || key2 === "prototype";
}
function parseYamlPath(path) {
if (Array.isArray(path)) return validateYamlPath(path);
if (typeof path !== "string") throw new YamlPathError("YAML path must be a string or path segment array.");
const trimmed = path.trim();
if (!trimmed) throw new YamlPathError("YAML path cannot be empty.");
const segments = [];
for (const part of trimmed.split(".")) {
if (!part) throw new YamlPathError(`Invalid YAML path '${path}'. Empty path segments are not supported.`);
readPathPart(part, path, segments);
}
return validateYamlPath(segments);
}
function formatYamlPath(path) {
const validated = validateYamlPath(path);
return validated.reduce((label, segment) => {
if (typeof segment === "number") return `${label}[${segment}]`;
return label ? `${label}.${segment}` : segment;
}, "");
}
function getYamlPath(root7, path) {
const resolvedPath = parseYamlPath(path);
let current = root7;
for (const segment of resolvedPath) {
current = readYamlPathSegment(current, segment, formatYamlPath(resolvedPath));
}
return current;
}
function setYamlPath(root7, path, value, options = {}) {
const resolvedPath = parseYamlPath(path);
for (const segment of resolvedPath) {
if (typeof segment === "string" && isReservedFrontmatterKey(segment)) {
throw new YamlPathError(
`Cannot write YAML path '${formatYamlPath(resolvedPath)}': '${segment}' is a reserved property name.`
);
}
}
let current = root7;
for (let idx = 0; idx < resolvedPath.length; idx++) {
const segment = resolvedPath[idx];
const isLeaf = idx === resolvedPath.length - 1;
const location = formatYamlPath(resolvedPath.slice(0, idx + 1));
if (typeof segment === "string") {
if (!isPlainYamlObject(current)) {
throw new YamlPathError(`Cannot write YAML path '${formatYamlPath(resolvedPath)}': '${location}' is not an object.`);
}
if (isLeaf) {
validateLeafWrite(current, segment, resolvedPath, options);
current[segment] = value;
return;
}
if (!Object.prototype.hasOwnProperty.call(current, segment)) {
current[segment] = createMissingParent(options, resolvedPath[idx + 1], location);
}
current = current[segment];
continue;
}
if (!Array.isArray(current)) {
throw new YamlPathError(`Cannot write YAML path '${formatYamlPath(resolvedPath)}': '${location}' is not an array.`);
}
if (!arrayIndexExists(current, segment)) {
throw new YamlPathError(`Cannot write YAML path '${formatYamlPath(resolvedPath)}': array index ${segment} is out of range.`);
}
if (isLeaf) {
validateLeafWrite(current, segment, resolvedPath, options);
current[segment] = value;
return;
}
current = current[segment];
}
}
function isPlainYamlObject(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
return Object.prototype.toString.call(value) === "[object Object]";
}
function isYamlScalarLeaf(value) {
return !isPlainYamlObject(value) && !Array.isArray(value);
}
function isYamlParentContainerValue(value) {
if (isPlainYamlObject(value)) return true;
if (!Array.isArray(value)) return false;
return value.some((item) => isPlainYamlObject(item) || Array.isArray(item));
}
function readPathPart(part, originalPath, segments) {
const keyMatch = part.match(/^([^\[\]]+)/);
if (!keyMatch) throw new YamlPathError(`Invalid YAML path '${originalPath}'. Bracket paths must follow a property name.`);
segments.push(keyMatch[1]);
let rest = part.substring(keyMatch[1].length);
while (rest.length > 0) {
const indexMatch = rest.match(/^\[(\d+)\]/);
if (!indexMatch) throw new YamlPathError(`Invalid YAML path '${originalPath}'. Only numeric array indexes are supported.`);
segments.push(Number(indexMatch[1]));
rest = rest.substring(indexMatch[0].length);
}
}
function validateYamlPath(path) {
if (path.length === 0) throw new YamlPathError("YAML path cannot be empty.");
return path.map((segment) => {
if (typeof segment === "string") {
if (!segment) throw new YamlPathError("YAML path string segments cannot be empty.");
return segment;
}
if (!Number.isInteger(segment) || segment < 0) {
throw new YamlPathError(`YAML path array index '${segment}' must be a non-negative integer.`);
}
return segment;
});
}
function readYamlPathSegment(current, segment, pathLabel) {
if (typeof segment === "string") {
if (!isPlainYamlObject(current) || !Object.prototype.hasOwnProperty.call(current, segment)) {
throw new YamlPathError(`YAML path '${pathLabel}' does not exist.`);
}
return current[segment];
}
if (!Array.isArray(current) || !arrayIndexExists(current, segment)) {
throw new YamlPathError(`YAML path '${pathLabel}' does not exist.`);
}
return current[segment];
}
function createMissingParent(options, nextSegment, location) {
if (!options.createParents) {
throw new YamlPathError(`Cannot write YAML path: '${location}' does not exist.`);
}
if (typeof nextSegment === "number") {
throw new YamlPathError(`Cannot create array parent at '${location}'. Array creation is not supported.`);
}
return {};
}
function arrayIndexExists(array, index2) {
return index2 >= 0 && index2 < array.length && Object.prototype.hasOwnProperty.call(array, index2);
}
function validateLeafWrite(current, segment, path, options) {
const exists = typeof segment === "number" ? arrayIndexExists(current, segment) : Object.prototype.hasOwnProperty.call(current, segment);
const label = formatYamlPath(path);
if (!exists && options.createLeaf === false) {
throw new YamlPathError(`Cannot write YAML path '${label}': path does not exist.`);
}
const currentValue = typeof segment === "number" ? current[segment] : current[segment];
if (exists && options.validateExpectedValue && !yamlValuesEqual(currentValue, options.expectedValue)) {
throw new YamlPathError(`Cannot write YAML path '${label}': current value changed before update.`);
}
}
function yamlValuesEqual(left, right) {
if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();
return Object.is(left, right);
}
// src/Modals/metaEditSuggester.ts
var DELETE_PROPERTY_ICON = "trash-2";
var TRANSFORM_PROPERTY_ICON = "replace";
var DELETE_PROPERTY_TOOLTIP = "Delete property";
var TRANSFORM_PROPERTY_TOOLTIP = "Transform to YAML \u21C4 Dataview";
var MetaEditSuggester = class _MetaEditSuggester extends import_obsidian4.FuzzySuggestModal {
constructor(app, plugin, data, file, controller) {
super(app);
this.file = file;
this.app = app;
this.plugin = plugin;
this.fileKeys = new Set(data.map((prop2) => prop2.key));
const ignored = plugin.settings.IgnoredProperties;
this.data = filterMenuItems(data, {
enabled: ignored.enabled,
ignoredProperties: ignored.properties,
hideFileTags: ignored.hideFileTags
}).filter((item) => !_MetaEditSuggester.isYamlParentContainer(item));
this.controller = controller;
this.options = MAIN_SUGGESTER_OPTIONS;
this.setSuggestValues();
this.setInstructions([
{ command: "#tag", purpose: "rename in this note \xB7 vault-wide: Tag pane" }
]);
}
renderSuggestion(item, el) {
super.renderSuggestion(item, el);
if (Object.values(this.options).find((v) => v === item.item)) {
el.classList.add("metaedit-suggester-command");
} else {
if (_MetaEditSuggester.canStructureEdit(item.item)) {
this.createButton(el, DELETE_PROPERTY_ICON, DELETE_PROPERTY_TOOLTIP, this.deleteItem(item));
this.createButton(el, TRANSFORM_PROPERTY_ICON, TRANSFORM_PROPERTY_TOOLTIP, this.transformProperty(item));
}
}
}
getItemText(item) {
if (item.type === 2 /* Tag */ && item.position) {
const sameKey = this.data.filter((d) => d.type === 2 /* Tag */ && d.key === item.key && d.position).sort((a, b) => a.position.start - b.position.start);
if (sameKey.length > 1) {
const ordinal = sameKey.findIndex((d) => d.position.start === item.position.start) + 1;
const line = item.position.line !== void 0 ? `line ${item.position.line + 1}, ` : "";
return `${item.key} (${line}${ordinal}/${sameKey.length})`;
}
}
return item.key;
}
getItems() {
return [...this.options, ...this.data];
}
async onChooseItem(item, _evt) {
if (item.content === newYaml) {
await this.controller.createNewYamlPropertyFluid(this.file, this.suggestValues, this.fileKeys);
return;
}
if (item.content === newDataView) {
const newProperty = await this.controller.createNewProperty(this.suggestValues);
if (!newProperty) return null;
const { propName, propValue } = newProperty;
await this.controller.appendDataviewField(propName, propValue, this.file);
return;
}
if (_MetaEditSuggester.isYamlParentContainer(item)) return;
setPendingValueContext({ app: this.app, key: item.key, type: item.type });
try {
await this.controller.editMetaElement(item, this.data, this.file);
} finally {
setPendingValueContext(null);
}
}
deleteItem(item) {
return async (evt) => {
evt.stopPropagation();
try {
await this.controller.deleteProperty(item.item, this.file);
} finally {
this.close();
}
};
}
transformProperty(item) {
return async (evt) => {
evt.stopPropagation();
const { item: property } = item;
if (!_MetaEditSuggester.canStructureEdit(property)) return;
if (property.type !== 0 /* YAML */ && isReservedFrontmatterKey(property.key)) {
new import_obsidian4.Notice(`MetaEdit: "${property.key}" is a reserved property name and can't be a YAML property.`);
this.close();
return;
}
try {
if (property.type === 0 /* YAML */) {
await this.toDataview(property);
} else {
await this.toYaml(property);
}
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
new import_obsidian4.Notice(`MetaEdit could not transform '${property.key}': ${reason}. It may have been removed - reopen the note to check.`);
} finally {
this.close();
}
};
}
async toYaml(property) {
await this.controller.deleteProperty(property, this.file);
await this.controller.addYamlProp(property.key, property.content, this.file);
}
async toDataview(property) {
await this.controller.deleteProperty(property, this.file);
await this.controller.appendDataviewField(property.key, property.content, this.file);
}
createButton(el, iconName, tooltip, callback) {
const itemButton = el.createEl("button");
itemButton.type = "button";
itemButton.classList.add("clickable-icon", "metaedit-suggester-action-button");
itemButton.setAttribute("aria-label", tooltip);
(0, import_obsidian4.setIcon)(itemButton, iconName);
(0, import_obsidian4.setTooltip)(itemButton, tooltip);
itemButton.addEventListener("click", callback);
}
static canStructureEdit(property) {
return canStructureEditProperty(property);
}
static isYamlParentContainer(property) {
if (property.type !== 0 /* YAML */ || property.isVirtual) return false;
return isYamlParentContainerValue(property.content);
}
setSuggestValues() {
const existing = this.fileKeys;
const names = /* @__PURE__ */ new Set();
for (const autoProp of this.plugin.settings.AutoProperties.properties) {
if (!autoProp.name.startsWith("#")) names.add(autoProp.name);
}
for (const name of getKnownPropertyNames(this.app)) names.add(name);
this.suggestValues = [...names].filter((name) => !existing.has(name));
}
};
// src/parser.ts
var import_obsidian5 = require("obsidian");
var INLINE_FIELD_WRAPPERS = Object.freeze({ "[": "]", "(": ")" });
var FULL_LINE_PREFIX = /^\s*(?:>\s+)*(?:[-*+]\s+|\d+[.)]\s+)?/;
var CODE_FENCE = /^\s{0,3}(`{3,}|~{3,})/;
function matchFenceLine(line) {
const match = line.match(CODE_FENCE);
if (!match) return null;
const run3 = match[1];
return { char: run3[0], len: run3.length, bare: line.slice(match[0].length).trim() === "" };
}
function nextFenceState(openFence, line) {
const fence = matchFenceLine(line);
if (!fence) return { open: openFence, boundary: null };
if (openFence === null) return { open: { char: fence.char, len: fence.len }, boundary: "open" };
if (fence.char === openFence.char && fence.len >= openFence.len && fence.bare) {
return { open: null, boundary: "close" };
}
return { open: openFence, boundary: null };
}
var MetaEditParser = class {
constructor(app) {
this.app = app;
}
async getTagsForFile(file) {
const cache = this.app.metadataCache.getFileCache(file);
if (!cache) return [];
const tags = cache.tags;
if (!tags) return [];
return tags.map((tag2) => ({
key: tag2.tag,
content: tag2.tag,
type: 2 /* Tag */,
position: { start: tag2.position.start.offset, end: tag2.position.end.offset, line: tag2.position.start.line }
}));
}
async parseFrontmatter(file) {
const frontmatter = await this.parseFrontmatterObject(file);
if (!frontmatter) return [];
return this.objectToYamlProperties(frontmatter);
}
parseFrontmatterCache(fileCache) {
const frontmatter = fileCache?.frontmatter;
if (!frontmatter) return [];
return this.objectToYamlProperties(frontmatter, true);
}
async parseFrontmatterObject(file) {
const fileCache = this.app.metadataCache.getFileCache(file);
const filecontent = await this.app.vault.cachedRead(file);
const parsedYaml = this.parseFrontmatterContent(filecontent);
if (this.isFrontmatterObject(parsedYaml)) return parsedYaml;
const frontmatter = fileCache?.frontmatter;
if (this.isFrontmatterObject(frontmatter)) return this.omitInternalFrontmatterPosition(frontmatter);
return null;
}
isFrontmatterObject(value) {
return isPlainYamlObject(value);
}
omitInternalFrontmatterPosition(frontmatter) {
if (!this.isFrontmatterPosition(frontmatter.position)) return frontmatter;
const cleaned = { ...frontmatter };
delete cleaned.position;
return cleaned;
}
isFrontmatterPosition(position) {
if (!position || typeof position !== "object") return false;
const candidate = position;
return this.isPosition(candidate.start) && this.isPosition(candidate.end);
}
isPosition(position) {
if (!position || typeof position !== "object") return false;
const candidate = position;
return typeof candidate.line === "number" && typeof candidate.col === "number" && typeof candidate.offset === "number";
}
objectToYamlProperties(parsedYaml, omitInternalPosition = false) {
if (!this.isFrontmatterObject(parsedYaml)) return [];
const rootProperties = [];
const nestedProperties = [];
for (const key2 in parsedYaml) {
const value = parsedYaml[key2];
if (omitInternalPosition && key2 === "position" && this.isFrontmatterPosition(value)) continue;
rootProperties.push({ key: key2, content: value, type: 0 /* YAML */ });
this.collectNestedYamlProperties(value, [key2], nestedProperties);
}
return [...rootProperties, ...nestedProperties];
}
collectNestedYamlProperties(value, path, properties) {
if (isYamlScalarLeaf(value)) {
if (path.length > 1 && typeof path[path.length - 1] !== "number") {
const rootKey = String(path[0]);
properties.push({
key: formatYamlPath(path),
content: value,
type: 0 /* YAML */,
path: [...path],
rootKey,
isNested: true,
isVirtual: true
});
}
return;
}
if (Array.isArray(value)) {
value.forEach((item, idx) => this.collectNestedYamlProperties(item, [...path, idx], properties));
return;
}
if (isPlainYamlObject(value)) {
for (const key2 in value) {
this.collectNestedYamlProperties(value[key2], [...path, key2], properties);
}
}
}
async parseInlineFields(file) {
const content = await this.app.vault.cachedRead(file);
return this.parseInlineContent(content);
}
/**
* Extract inline `key:: value` fields from raw note content.
*
* Mirrors Dataview's two-mode model: bracketed fields (`[k:: v]` / `(k:: v)`)
* take precedence over a single "full-line" field, and a line yields one or
* the other - never both. Keys are returned clean (without leading list or
* blockquote markers) so callers can match and round-trip them; the
* full-line key is otherwise kept verbatim so odd-but-real keys like
* `progress (%)` survive a read/write cycle.
*/
parseInlineContent(content) {
const properties = [];
for (const line of this.walkInlineContentLines(content)) {
if (!line.readable) continue;
if (!line.text.includes("::")) continue;
for (const field of this.parseLineFields(line.text)) {
properties.push({ key: field.key, content: field.value, type: 1 /* Dataview */ });
}
}
return properties;
}
parseFrontmatterContent(content) {
const frontmatterInfo = this.getFrontmatterInfo(content);
if (!frontmatterInfo?.exists) return null;
try {
return (0, import_obsidian5.parseYaml)(frontmatterInfo.frontmatter);
} catch {
return null;
}
}
getFrontmatterInfo(content) {
const info = (0, import_obsidian5.getFrontMatterInfo)(content);
const legacyDotInfo = this.getLegacyDotCloseFrontmatterInfo(content);
if (legacyDotInfo && (!info.exists || legacyDotInfo.contentStart < info.contentStart))
return legacyDotInfo;
if (info.exists) return info;
return null;
}
getLegacyDotCloseFrontmatterInfo(content) {
const lines = this.splitContentLines(content);
if (!/^---\s*$/.test(lines[0]?.text ?? "")) return null;
for (let i = 1; i < lines.length; i++) {
if (!/^\.\.\.\s*$/.test(lines[i].text)) continue;
const from = lines[0].nextStart;
const to = lines[i].start;
return {
exists: true,
frontmatter: content.slice(from, to),
from,
to,
contentStart: lines[i].nextStart
};
}
return null;
}
splitContentLines(content) {
const textLines = content.split(/\r?\n/);
const lines = [];
let offset = 0;
for (let i = 0; i < textLines.length; i++) {
const text2 = textLines[i];
const start = offset;
const end = start + text2.length;
let nextStart = end;
if (i < textLines.length - 1) {
nextStart += content.startsWith("\r\n", end) ? 2 : 1;
}
lines.push({ text: text2, start, end, nextStart });
offset = nextStart;
}
return lines;
}
*walkInlineContentLines(content) {
const lines = this.splitContentLines(content);
const frontmatterInfo = this.getFrontmatterInfo(content);
let openFence = null;
for (let index2 = 0; index2 < lines.length; index2++) {
const line = lines[index2];
const inFrontmatter = frontmatterInfo?.exists === true && line.start < frontmatterInfo.contentStart;
if (inFrontmatter) {
yield { ...line, index: index2, inFrontmatter, fenceBoundary: null, readable: false };
continue;
}
const { open, boundary: boundary2 } = nextFenceState(openFence, line.text);
openFence = open;
yield {
...line,
index: index2,
inFrontmatter: false,
fenceBoundary: boundary2,
readable: boundary2 === null && openFence === null
};
}
}
parseLineFields(line) {
const bracketed = this.extractBracketedFields(line);
if (bracketed.length > 0) return bracketed;
const fullLine = this.extractFullLineField(line);
return fullLine ? [fullLine] : [];
}
extractBracketedFields(line) {
const fields = [];
for (const open of Object.keys(INLINE_FIELD_WRAPPERS)) {
let idx = line.indexOf(open);
while (idx >= 0) {
const field = this.findBracketedField(line, idx);
if (!field) {
idx = line.indexOf(open, idx + 1);
continue;
}
fields.push(field);
idx = line.indexOf(open, field.end);
}
}
fields.sort((a, b) => a.start - b.start);
const kept = [];
for (const field of fields) {
if (kept.length === 0 || kept[kept.length - 1].end <= field.start) {
kept.push(field);
}
}
return kept;
}
findBracketedField(line, start) {
const open = line[start];
const close = INLINE_FIELD_WRAPPERS[open];
const sep = line.indexOf("::", start + 1);
if (sep < 0) return null;
const key2 = line.substring(start + 1, sep).trim();
if (!key2 || /[[\]()]/.test(key2)) return null;
const closing = this.findClosingBracket(line, sep + 2, open, close);
if (!closing) return null;
return { key: key2, value: closing.value, start, end: closing.end, sepEnd: sep + 2, valueEnd: closing.end - 1 };
}
findClosingBracket(line, start, open, close) {
let nesting = 0;
for (let i = start; i < line.length; i++) {
const char = line[i];
if (char === open) {
nesting++;
} else if (char === close) {
if (nesting === 0) {
return { value: line.substring(start, i).trim(), end: i + 1 };
}
nesting--;
}
}
return null;
}
extractFullLineField(line) {
const lineEnd = line.endsWith("\r") ? line.length - 1 : line.length;
const prefix = line.match(FULL_LINE_PREFIX)?.[0] ?? "";
const body = line.slice(prefix.length, lineEnd);
const sep = body.indexOf("::");
if (sep < 0) return null;
const key2 = body.substring(0, sep).trim();
if (!key2) return null;
const value = body.substring(sep + 2).trim();
const sepEnd = prefix.length + sep + 2;
return { key: key2, value, start: prefix.length, end: lineEnd, sepEnd, valueEnd: lineEnd };
}
/**
* Rewrite the value of every inline field named `key` on a single line,
* leaving the key, surrounding text, and any `[...]`/`(...)` wrapper intact.
*
* This is the write-side counterpart to {@link parseInlineContent}: because
* it reuses the same field boundaries, a full-line value (which may itself
* contain `]`/`)`, e.g. `ref:: [[Note]]`) is replaced up to end-of-line and a
* bracketed value only up to its matching close bracket - so updates no
* longer append a stray closing bracket. Returns the line unchanged when no
* field matches.
*/
replaceInlineFieldValue(line, key2, newValue) {
const matches = this.parseLineFields(line).filter((field) => field.key === key2);
if (matches.length === 0) return line;
let result = line;
for (let i = matches.length - 1; i >= 0; i--) {
const field = matches[i];
result = result.slice(0, field.sepEnd) + " " + newValue + result.slice(field.valueEnd);
}
return result;
}
/**
* Rewrite inline field values in raw note content using the same readable-line
* boundary as {@link parseInlineContent}. Only the changed line spans are
* replaced; all untouched bytes, including mixed CRLF/LF line endings, are
* preserved exactly.
*/
replaceInlineFieldValuesInContent(content, replacements) {
const activeReplacements = replacements.filter(({ key: key2 }) => key2.length > 0);
if (activeReplacements.length === 0) return content;
let result = "";
let cursor = 0;
for (const line of this.walkInlineContentLines(content)) {
if (!line.readable) continue;
if (!line.text.includes("::")) continue;
let updatedLine = line.text;
for (const { key: key2, value } of activeReplacements) {
updatedLine = this.replaceInlineFieldValue(updatedLine, key2, value);
}
if (updatedLine === line.text) continue;
result += content.slice(cursor, line.start) + updatedLine;
cursor = line.end;
}
if (cursor === 0) return content;
return result + content.slice(cursor);
}
/**
* Compute the line index at which to splice a new `name:: value` inline field.
*
* This is the write-placement counterpart to {@link parseInlineContent}: it walks
* the content with the SAME frontmatter, fenced-code, and inline-field detection so
* the insertion point is always consistent with what MetaEdit reads as a field. The
* returned index is into `content.split(/\r?\n/)` (the same split
* {@link splitContentLines} performs), so a caller can splice directly.
*
* Guarantees: the index is never inside YAML frontmatter or a fenced code block.
* - "afterLastMatch": just after the last body line that declares `name` (full-line
* or bracketed), falling back to "end" when there is no such field.
* - "end": just after the last body content line or trailing closing code fence.
* When the note has no body content (empty or frontmatter-only), the field is placed
* at the start of the body, or at the very end when the whole file is frontmatter.
*/
computeInlineInsertIndex(content, name, location = "afterLastMatch") {
let lastMatchIdx = -1;
let lastAnchorIdx = -1;
let firstBodyIdx = -1;
let lineCount = 0;
for (const line of this.walkInlineContentLines(content)) {
lineCount = line.index + 1;
if (line.inFrontmatter) continue;
if (firstBodyIdx === -1) firstBodyIdx = line.index;
if (line.fenceBoundary === "open") continue;
if (line.fenceBoundary === "close") {
lastAnchorIdx = line.index;
continue;
}
if (!line.readable) continue;
if (line.text.trim() !== "") lastAnchorIdx = line.index;
if (line.text.includes("::") && this.parseLineFields(line.text).some((field) => field.key === name)) {
lastMatchIdx = line.index;
}
}
if (location === "afterLastMatch" && lastMatchIdx !== -1) return lastMatchIdx + 1;
if (lastAnchorIdx !== -1) return lastAnchorIdx + 1;
return firstBodyIdx !== -1 ? firstBodyIdx : lineCount;
}
};
// src/Modals/GenericPrompt/GenericPrompt.ts
var import_obsidian7 = require("obsidian");
// src/Modals/GenericPrompt/genericTextSuggester.ts
var import_obsidian6 = require("obsidian");
var GenericTextSuggester = class extends import_obsidian6.AbstractInputSuggest {
constructor(app, inputEl, items) {
super(app, inputEl);
this.inputEl = inputEl;
this.items = items;
this.onSelect((item) => this.acceptSuggestion(item));
}
getSuggestions(inputStr) {
return filterSuggestions(this.items, inputStr);
}
acceptSuggestion(item) {
this.setValue(item);
this.inputEl.trigger("input");
this.close();
}
renderSuggestion(value, el) {
if (value)
el.setText(value);
}
refreshSuggestions() {
this.inputEl.trigger("input");
}
};
// src/Modals/GenericPrompt/GenericPromptContent.svelte
var root5 = from_html(`<input class="metaEditPromptInput metadata-input metadata-input-text mod-date" style="width: 100%;" type="date"/>`);
var root_15 = from_html(`<input class="metaEditPromptInput metadata-input metadata-input-text mod-datetime" style="width: 100%;" type="datetime-local"/>`);
var root_23 = from_html(`<input class="metaEditPromptInput" style="width: 100%;" type="text"/>`);
var root_32 = from_html(`<div class="metaEditPrompt"><h1 style="text-align: center"> </h1> <!></div>`);
function GenericPromptContent($$anchor, $$props) {
push($$props, true);
let header = prop($$props, "header", 3, ""), placeholder = prop($$props, "placeholder", 3, ""), propValue = prop($$props, "value", 3, ""), suggestValues = prop($$props, "suggestValues", 19, () => []);
const initialApp = untrack(() => $$props.app);
const initialSuggestValues = untrack(() => suggestValues());
const initialValue = untrack(() => propValue());
let value = state(proxy(initialValue));
let suggester;
let inputEl = state(void 0);
const context = consumePendingValueContext();
const hasExplicitSuggestions = Array.isArray(initialSuggestValues) && initialSuggestValues.length > 0;
const dateInputType = !hasExplicitSuggestions && context ? getDateInputType(context.app, context.key, initialValue, context.type) : null;
const datetimeStep = dateInputType === "datetime" && /T\d{2}:\d{2}:\d{2}/.test(initialValue) ? "1" : void 0;
let didInitialise = false;
user_effect(() => {
const el = get2(inputEl);
if (!el || didInitialise) return;
didInitialise = true;
let suggestions = [];
if (!dateInputType) {
suggestions = hasExplicitSuggestions ? initialSuggestValues : context ? getValueSuggestions(context.app, context.key, context.type, context.tagMode) : [];
}
el.focus();
if (!dateInputType) el.select();
if (!dateInputType && suggestions.length > 0) {
suggester = new GenericTextSuggester(initialApp, el, suggestions);
}
if (suggester && !initialValue) suggester.refreshSuggestions();
return () => {
suggester?.close();
suggester = void 0;
};
});
function submit(evt) {
if (evt.key === "Enter") {
evt.preventDefault();
$$props.onSubmit(get2(value));
}
}
var div = root_32();
var h1 = child(div);
var text2 = child(h1, true);
reset(h1);
var node = sibling(h1, 2);
{
var consequent = ($$anchor2) => {
var input = root5();
remove_input_defaults(input);
bind_this(input, ($$value) => set(inputEl, $$value), () => get2(inputEl));
delegated("keydown", input, submit);
bind_value(input, () => get2(value), ($$value) => set(value, $$value));
append($$anchor2, input);
};
var consequent_1 = ($$anchor2) => {
var input_1 = root_15();
remove_input_defaults(input_1);
bind_this(input_1, ($$value) => set(inputEl, $$value), () => get2(inputEl));
template_effect(() => set_attribute2(input_1, "step", datetimeStep));
delegated("keydown", input_1, submit);
bind_value(input_1, () => get2(value), ($$value) => set(value, $$value));
append($$anchor2, input_1);
};
var alternate = ($$anchor2) => {
var input_2 = root_23();
remove_input_defaults(input_2);
bind_this(input_2, ($$value) => set(inputEl, $$value), () => get2(inputEl));
template_effect(() => set_attribute2(input_2, "placeholder", placeholder()));
delegated("keydown", input_2, submit);
bind_value(input_2, () => get2(value), ($$value) => set(value, $$value));
append($$anchor2, input_2);
};
if_block(node, ($$render) => {
if (dateInputType === "date") $$render(consequent);
else if (dateInputType === "datetime") $$render(consequent_1, 1);
else $$render(alternate, -1);
});
}
reset(div);
template_effect(() => set_text(text2, header()));
append($$anchor, div);
pop();
}
delegate(["keydown"]);
// src/Modals/GenericPrompt/GenericPrompt.ts
var GenericPrompt = class _GenericPrompt extends import_obsidian7.Modal {
constructor(app, header, placeholder, value, suggestValues) {
super(app);
this.didSubmit = false;
this.modalContent = mountSvelteComponent(
GenericPromptContent,
this.contentEl,
{
app,
header,
placeholder,
value,
suggestValues,
onSubmit: (input) => {
this.input = input;
this.didSubmit = true;
this.close();
}
}
);
this.waitForClose = new Promise(
(resolve) => {
this.resolvePromise = resolve;
}
);
this.open();
}
static Prompt(app, header, placeholder, value, suggestValues) {
const newPromptModal = new _GenericPrompt(app, header, placeholder, value, suggestValues);
return newPromptModal.waitForClose;
}
onOpen() {
super.onOpen();
const modalPrompt = activeDocument.querySelector(".metaEditPrompt");
const modalInput = modalPrompt?.querySelector(".metaEditPromptInput");
modalInput?.focus();
if (modalInput?.type === "text") modalInput.select();
}
onClose() {
super.onClose();
unmountSvelteComponent(this.modalContent);
if (!this.didSubmit) this.resolvePromise(null);
else this.resolvePromise(this.input);
}
};
// src/Modals/GenericSuggester/GenericSuggester.ts
var import_obsidian8 = require("obsidian");
var GenericSuggester = class _GenericSuggester extends import_obsidian8.FuzzySuggestModal {
constructor(app, displayItems, items) {
super(app);
this.displayItems = displayItems;
this.items = items;
this.didChoose = false;
this.promise = new Promise(
(resolve) => this.resolvePromise = resolve
);
this.open();
}
static Suggest(app, displayItems, items) {
const newSuggester = new _GenericSuggester(app, displayItems, items);
return newSuggester.promise;
}
getItemText(item) {
return this.displayItems[this.items.indexOf(item)];
}
getItems() {
return this.items;
}
onChooseItem(item, _evt) {
this.didChoose = true;
this.resolvePromise(item);
}
onClose() {
super.onClose();
queueMicrotask(() => {
if (!this.didChoose) this.resolvePromise("");
});
}
};
// src/metaController.ts
var import_obsidian16 = require("obsidian");
// src/Modals/AutoPropertyValueModal/AutoPropertyValueModal.ts
var import_obsidian10 = require("obsidian");
// src/Modals/AutoPropertyValueModal/AutoPropertyValueModalContent.svelte
var import_obsidian9 = require("obsidian");
var root6 = from_html(`<div class="metaedit-ap-prompt-desc svelte-rukrzs"> </div>`);
var root_16 = from_html(`<span class="metaedit-ap-prompt-tag svelte-rukrzs">new</span>`);
var root_24 = from_html(`<label class="metaedit-ap-prompt-row metaedit-ap-prompt-check svelte-rukrzs"><input type="checkbox" class="svelte-rukrzs"/> <span class="metaedit-ap-prompt-row-label svelte-rukrzs"> </span> <!></label>`);
var root_33 = from_html(`<div class="metaedit-ap-prompt-empty svelte-rukrzs">No values yet - type one above and press Enter.</div>`);
var root_42 = from_html(`<label class="metaedit-ap-prompt-savenew svelte-rukrzs"><input type="checkbox"/> Also add new values to this property's choice list</label>`);
var root_5 = from_html(`<input class="metaedit-ap-prompt-input svelte-rukrzs" type="text" placeholder="Type a value and press Enter to add it"/> <div class="metaedit-ap-prompt-list svelte-rukrzs" role="listbox" aria-multiselectable="true"></div> <!> <div class="metaedit-ap-prompt-actions svelte-rukrzs"><button class="mod-cta">Confirm</button></div>`, 1);
var root_6 = from_html(`<span class="metaedit-ap-prompt-row-icon svelte-rukrzs"></span>`);
var root_7 = from_html(`<button><!> <span class="metaedit-ap-prompt-row-label svelte-rukrzs"> </span></button>`);
var root_8 = from_html(`<div class="metaedit-ap-prompt-empty svelte-rukrzs">No choices defined - type a value and press Enter.</div>`);
var root_9 = from_html(`<input class="metaedit-ap-prompt-input svelte-rukrzs" type="text" placeholder="Pick a value, or type a new one"/> <div class="metaedit-ap-prompt-list svelte-rukrzs" role="listbox"></div>`, 1);
var root_10 = from_html(`<div class="metaedit-ap-prompt svelte-rukrzs"><div class="metaedit-ap-prompt-head svelte-rukrzs"><div class="metaedit-ap-prompt-title svelte-rukrzs"> </div> <!></div> <!></div>`);
var $$css5 = {
hash: "svelte-rukrzs",
code: ".metaedit-ap-prompt.svelte-rukrzs {display:flex;flex-direction:column;gap:0.6rem;}.metaedit-ap-prompt-head.svelte-rukrzs {display:flex;flex-direction:column;gap:0.15rem;}.metaedit-ap-prompt-title.svelte-rukrzs {font-size:var(--font-ui-large, 1.1em);font-weight:var(--font-semibold, 600);color:var(--text-normal);}.metaedit-ap-prompt-desc.svelte-rukrzs {color:var(--text-muted);font-size:var(--font-ui-small, 0.85em);line-height:1.4;}.metaedit-ap-prompt-input.svelte-rukrzs {width:100%;}.metaedit-ap-prompt-list.svelte-rukrzs {display:flex;flex-direction:column;gap:2px;max-height:16rem;overflow-y:auto;}.metaedit-ap-prompt-row.svelte-rukrzs {display:flex;align-items:center;gap:0.5rem;width:100%;text-align:left;padding:0.4rem 0.55rem;border-radius:var(--radius-s, 4px);background:transparent;box-shadow:none;color:var(--text-normal);cursor:pointer;font-size:var(--font-ui-medium, 1em);}.metaedit-ap-prompt-row.is-selected.svelte-rukrzs {background-color:var(--background-modifier-hover);}.metaedit-ap-prompt-action.svelte-rukrzs {color:var(--text-muted);}.metaedit-ap-prompt-check.svelte-rukrzs {cursor:pointer;}.metaedit-ap-prompt-check.svelte-rukrzs input:where(.svelte-rukrzs) {margin:0;}.metaedit-ap-prompt-row-icon.svelte-rukrzs {display:inline-flex;align-items:center;}.metaedit-ap-prompt-row-label.svelte-rukrzs {flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.metaedit-ap-prompt-tag.svelte-rukrzs {flex:0 0 auto;font-size:var(--font-ui-smaller, 0.75em);color:var(--text-accent);border:1px solid var(--background-modifier-border);border-radius:var(--radius-s, 4px);padding:0 0.3rem;}.metaedit-ap-prompt-empty.svelte-rukrzs {color:var(--text-muted);padding:0.4rem 0.55rem;font-size:var(--font-ui-small, 0.85em);}.metaedit-ap-prompt-savenew.svelte-rukrzs {display:flex;align-items:center;gap:0.45rem;color:var(--text-muted);font-size:var(--font-ui-small, 0.85em);cursor:pointer;}.metaedit-ap-prompt-actions.svelte-rukrzs {display:flex;justify-content:flex-end;}"
};
function AutoPropertyValueModalContent($$anchor, $$props) {
push($$props, true);
append_styles($$anchor, $$css5);
let isMulti = prop($$props, "isMulti", 3, false), currentValue = prop($$props, "currentValue", 3, null);
const initialAutoProperty = untrack(() => $$props.autoProperty);
const initialIsMulti = untrack(() => isMulti());
const initialCurrentValue = untrack(() => currentValue());
const choices = normalizeChoices(initialAutoProperty.choices);
let inputEl = state(void 0);
let query = state("");
let highlight = state(0);
function icon(node, name) {
node.textContent = "";
(0, import_obsidian9.setIcon)(node, name);
return {};
}
let trimmedQuery = user_derived(() => get2(query).trim());
let filtered = user_derived(() => choices.filter((c) => c.toLowerCase().includes(get2(trimmedQuery).toLowerCase())));
let exactMatch = user_derived(() => choices.some((c) => c.toLowerCase() === get2(trimmedQuery).toLowerCase()));
let singleItems = user_derived(() => buildSingleItems(get2(filtered), get2(trimmedQuery), get2(exactMatch)));
user_effect(() => {
const maxHighlight = Math.max(0, get2(singleItems).length - 1);
if (get2(highlight) > maxHighlight) set(highlight, maxHighlight, true);
});
function buildSingleItems(matches, q, exact) {
const items = matches.map((c) => ({ kind: "choice", value: c, label: c }));
if (q !== "" && !exact) {
items.push({ kind: "use", value: q, label: `Use "${q}"` });
items.push({ kind: "save", value: q, label: `Save "${q}" as a choice` });
}
return items;
}
async function persistChoices(values) {
try {
await $$props.onSaveChoices(values);
} catch (e) {
console.error("MetaEdit: failed to save new auto property choice", e);
}
}
async function chooseSingle(item) {
if (!item) return;
if (item.kind === "save") {
await persistChoices([item.value]);
}
$$props.onSubmit(item.value);
}
function onSingleKeydown(e) {
if (e.key === "ArrowDown") {
e.preventDefault();
set(highlight, Math.min(get2(highlight) + 1, get2(singleItems).length - 1), true);
} else if (e.key === "ArrowUp") {
e.preventDefault();
set(highlight, Math.max(get2(highlight) - 1, 0), true);
} else if (e.key === "Enter") {
e.preventDefault();
if (get2(singleItems).length > 0) chooseSingle(get2(singleItems)[get2(highlight)]);
else if (get2(trimmedQuery) !== "") $$props.onSubmit(get2(trimmedQuery));
}
}
let options = state(proxy(untrack(() => initialIsMulti ? multiSelectOptions(initialAutoProperty, initialCurrentValue) : [])));
let checkedValues = state(proxy(untrack(() => toValueArray(initialCurrentValue))));
let saveNew = state(false);
let newCheckedValues = user_derived(() => get2(options).filter((o) => get2(checkedValues).includes(o) && !choices.includes(o)));
function toggleCheck(value) {
set(
checkedValues,
get2(checkedValues).includes(value) ? get2(checkedValues).filter((checkedValue) => checkedValue !== value) : [...get2(checkedValues), value],
true
);
}
function addMultiValue() {
const value = get2(query).trim();
if (value === "") return;
if (!get2(options).includes(value)) set(options, [...get2(options), value], true);
if (!get2(checkedValues).includes(value)) set(checkedValues, [...get2(checkedValues), value], true);
set(query, "");
}
function onMultiAddKeydown(e) {
if (e.key === "Enter") {
e.preventDefault();
addMultiValue();
}
}
async function confirmMulti() {
const result = get2(options).filter((o) => get2(checkedValues).includes(o));
if (get2(saveNew) && get2(newCheckedValues).length > 0) {
await persistChoices(get2(newCheckedValues));
}
$$props.onSubmit(result);
}
let didFocus = false;
user_effect(() => {
const el = get2(inputEl);
if (!el || didFocus) return;
didFocus = true;
el.focus();
});
var div = root_10();
var div_1 = child(div);
var div_2 = child(div_1);
var text2 = child(div_2, true);
reset(div_2);
var node_1 = sibling(div_2, 2);
{
var consequent = ($$anchor2) => {
var div_3 = root6();
var text_1 = child(div_3, true);
reset(div_3);
template_effect(() => set_text(text_1, initialAutoProperty.description));
append($$anchor2, div_3);
};
if_block(node_1, ($$render) => {
if (initialAutoProperty.description) $$render(consequent);
});
}
reset(div_1);
var node_2 = sibling(div_1, 2);
{
var consequent_3 = ($$anchor2) => {
var fragment = root_5();
var input = first_child(fragment);
remove_input_defaults(input);
bind_this(input, ($$value) => set(inputEl, $$value), () => get2(inputEl));
var div_4 = sibling(input, 2);
each(
div_4,
20,
() => get2(options),
(option) => option,
($$anchor3, option) => {
var label = root_24();
var input_1 = child(label);
remove_input_defaults(input_1);
var span = sibling(input_1, 2);
var text_2 = child(span, true);
reset(span);
var node_3 = sibling(span, 2);
{
var consequent_1 = ($$anchor4) => {
var span_1 = root_16();
append($$anchor4, span_1);
};
var d = user_derived(() => !choices.includes(option));
if_block(node_3, ($$render) => {
if (get2(d)) $$render(consequent_1);
});
}
reset(label);
template_effect(
($0) => {
set_checked(input_1, $0);
set_text(text_2, option);
},
[() => get2(checkedValues).includes(option)]
);
delegated("change", input_1, () => toggleCheck(option));
append($$anchor3, label);
},
($$anchor3) => {
var div_5 = root_33();
append($$anchor3, div_5);
}
);
reset(div_4);
var node_4 = sibling(div_4, 2);
{
var consequent_2 = ($$anchor3) => {
var label_1 = root_42();
var input_2 = child(label_1);
remove_input_defaults(input_2);
next();
reset(label_1);
bind_checked(input_2, () => get2(saveNew), ($$value) => set(saveNew, $$value));
append($$anchor3, label_1);
};
if_block(node_4, ($$render) => {
if (get2(newCheckedValues).length > 0) $$render(consequent_2);
});
}
var div_6 = sibling(node_4, 2);
var button = child(div_6);
reset(div_6);
delegated("keydown", input, onMultiAddKeydown);
bind_value(input, () => get2(query), ($$value) => set(query, $$value));
delegated("click", button, confirmMulti);
append($$anchor2, fragment);
};
var alternate = ($$anchor2) => {
var fragment_1 = root_9();
var input_3 = first_child(fragment_1);
remove_input_defaults(input_3);
bind_this(input_3, ($$value) => set(inputEl, $$value), () => get2(inputEl));
var div_7 = sibling(input_3, 2);
each(
div_7,
23,
() => get2(singleItems),
(item) => item.kind + item.value,
($$anchor3, item, i) => {
var button_1 = root_7();
let classes;
var node_5 = child(button_1);
{
var consequent_4 = ($$anchor4) => {
var span_2 = root_6();
action(span_2, ($$node, $$action_arg) => icon?.($$node, $$action_arg), () => "plus");
append($$anchor4, span_2);
};
var consequent_5 = ($$anchor4) => {
var span_3 = root_6();
action(span_3, ($$node, $$action_arg) => icon?.($$node, $$action_arg), () => "corner-down-left");
append($$anchor4, span_3);
};
if_block(node_5, ($$render) => {
if (get2(item).kind === "save") $$render(consequent_4);
else if (get2(item).kind === "use") $$render(consequent_5, 1);
});
}
var span_4 = sibling(node_5, 2);
var text_3 = child(span_4, true);
reset(span_4);
reset(button_1);
template_effect(() => {
classes = set_class(button_1, 1, "metaedit-ap-prompt-row svelte-rukrzs", null, classes, {
"is-selected": get2(i) === get2(highlight),
"metaedit-ap-prompt-action": get2(item).kind !== "choice"
});
set_text(text_3, get2(item).label);
});
delegated("click", button_1, () => chooseSingle(get2(item)));
event("mouseenter", button_1, () => set(highlight, get2(i), true));
append($$anchor3, button_1);
},
($$anchor3) => {
var div_8 = root_8();
append($$anchor3, div_8);
}
);
reset(div_7);
delegated("keydown", input_3, onSingleKeydown);
bind_value(input_3, () => get2(query), ($$value) => set(query, $$value));
append($$anchor2, fragment_1);
};
if_block(node_2, ($$render) => {
if (initialIsMulti) $$render(consequent_3);
else $$render(alternate, -1);
});
}
reset(div);
template_effect(() => set_text(text2, initialAutoProperty.name));
append($$anchor, div);
pop();
}
delegate(["keydown", "change", "click"]);
// src/Modals/AutoPropertyValueModal/AutoPropertyValueModal.ts
var AutoPropertyValueModal = class _AutoPropertyValueModal extends import_obsidian10.Modal {
constructor(app, autoProperty, options) {
super(app);
this.result = null;
this.didSubmit = false;
this.waitForClose = new Promise((resolve) => this.resolvePromise = resolve);
this.content = mountSvelteComponent(
AutoPropertyValueModalContent,
this.contentEl,
{
autoProperty,
isMulti: options.isMulti,
currentValue: options.currentValue ?? null,
onSaveChoices: options.onSaveChoices,
onSubmit: (value) => {
this.result = value;
this.didSubmit = true;
this.close();
}
}
);
this.open();
}
static Show(app, autoProperty, options) {
return new _AutoPropertyValueModal(app, autoProperty, options).waitForClose;
}
onClose() {
super.onClose();
unmountSvelteComponent(this.content);
this.resolvePromise(this.didSubmit ? this.result : null);
}
};
// src/tagEditing.ts
function stripHash(tag2) {
return tag2.replace(/^#+/, "");
}
function isNestedTag(tag2) {
return stripHash(tag2).includes("/");
}
function tagLeaf(tag2) {
const body = stripHash(tag2);
return body.split("/").pop() ?? "";
}
function tagParent(tag2) {
const segments = stripHash(tag2).split("/");
segments.pop();
return `#${segments.join("/")}`;
}
function computeTagRewrite(oldTag, input, mode) {
const value = input.trim();
if (mode === "tracker") {
return value === "" ? "" : `${oldTag}:${value}`;
}
const normalized = stripHash(value);
if (normalized === "") return "";
if (mode === "leaf") {
return `${tagParent(oldTag)}/${normalized}`;
}
return `#${normalized}`;
}
var TRACKER_VALUE = "[A-Za-z0-9._+-]+";
function isTrackerToken(token) {
return new RegExp(`^#[^\\s:]+:${TRACKER_VALUE}$`).test(token);
}
function normalizeTagToken(value) {
const trimmed = value.trim();
if (trimmed === "") return "";
return `#${trimmed.replace(/^#+/, "")}`;
}
function isValidTagToken(token) {
if (!token.startsWith("#")) return false;
const tracker = token.match(new RegExp(`^(#.+?):${TRACKER_VALUE}$`, "u"));
const body = (tracker ? tracker[1] : token).slice(1);
if (!/^[\p{L}\p{N}_/-]+$/u.test(body)) return false;
return /[^\d/]/u.test(body);
}
function spliceTag(content, position, expectedTag, newToken) {
if (!position) return null;
const { start, end } = position;
if (!Number.isInteger(start) || !Number.isInteger(end)) return null;
if (start < 0 || end > content.length || start >= end) return null;
if (content.slice(start, end) !== expectedTag) return null;
let cutEnd = end;
if (isTrackerToken(newToken)) {
const existingSuffix = content.slice(end).match(new RegExp(`^:${TRACKER_VALUE}`));
if (existingSuffix) cutEnd = end + existingSuffix[0].length;
}
return content.slice(0, start) + newToken + content.slice(cutEnd);
}
var TAG_FRONTMATTER_KEYS = /* @__PURE__ */ new Set(["tags", "tag"]);
function isTagsKey(key2) {
return !!key2 && TAG_FRONTMATTER_KEYS.has(key2.toLowerCase());
}
function canonicalizeFrontmatterTag(value) {
return stripHash(value.trim()).trim();
}
function splitFrontmatterTags(content) {
const items = Array.isArray(content) ? content : [content];
const out = [];
for (const item of items) {
if (item === null || item === void 0 || typeof item === "object") continue;
for (const token of String(item).split(/[\s,]+/)) {
const tag2 = canonicalizeFrontmatterTag(token);
if (tag2) out.push(tag2);
}
}
return out;
}
// src/multiValue.ts
function isMultiValueYamlProperty(property) {
return property.type === 0 /* YAML */ && Array.isArray(property.content);
}
function shouldUseMultiValueEditor(property, editMode) {
if (isMultiValueYamlProperty(property)) return true;
if (property.type === 0 /* YAML */ && isTagsKey(property.key)) return true;
if (editMode.mode === "All Multi" /* AllMulti */) return true;
if (editMode.mode === "Some Multi" /* SomeMulti */ && !!property.key && editMode.properties.includes(property.key)) {
return true;
}
return false;
}
function applyMultiValueEdit(base, edit) {
switch (edit.kind) {
case "addFirst":
return [edit.value];
case "prepend":
return [edit.value, ...base];
case "append":
return [...base, edit.value];
case "replace": {
if (edit.index < 0 || edit.index >= base.length) return [edit.value];
const next2 = [...base];
next2[edit.index] = edit.value;
return next2;
}
}
}
// src/Modals/NativePropertyPrompt/NativePropertyPrompt.ts
var import_obsidian14 = require("obsidian");
// src/typedProperties/nativePropertyTypes.ts
var STANDARD_NATIVE_PROPERTY_TYPES = [
"text",
"multitext",
"number",
"checkbox",
"date",
"datetime",
"tags",
"aliases",
"cssclasses"
];
var NATIVE_TYPE_CHOICES = [
{ type: "text", label: "Text" },
{ type: "multitext", label: "List" },
{ type: "number", label: "Number" },
{ type: "checkbox", label: "Checkbox" },
{ type: "date", label: "Date" },
{ type: "datetime", label: "Date & time" }
];
var LOCKED_NATIVE_TYPES = /* @__PURE__ */ new Set(["tags", "aliases", "cssclasses"]);
var STANDARD_TYPE_SET = new Set(STANDARD_NATIVE_PROPERTY_TYPES);
var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
var DATETIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/;
function isNativeEditableYamlProperty(property) {
return property.type === 0 /* YAML */ && !property.path && !property.isNested && !property.isVirtual && !isYamlParentContainerValue(property.content);
}
function resolveNativeProperty(app, property) {
const manager = getMetadataTypeManager2(app);
const widgets = manager?.registeredTypeWidgets;
if (!widgets) {
return {
kind: "fallback",
reason: "Obsidian native property widgets are not available.",
type: "text"
};
}
const type = resolveNativePropertyType(manager, widgets, property.key, property.content);
const widget = widgets[type];
if (!widget || typeof widget.render !== "function") {
return {
kind: "fallback",
reason: `Obsidian's native ${type} property widget is not available.`,
type: "text"
};
}
return { kind: "native", type, widget };
}
function canAssignVaultPropertyType(app) {
return typeof getMetadataTypeManager2(app)?.setType === "function";
}
async function assignVaultPropertyType(app, key2, type) {
const manager = getMetadataTypeManager2(app);
if (!manager || typeof manager.setType !== "function") return false;
try {
await manager.setType(key2, type);
return true;
} catch {
return false;
}
}
function getNativeWidgetForType(app, type) {
const widget = getMetadataTypeManager2(app)?.registeredTypeWidgets?.[type];
return widget && typeof widget.render === "function" ? widget : null;
}
function normalizeWidgetValue(type, value, valueSource) {
if (valueSource === "fallback") {
return { ok: true, value: value === null || value === void 0 ? "" : String(value) };
}
switch (type) {
case "text":
if (typeof value === "string" || value === null) return { ok: true, value };
return invalidType(type, "a string or null");
case "multitext":
case "tags":
case "aliases":
case "cssclasses":
if (typeof value === "string") return { ok: true, value };
if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
return { ok: true, value };
}
return invalidType(type, "a string or string array");
case "number":
if (value === null) return { ok: true, value };
if (typeof value === "number" && Number.isFinite(value)) return { ok: true, value };
return invalidType(type, "a finite number or null");
case "checkbox":
if (typeof value === "boolean") return { ok: true, value };
return invalidType(type, "a boolean");
case "date":
if (value === null || value === "") return { ok: true, value };
if (typeof value === "string" && DATE_RE.test(value)) return { ok: true, value };
return invalidType(type, "an ISO date string, empty string, or null");
case "datetime":
if (value === null || value === "") return { ok: true, value };
if (typeof value === "string" && DATETIME_RE.test(value)) return { ok: true, value };
return invalidType(type, "an ISO datetime string, empty string, or null");
}
}
function resolveCreationType(app, key2) {
const manager = getMetadataTypeManager2(app);
const widgets = manager?.registeredTypeWidgets;
if (!manager || !widgets) return "text";
const normalizedKey = key2.toLowerCase();
if (isTagsKey(normalizedKey)) return "tags";
if (normalizedKey === "aliases") return "aliases";
if (normalizedKey === "cssclasses" && widgets.cssclasses) return "cssclasses";
const assigned = toStandardType(manager.getAssignedWidget?.(key2), widgets);
if (assigned) return assigned;
const propertyInfoType = toStandardType(readPropertyInfoWidget(manager, key2), widgets);
if (propertyInfoType) return propertyInfoType;
const expectedType = toStandardType(readTypeInfoExpected(manager, key2, void 0), widgets);
if (expectedType) return expectedType;
return "text";
}
function emptyValueForType(type) {
switch (type) {
case "number":
return null;
case "checkbox":
return false;
case "multitext":
case "tags":
case "aliases":
case "cssclasses":
return [];
case "text":
case "date":
case "datetime":
return "";
}
}
function inferCreationTypeFromText(rawText, currentType) {
if (currentType !== "text") return null;
const inferred = inferTypeFromText(rawText.trim());
return inferred && inferred !== currentType ? inferred : null;
}
function seedFromRawText(rawText, nextType) {
const trimmed = rawText.trim();
switch (nextType) {
case "text":
return rawText;
case "multitext":
case "tags":
case "aliases":
case "cssclasses":
return trimmed === "" ? [] : [trimmed];
case "number":
return isFiniteNumericString(trimmed) ? Number(trimmed) : null;
case "checkbox":
return trimmed === "true" ? true : false;
case "date":
return isValidIsoDate(trimmed) ? trimmed : "";
case "datetime":
return isValidIsoDatetime(trimmed) ? trimmed : "";
}
}
function frontmatterValuesEqual(left, right) {
if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();
if (left instanceof Date || right instanceof Date) return compareDateWithPrimitive(left, right);
if (Array.isArray(left) || Array.isArray(right)) return arraysEqual(left, right);
if (isPlainYamlObject(left) || isPlainYamlObject(right)) return objectsEqual(left, right);
return Object.is(left, right);
}
function resolveNativePropertyType(manager, widgets, key2, value) {
const normalizedKey = key2.toLowerCase();
if (isTagsKey(normalizedKey)) return "tags";
if (normalizedKey === "aliases") return "aliases";
if (normalizedKey === "cssclasses" && widgets.cssclasses) return "cssclasses";
const assigned = toStandardType(manager.getAssignedWidget?.(key2), widgets);
if (assigned) return assigned;
const propertyInfoWidget = readPropertyInfoWidget(manager, key2);
const propertyInfoType = toStandardType(propertyInfoWidget, widgets);
if (propertyInfoType) return propertyInfoType;
const expected = readTypeInfoExpected(manager, key2, value);
const expectedType = toStandardType(expected, widgets);
if (expectedType) return expectedType;
return inferTypeFromValue(value);
}
function readPropertyInfoWidget(manager, key2) {
try {
const all = manager.getAllProperties?.();
return all?.[key2]?.widget ?? all?.[key2.toLowerCase()]?.widget;
} catch {
return null;
}
}
function readTypeInfoExpected(manager, key2, value) {
try {
return manager.getTypeInfo?.(key2, value)?.expected?.type ?? manager.getTypeInfo?.(key2)?.expected?.type;
} catch {
return null;
}
}
function toStandardType(value, widgets) {
if (typeof value !== "string") return null;
if (!STANDARD_TYPE_SET.has(value)) return null;
if (value === "cssclasses" && !widgets.cssclasses) return null;
return value;
}
function inferTypeFromValue(value) {
if (Array.isArray(value)) return "multitext";
if (typeof value === "boolean") return "checkbox";
if (typeof value === "number" && Number.isFinite(value)) return "number";
if (value instanceof Date) return hasDateTime(value) ? "datetime" : "date";
if (typeof value === "string") {
if (DATETIME_RE.test(value)) return "datetime";
if (DATE_RE.test(value)) return "date";
}
return "text";
}
function hasDateTime(value) {
return value.getUTCHours() !== 0 || value.getUTCMinutes() !== 0 || value.getUTCSeconds() !== 0 || value.getUTCMilliseconds() !== 0;
}
var NUMERIC_RE = /^-?(?:\d+\.?\d*|\.\d+)$/;
function isFiniteNumericString(text2) {
if (!NUMERIC_RE.test(text2)) return false;
return Number.isFinite(Number(text2));
}
function isValidIsoDate(value) {
if (!DATE_RE.test(value)) return false;
const year = Number(value.slice(0, 4));
const month = Number(value.slice(5, 7));
const day = Number(value.slice(8, 10));
const date = new Date(Date.UTC(year, month - 1, day));
return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
}
function isValidIsoDatetime(value) {
if (!DATETIME_RE.test(value)) return false;
if (!isValidIsoDate(value.slice(0, 10))) return false;
const hour = Number(value.slice(11, 13));
const minute = Number(value.slice(14, 16));
const second = value.length > 16 ? Number(value.slice(17, 19)) : 0;
return hour <= 23 && minute <= 59 && second <= 59;
}
function inferTypeFromText(text2) {
if (text2 === "") return null;
if (isValidIsoDatetime(text2)) return "datetime";
if (isValidIsoDate(text2)) return "date";
if (text2 === "true" || text2 === "false") return "checkbox";
if (/^0\d/.test(text2)) return null;
if (isFiniteNumericString(text2)) return "number";
return null;
}
function invalidType(type, expected) {
return {
ok: false,
reason: `Obsidian's native ${type} editor returned an unsupported value shape; expected ${expected}.`
};
}
function arraysEqual(left, right) {
if (!Array.isArray(left) || !Array.isArray(right)) return false;
if (left.length !== right.length) return false;
return left.every((value, index2) => frontmatterValuesEqual(value, right[index2]));
}
function objectsEqual(left, right) {
if (!isPlainYamlObject(left) || !isPlainYamlObject(right)) return false;
const leftKeys = Object.keys(left);
const rightKeys = Object.keys(right);
if (leftKeys.length !== rightKeys.length) return false;
return leftKeys.every(
(key2) => Object.prototype.hasOwnProperty.call(right, key2) && frontmatterValuesEqual(left[key2], right[key2])
);
}
function compareDateWithPrimitive(left, right) {
const date = left instanceof Date ? left : right instanceof Date ? right : null;
const other = left instanceof Date ? right : left;
if (!date || typeof other !== "string") return false;
if (DATE_RE.test(other)) return date.toISOString().slice(0, 10) === other;
if (DATETIME_RE.test(other)) return date.toISOString().replace(/\.\d{3}Z$/, "").startsWith(other);
return false;
}
function getMetadataTypeManager2(app) {
return app.metadataTypeManager ?? null;
}
// src/Modals/NativeWidgetHost.ts
var import_obsidian12 = require("obsidian");
// src/Modals/NativePropertyPrompt/nativeWikilinkSuggester.ts
var import_obsidian11 = require("obsidian");
var WIKILINK_QUERY = /\[\[([^\]]*)$/;
var NativeWikilinkSuggester = class extends import_obsidian11.AbstractInputSuggest {
constructor(app, inputEl, sourcePath) {
const mirrorHost = inputEl.parentElement ?? inputEl;
const mirrorEl = mirrorHost.createEl("input", {
cls: "metaedit-native-wikilink-suggest-mirror",
type: "text"
});
super(app, mirrorEl);
this.inputEl = inputEl;
this.sourcePath = sourcePath;
this.onInput = () => this.refreshFromContent();
this.mirrorEl = mirrorEl;
this.mirrorEl.tabIndex = -1;
this.mirrorEl.setAttribute("aria-hidden", "true");
this.inputEl.addEventListener("input", this.onInput);
this.inputEl.addEventListener("keyup", this.onInput);
this.onSelect((suggestion) => this.acceptSuggestion(suggestion));
}
getSuggestions(query) {
const normalized = query.toLowerCase();
return this.readLinkSuggestions().filter((suggestion) => {
const path = suggestion.path ?? suggestion.file?.basename ?? "";
const alias = suggestion.alias ?? "";
return path.toLowerCase().includes(normalized) || alias.toLowerCase().includes(normalized);
}).slice(0, 50);
}
renderSuggestion(value, el) {
const label = value.alias ?? value.path ?? value.file?.basename ?? value.file?.path ?? "";
el.setText(label);
}
selectSuggestion(value, _evt) {
this.acceptSuggestion(value);
}
destroy() {
this.inputEl.removeEventListener("input", this.onInput);
this.inputEl.removeEventListener("keyup", this.onInput);
this.close();
this.mirrorEl.remove();
}
refreshFromContent() {
const match = this.currentQuery();
if (!match) {
this.close();
return;
}
this.mirrorEl.value = match.query;
this.mirrorEl.focus();
this.mirrorEl.trigger("input");
}
currentQuery() {
const text2 = this.inputEl.textContent ?? "";
const match = text2.match(WIKILINK_QUERY);
if (!match) return null;
return { query: match[1] ?? "" };
}
acceptSuggestion(suggestion) {
if (!suggestion.file) return;
const link2 = this.app.fileManager.generateMarkdownLink(
suggestion.file,
this.sourcePath,
"",
suggestion.alias
);
this.inputEl.textContent = link2;
this.inputEl.focus();
this.inputEl.trigger("input");
this.close();
}
readLinkSuggestions() {
const metadataCache = this.app.metadataCache;
const suggestions = metadataCache.getLinkSuggestions?.() ?? [];
return suggestions.filter((suggestion) => suggestion.file);
}
};
// src/Modals/NativeWidgetHost.ts
var BODY_PORTAL_SELECTOR = ".suggestion-container, .popover, .hover-popover";
var EDITING_KEYS = /* @__PURE__ */ new Set([
"Backspace",
"Delete",
"Enter",
"Spacebar",
" "
]);
var NativeWidgetHost = class {
constructor(options) {
this.widgetInstance = null;
this.preMountBodyChildren = /* @__PURE__ */ new Set();
this.perMountCleanup = [];
this.typeInternal = "text";
this.valueSourceInternal = "native";
this.didReceiveChangeInternal = false;
this.didEditDomInternal = false;
this.renderFailedInternal = false;
this.app = options.app;
this.hostEl = options.hostEl;
this.sourcePath = options.sourcePath;
this.key = options.key;
this.onChangeCallback = options.onChange;
}
get value() {
return this.lastValueInternal;
}
get type() {
return this.typeInternal;
}
get valueSource() {
return this.valueSourceInternal;
}
get didReceiveChange() {
return this.didReceiveChangeInternal;
}
get didEditDom() {
return this.didEditDomInternal;
}
get renderFailed() {
return this.renderFailedInternal;
}
setKey(key2) {
this.key = key2;
}
/**
* Mount `type`'s native widget seeded with `value`, tearing down any currently
* mounted widget first. Falls back to a plain text input when the native widget
* is unavailable. `lastValue` starts at the seed so an untouched widget commits
* exactly what was mounted.
*/
mountNative(type, value) {
const widget = getNativeWidgetForType(this.app, type);
if (!widget) {
this.mountFallback(`Obsidian's native ${type} property widget is not available.`, value);
this.typeInternal = type;
return;
}
this.beginMount(type, value, "native");
try {
this.widgetInstance = widget.render?.(this.hostEl, value, {
app: this.app,
key: this.key,
sourcePath: this.sourcePath,
onChange: (changed) => {
this.lastValueInternal = changed;
this.didReceiveChangeInternal = true;
this.onChangeCallback?.(changed);
},
blur: () => void 0
});
this.installAliasesWikilinkFallback(type);
} catch (error) {
this.handleRenderFailure(type, error, widget);
}
}
/** Mount a plain text input (native widgets unavailable, or a render failure fallback). */
mountFallback(reason, value) {
this.beginMount("text", value, "fallback");
this.hostEl.createDiv({
cls: "metaedit-native-property-fallback-note",
text: reason
});
const inputEl = this.hostEl.createEl("input", {
cls: "metadata-input metadata-input-text metaedit-native-property-fallback-input",
type: "text"
});
inputEl.value = value === null || value === void 0 ? "" : String(value);
const onInput = () => {
this.lastValueInternal = inputEl.value;
this.didReceiveChangeInternal = true;
this.onChangeCallback?.(inputEl.value);
};
inputEl.addEventListener("input", onInput);
this.perMountCleanup.push(() => inputEl.removeEventListener("input", onInput));
}
focus() {
const focusable = this.hostEl.querySelector(
"input, textarea, [contenteditable='true'], select, button"
);
if (!focusable) return;
focusable.focus();
if (focusable instanceof HTMLInputElement && focusable.type === "text") focusable.select();
}
/** Blur the focused editor if it lives in this host, so a pending edit flushes to onChange before submit. */
flushFocus() {
const active = activeDocument.activeElement;
if (active instanceof HTMLElement && this.hostEl.contains(active)) {
active.blur();
}
}
/**
* Whether the mounted editor is a genuinely single-line control (a real
* `<input>`/`<select>`, e.g. number/date/datetime) rather than a multi-line
* contenteditable (the text longtext editor) or a chip editor. Used to decide
* whether plain Enter should commit: in a single-line control it can, matching
* Obsidian; in a contenteditable/chip editor Enter belongs to the widget.
*/
isSingleLineEditor() {
if (this.hostEl.querySelector(".multi-select-container")) return false;
if (this.hostEl.querySelector("[contenteditable='true']")) return false;
const focusable = this.hostEl.querySelector("input, select, textarea");
if (focusable instanceof HTMLTextAreaElement) return false;
if (focusable instanceof HTMLInputElement) return focusable.type !== "checkbox";
return focusable instanceof HTMLSelectElement;
}
/**
* The current value as raw text, for carrying across a type switch. Prefers a
* live editor's in-progress text; otherwise falls back to the last reported
* value stringified, so switching away from a checkbox/number/list still
* carries its state (a checkbox -> "true"/"false", a list -> its comma-joined
* items) rather than dropping to empty.
*/
readRawText() {
return carryTextFromEditor(this.readEditorText(), this.lastValueInternal);
}
/**
* The live text of the mounted editor, or null when there is no text editor at
* all (e.g. a checkbox). An EXISTING but empty editor returns "" (not null), so a
* cleared value is carried as empty rather than resurrecting the stale lastValue.
*/
readEditorText() {
if (this.hostEl.querySelector(".multi-select-container")) return null;
const input = this.hostEl.querySelector("input:not([type='checkbox']), textarea");
if (input) return input.value ?? "";
const editable = this.hostEl.querySelector("[contenteditable='true']");
if (editable) return editable.textContent ?? "";
return null;
}
destroy() {
this.teardownCurrent();
}
beginMount(type, value, valueSource) {
this.teardownCurrent();
this.preMountBodyChildren = new Set(Array.from(activeDocument.body.children));
this.typeInternal = type;
this.valueSourceInternal = valueSource;
this.lastValueInternal = value;
this.didReceiveChangeInternal = false;
this.didEditDomInternal = false;
this.renderFailedInternal = false;
this.trackDomActivity();
}
handleRenderFailure(type, error, widget) {
const reason = error instanceof Error ? error.message : String(error);
this.renderFailedInternal = true;
this.hostEl.empty();
this.hostEl.createDiv({
cls: "metaedit-native-property-error",
text: `MetaEdit could not render Obsidian's native editor for '${this.key}'.`
});
new import_obsidian12.Notice(`MetaEdit could not render Obsidian's native editor for '${this.key}': ${reason}`);
void widget;
}
installAliasesWikilinkFallback(type) {
if (type !== "aliases") return;
const inputEl = this.hostEl.querySelector(".multi-select-input[contenteditable='true']");
if (!inputEl) return;
const suggester = new NativeWikilinkSuggester(this.app, inputEl, this.sourcePath);
this.perMountCleanup.push(() => suggester.destroy());
}
trackDomActivity() {
const markEdited = (evt) => {
if (evt instanceof KeyboardEvent && !isEditingKey(evt)) return;
this.didEditDomInternal = true;
};
const events = ["input", "change", "paste", "compositionend", "keydown"];
for (const eventName of events) {
this.hostEl.addEventListener(eventName, markEdited, true);
this.perMountCleanup.push(() => this.hostEl.removeEventListener(eventName, markEdited, true));
}
}
teardownCurrent() {
for (const callback of this.perMountCleanup.splice(0)) {
try {
callback();
} catch {
}
}
this.closeWidgetLifecycle(this.widgetInstance);
this.widgetInstance = null;
this.removeBodyPortalsCreatedByWidget();
this.hostEl.empty();
}
closeWidgetLifecycle(value) {
const seen = /* @__PURE__ */ new Set();
const visit = (candidate) => {
if (!candidate || seen.has(candidate)) return;
seen.add(candidate);
const owner = candidate;
for (const method of ["close", "destroy", "unload"]) {
const fn = owner[method];
if (typeof fn !== "function") continue;
try {
fn.call(candidate);
} catch {
}
}
for (const key2 of ["multiselect", "suggest", "suggester", "suggestEl", "hoverPopover", "popover"]) {
visit(owner[key2]);
}
};
visit(value);
}
removeBodyPortalsCreatedByWidget() {
for (const el of Array.from(activeDocument.querySelectorAll(BODY_PORTAL_SELECTOR))) {
if (this.preMountBodyChildren.has(el)) continue;
el.remove();
}
}
};
function carryTextFromEditor(editorText, lastValue) {
return editorText === null ? stringifyForCarry(lastValue) : editorText;
}
function stringifyForCarry(value) {
if (typeof value === "string") return value;
if (Array.isArray(value)) return value.map((item) => String(item ?? "")).filter(Boolean).join(", ");
if (typeof value === "number" && Number.isFinite(value)) return String(value);
if (typeof value === "boolean") return String(value);
return "";
}
function isEditingKey(evt) {
if (evt.metaKey || evt.ctrlKey || evt.altKey) return false;
if (evt.key.length === 1) return true;
return EDITING_KEYS.has(evt.key);
}
// src/Modals/TypePill.ts
var import_obsidian13 = require("obsidian");
var FALLBACK_ICONS = {
text: "text",
multitext: "list",
number: "binary",
checkbox: "check-square",
date: "calendar",
datetime: "clock",
tags: "tags",
aliases: "text",
cssclasses: "list"
};
var TypePill = class {
constructor(options) {
this.type = "text";
this.locked = false;
this.opts = options;
this.buttonEl = options.parentEl.createEl("button", { cls: "metaedit-type-pill" });
this.buttonEl.type = "button";
this.iconEl = this.buttonEl.createSpan({ cls: "metaedit-type-pill-icon" });
this.labelEl = this.buttonEl.createSpan({ cls: "metaedit-type-pill-label" });
this.buttonEl.addEventListener("click", () => this.openMenu());
}
/** Reflect the mounted widget's type on the pill; `locked` disables the menu. */
setState(type, locked) {
this.type = type;
this.locked = locked;
const label = this.labelFor(type);
(0, import_obsidian13.setIcon)(this.iconEl, this.iconIdFor(type));
this.labelEl.setText(label);
this.buttonEl.toggleClass("is-locked", locked);
this.buttonEl.disabled = locked;
(0, import_obsidian13.setTooltip)(this.buttonEl, locked ? `${label} (fixed for this property)` : this.opts.tooltip);
}
openMenu() {
if (this.opts.beforeOpen && !this.opts.beforeOpen()) return;
if (this.locked) return;
const menu = new import_obsidian13.Menu();
for (const choice of NATIVE_TYPE_CHOICES) {
menu.addItem((item) => {
item.setTitle(choice.label);
item.setIcon(this.iconIdFor(choice.type));
item.setChecked(choice.type === this.type);
item.onClick(() => this.opts.onPick(choice.type));
});
}
const rect = this.buttonEl.getBoundingClientRect();
menu.showAtPosition({ x: rect.left, y: rect.bottom + 4 });
}
hide() {
this.buttonEl.hide();
}
show() {
this.buttonEl.show();
}
labelFor(type) {
const label = NATIVE_TYPE_CHOICES.find((choice) => choice.type === type)?.label;
if (label) return label;
return type.length === 0 ? type : type[0].toUpperCase() + type.slice(1);
}
iconIdFor(type) {
const raw = getNativeWidgetForType(this.opts.app, type)?.icon;
const id = typeof raw === "string" ? raw.replace(/^lucide-/, "") : "";
return id || FALLBACK_ICONS[type];
}
};
// src/Modals/NativePropertyPrompt/NativePropertyPrompt.ts
var RESERVED_TYPE_KEYS = /* @__PURE__ */ new Set(["aliases", "cssclasses"]);
function isReservedTypeKey(key2) {
return isTagsKey(key2) || RESERVED_TYPE_KEYS.has(key2.toLowerCase());
}
var NativePropertyPrompt = class _NativePropertyPrompt extends import_obsidian14.Modal {
constructor(app, file, property) {
super(app);
this.typePill = null;
// The type the property resolved to when the prompt opened; null when the
// native widgets are unavailable (fallback editor), which also disables the
// pill and therefore type switching.
this.originalType = null;
// True once the user switched the widget's type at least once, even back to
// the original. Every re-mount resets the host's didReceiveChange flag, so
// after any switch the untouched fast path is no longer trustworthy and the
// submit decision falls through to a value comparison instead.
this.didSwitchType = false;
this.result = { kind: "cancel" };
this.didFinish = false;
this.didResolve = false;
this.saveButton = null;
this.file = file;
this.property = property;
this.waitForClose = new Promise((resolve) => {
this.resolvePromise = resolve;
});
this.contentEl.addClass("metaedit-native-property-prompt");
new import_obsidian14.Setting(this.contentEl).setHeading().setName(`Edit ${property.key}`);
const rowEl = this.contentEl.createDiv({ cls: "metadata-property metaedit-native-property-row" });
const resolution = resolveNativeProperty(app, property);
const canSwitchType = resolution.kind === "native" && canAssignVaultPropertyType(app);
if (canSwitchType) {
this.typePill = new TypePill({
app,
parentEl: rowEl,
tooltip: "Change property type - applies vault-wide (\u2318/Ctrl+Y)",
onPick: (type) => this.pickType(type)
});
}
this.hostEl = rowEl.createDiv({ cls: "metadata-property-value metaedit-native-property-host" });
this.host = new NativeWidgetHost({
app,
hostEl: this.hostEl,
sourcePath: file.path,
key: property.key
});
if (resolution.kind === "native") {
this.originalType = resolution.type;
this.host.mountNative(resolution.type, property.content);
if (canSwitchType) {
this.updateTypePill();
this.registerTypeSwitchAccelerator();
}
} else {
this.host.mountFallback(resolution.reason, property.content);
}
new import_obsidian14.Setting(this.contentEl).addButton((button) => {
this.saveButton = button;
button.setButtonText("Save").setCta().setDisabled(this.host.renderFailed).onClick(() => this.submit());
}).addButton((button) => {
button.setButtonText("Cancel").onClick(() => this.cancel());
});
this.open();
}
static Prompt(app, file, property) {
const modal = new _NativePropertyPrompt(app, file, property);
return modal.waitForClose;
}
onOpen() {
super.onOpen();
this.host.focus();
}
onClose() {
super.onClose();
this.host.destroy();
this.hostEl.remove();
if (!this.didFinish) this.result = { kind: "cancel" };
this.resolveOnce();
}
registerTypeSwitchAccelerator() {
this.contentEl.addEventListener("keydown", (evt) => {
if (evt.isComposing) return;
if ((evt.metaKey || evt.ctrlKey) && (evt.key === "y" || evt.key === "Y")) {
evt.preventDefault();
this.typePill?.openMenu();
}
}, true);
}
pickType(type) {
if (type === this.host.type) return;
this.didSwitchType = true;
this.host.mountNative(type, seedFromRawText(this.host.readRawText(), type));
this.updateTypePill();
this.saveButton?.setDisabled(this.host.renderFailed);
this.host.focus();
}
updateTypePill() {
const locked = LOCKED_NATIVE_TYPES.has(this.host.type) || isReservedTypeKey(this.property.key);
this.typePill?.setState(this.host.type, locked);
}
submit() {
this.host.flushFocus();
if (this.host.valueSource === "native" && this.host.didEditDom && !this.host.didReceiveChange) {
new import_obsidian14.Notice(`MetaEdit did not receive a value from Obsidian's native editor for '${this.property.key}'. Nothing was written.`);
return;
}
const typeChanged = this.originalType !== null && this.host.type !== this.originalType;
if (!this.host.didReceiveChange && !typeChanged && !this.didSwitchType) {
this.finish({
kind: "submit",
changed: false,
typeChanged: false,
type: this.host.type,
value: this.property.content,
valueSource: this.host.valueSource
});
return;
}
const normalized = normalizeWidgetValue(this.host.type, this.host.value, this.host.valueSource);
if (normalized.ok === false) {
new import_obsidian14.Notice(`MetaEdit could not update '${this.property.key}': ${normalized.reason}`);
return;
}
const changed = !frontmatterValuesEqual(normalized.value, this.property.content);
this.finish({
kind: "submit",
changed,
typeChanged,
type: this.host.type,
value: normalized.value,
valueSource: this.host.valueSource
});
}
cancel() {
this.finish({ kind: "cancel" });
}
finish(result) {
this.result = result;
this.didFinish = true;
this.close();
}
resolveOnce() {
if (this.didResolve) return;
this.didResolve = true;
this.resolvePromise(this.result);
}
};
// src/Modals/FluidPropertyCreatePrompt/FluidPropertyCreatePrompt.ts
var import_obsidian15 = require("obsidian");
var FluidPropertyCreatePrompt = class _FluidPropertyCreatePrompt extends import_obsidian15.Modal {
constructor(app, options) {
super(app);
this.addButton = null;
this.pinnedType = false;
this.autoPropertyKey = false;
this.lastSettledKey = null;
this.inferredType = null;
this.result = { kind: "cancel" };
this.didFinish = false;
this.didResolve = false;
this.opts = options;
this.waitForClose = new Promise((resolve) => {
this.resolvePromise = resolve;
});
this.modalEl.addClass("metaedit-fluid-create-modal");
this.contentEl.addClass("metaedit-fluid-create");
new import_obsidian15.Setting(this.contentEl).setHeading().setName("New property");
const rowEl = this.contentEl.createDiv({ cls: "metadata-property metaedit-fluid-create-row" });
this.typePill = new TypePill({
app,
parentEl: rowEl,
tooltip: "Change type (\u2318/Ctrl+Y)",
onPick: (type) => this.pickType(type),
// Settle first so a reserved key locks its type before the menu opens (you
// can't pick a type for tags/aliases), and so the adopted type is checked.
beforeOpen: () => {
this.settleKey();
return !this.autoPropertyKey;
}
});
this.keyInputEl = rowEl.createEl("input", {
cls: "metadata-property-key-input metaedit-fluid-create-key",
type: "text"
});
this.keyInputEl.placeholder = "Property name";
this.hostEl = rowEl.createDiv({ cls: "metadata-property-value metaedit-native-property-host metaedit-fluid-create-value" });
this.autoPropertyNoteEl = rowEl.createDiv({ cls: "metaedit-fluid-create-autoprop" });
this.autoPropertyNoteEl.hide();
this.hintEl = this.contentEl.createDiv({ cls: "metaedit-fluid-create-hint" });
this.hintEl.hide();
this.warningEl = this.contentEl.createDiv({ cls: "metaedit-fluid-create-warning" });
this.warningEl.hide();
this.host = new NativeWidgetHost({
app,
hostEl: this.hostEl,
sourcePath: options.sourcePath,
key: ""
});
this.host.mountNative("text", emptyValueForType("text"));
this.updateTypePill();
this.buildFooter();
this.registerKeyInput();
this.registerKeyboard();
this.open();
}
static Open(app, options) {
return new _FluidPropertyCreatePrompt(app, options).waitForClose;
}
onOpen() {
super.onOpen();
this.keyInputEl.focus();
this.updateValidity();
}
onClose() {
super.onClose();
this.keySuggester?.close();
this.keySuggester = void 0;
this.host.destroy();
if (!this.didFinish) this.result = { kind: "cancel" };
this.resolveOnce();
}
buildFooter() {
new import_obsidian15.Setting(this.contentEl).addExtraButton((button) => button.setIcon("info").setDisabled(true).setTooltip("\u2318/Ctrl+\u21B5 to add \xB7 \u2318/Ctrl+Y to change type")).addButton((button) => {
this.addButton = button;
button.setButtonText("Add").setCta().onClick(() => this.commit());
}).addButton((button) => button.setButtonText("Cancel").onClick(() => this.cancel()));
}
registerKeyInput() {
if (this.opts.suggestValues.length > 0) {
this.keySuggester = new FluidKeyNameSuggester(this.app, this.keyInputEl, this.opts.suggestValues);
}
this.keyInputEl.addEventListener("input", () => this.updateValidity());
this.keyInputEl.addEventListener("blur", () => this.settleKey());
this.keyInputEl.addEventListener("keydown", (evt) => {
if (evt.isComposing) return;
if ((evt.key === "Enter" || evt.key === "Tab") && !evt.shiftKey && !this.isSuggestionOpen()) {
evt.preventDefault();
this.settleAndAdvance();
}
});
}
registerKeyboard() {
this.contentEl.addEventListener("keydown", (evt) => {
if (evt.isComposing) return;
if ((evt.metaKey || evt.ctrlKey) && evt.key === "Enter") {
evt.preventDefault();
this.commit();
return;
}
if ((evt.metaKey || evt.ctrlKey) && (evt.key === "y" || evt.key === "Y")) {
evt.preventDefault();
this.typePill.openMenu();
}
}, true);
this.hostEl.addEventListener("keydown", (evt) => {
if (evt.isComposing) return;
if (evt.key !== "Enter" || evt.metaKey || evt.ctrlKey || evt.shiftKey || evt.altKey) return;
if (!this.host.isSingleLineEditor()) return;
evt.preventDefault();
this.commit();
});
this.hostEl.addEventListener("input", () => this.updateInferenceHint());
}
settleAndAdvance() {
this.settleKey();
if (this.autoPropertyKey) return;
this.host.focus();
}
settleKey() {
const key2 = this.keyInputEl.value.trim();
this.updateValidity();
if (key2 === "" || isReservedFrontmatterKey(key2) || this.opts.existingKeys.has(key2)) {
if (this.autoPropertyKey) this.exitAutoPropertyState();
this.lastSettledKey = key2;
return;
}
if (key2 === this.lastSettledKey) return;
this.lastSettledKey = key2;
this.host.setKey(key2);
if (this.opts.hasAutoProperty(key2)) {
this.enterAutoPropertyState(key2);
return;
}
if (this.autoPropertyKey) this.exitAutoPropertyState();
const type = resolveCreationType(this.app, key2);
if (LOCKED_NATIVE_TYPES.has(type)) {
this.pinnedType = false;
if (type !== this.host.type) this.remountAs(type);
return;
}
if (this.pinnedType) return;
if (type !== this.host.type) this.remountAs(type);
}
enterAutoPropertyState(key2) {
this.autoPropertyKey = true;
this.host.destroy();
this.hostEl.hide();
this.typePill.hide();
this.hideInferenceHint();
this.autoPropertyNoteEl.setText(`"${key2}" uses an Auto Property \u2013 press \u2318/Ctrl+\u21B5 to choose its value.`);
this.autoPropertyNoteEl.show();
this.updateValidity();
}
exitAutoPropertyState() {
this.autoPropertyKey = false;
this.autoPropertyNoteEl.hide();
this.hostEl.show();
this.typePill.show();
this.host.mountNative("text", emptyValueForType("text"));
this.pinnedType = false;
this.updateTypePill();
}
remountAs(type) {
this.keySuggester?.close();
const seed = seedFromRawText(this.host.readRawText(), type);
this.host.mountNative(type, seed);
this.updateTypePill();
this.updateInferenceHint();
}
pickType(type) {
this.pinnedType = true;
this.remountAs(type);
this.host.focus();
}
updateTypePill() {
this.typePill.setState(this.host.type, LOCKED_NATIVE_TYPES.has(this.host.type));
}
updateInferenceHint() {
if (this.autoPropertyKey || this.pinnedType) {
this.hideInferenceHint();
return;
}
const inferred = inferCreationTypeFromText(this.host.readRawText(), this.host.type);
if (!inferred) {
this.hideInferenceHint();
return;
}
this.inferredType = inferred;
const label = NATIVE_TYPE_CHOICES.find((choice) => choice.type === inferred)?.label ?? inferred;
this.hintEl.empty();
this.hintEl.createSpan({ text: `Looks like a ${label.toLowerCase()}. ` });
const acceptEl = this.hintEl.createEl("a", { cls: "metaedit-fluid-create-hint-accept", text: `Change to ${label}` });
acceptEl.addEventListener("click", (evt) => {
evt.preventDefault();
if (this.inferredType) this.pickType(this.inferredType);
});
this.hintEl.show();
}
hideInferenceHint() {
this.inferredType = null;
this.hintEl.hide();
this.hintEl.empty();
}
updateValidity() {
const key2 = this.keyInputEl.value.trim();
let warning = "";
if (key2 !== "" && isReservedFrontmatterKey(key2)) {
warning = `"${key2}" is a reserved property name and can't be used.`;
} else if (key2 !== "" && this.opts.existingKeys.has(key2)) {
warning = `This note already has a property named "${key2}".`;
}
this.warningEl.setText(warning);
this.warningEl.toggle(warning !== "");
this.addButton?.setDisabled(key2 === "" || warning !== "");
}
commit() {
this.settleKey();
const key2 = this.keyInputEl.value.trim();
if (key2 === "" || isReservedFrontmatterKey(key2) || this.opts.existingKeys.has(key2)) {
this.updateValidity();
this.keyInputEl.focus();
return;
}
if (this.autoPropertyKey) {
this.finish({ kind: "autoProperty", key: key2 });
return;
}
if (this.host.renderFailed) {
new import_obsidian15.Notice(`MetaEdit could not render an editor for '${key2}'. Nothing was written.`);
return;
}
this.host.flushFocus();
if (this.host.valueSource === "native" && this.host.didEditDom && !this.host.didReceiveChange) {
new import_obsidian15.Notice(`MetaEdit did not receive a value from Obsidian's native editor for '${key2}'. Nothing was written.`);
return;
}
const normalized = normalizeWidgetValue(this.host.type, this.host.value, this.host.valueSource);
if (normalized.ok === false) {
new import_obsidian15.Notice(`MetaEdit could not create '${key2}': ${normalized.reason}`);
return;
}
this.finish({
kind: "submit",
key: key2,
type: this.host.type,
value: normalized.value,
valueSource: this.host.valueSource
});
}
cancel() {
this.finish({ kind: "cancel" });
}
finish(result) {
this.result = result;
this.didFinish = true;
this.close();
}
resolveOnce() {
if (this.didResolve) return;
this.didResolve = true;
this.resolvePromise(this.result);
}
isSuggestionOpen() {
return activeDocument.querySelector(".suggestion-container") !== null;
}
};
var FluidKeyNameSuggester = class extends GenericTextSuggester {
renderSuggestion(value, el) {
super.renderSuggestion(value, el);
el.closest(".suggestion-container")?.addClass("metaedit-fluid-create-suggest");
}
};
// src/metaController.ts
var fileWriteQueues = /* @__PURE__ */ new Map();
var ADD_FIRST_SELECTION = "metaedit:multi-value:add-first";
var ADD_TO_BEGINNING_SELECTION = "metaedit:multi-value:add-beginning";
var ADD_TO_END_SELECTION = "metaedit:multi-value:add-end";
var VALUE_SELECTION_PREFIX = "metaedit:multi-value:value:";
var MetaController = class {
constructor(app, plugin) {
this.hasTrackerPlugin = false;
this.app = app;
this.parser = new MetaEditParser(app);
this.plugin = plugin;
this.hasTrackerPlugin = !!this.app.plugins.plugins["obsidian-tracker"];
}
async getPropertiesInFile(file) {
const yaml = await this.parser.parseFrontmatter(file);
const inlineFields = await this.parser.parseInlineFields(file);
const tags = await this.parser.getTagsForFile(file);
return [...tags, ...yaml, ...inlineFields];
}
async addYamlProp(propName, propValue, file) {
this.assertWritableKey(propName);
const settings = this.plugin.settings;
if (isTagsKey(propName)) {
propValue = splitFrontmatterTags(propValue);
}
const activeAutoProperty = this.getActiveAutoProperty(propName);
const autoPropertyKeepsScalar = !!activeAutoProperty && !isMultiAutoProperty(activeAutoProperty, settings.EditMode, propName);
if (!Array.isArray(propValue) && !autoPropertyKeepsScalar && (settings.EditMode.mode === "All Multi" /* AllMulti */ || settings.EditMode.mode === "Some Multi" /* SomeMulti */ && settings.EditMode.properties.contains(propName))) {
propValue = [propValue];
}
let propertyExists = false;
await this.enqueueFileWrite(file, async () => {
await this.processFrontMatter(file, (frontmatter) => {
if (Object.prototype.hasOwnProperty.call(frontmatter, propName)) {
propertyExists = true;
return;
}
frontmatter[propName] = propValue;
});
});
if (propertyExists) {
new import_obsidian16.Notice(`Frontmatter in file '${file.name}' already has property '${propName}'. Will not add.`);
}
}
/**
* Append a NEW inline `name:: value` field instance, leaving any existing
* same-named fields untouched. This is the add-an-instance counterpart to
* {@link updatePropertyInFile}, which replaces every existing instance.
*
* Placement is computed by {@link MetaEditParser.computeInlineInsertIndex} so the
* field is never inserted inside frontmatter or a fenced code block. The write goes
* through the per-file queue, so it serializes with other MetaEdit writes instead of
* racing them (the previous implementation read and wrote outside the queue, and
* silently no-opped when the chosen line index was 0).
*/
async appendDataviewField(propName, propValue, file, options = {}) {
const valueStr = Array.isArray(propValue) ? propValue.join(", ") : String(propValue);
const location = options.location ?? "afterLastMatch";
await this.enqueueFileWrite(file, async () => {
const content = await this.app.vault.read(file);
const newline = content.includes("\r\n") ? "\r\n" : "\n";
const lines = content.split(/\r?\n/);
const insertIndex = this.parser.computeInlineInsertIndex(content, propName, location);
lines.splice(insertIndex, 0, `${propName}:: ${valueStr}`);
await this.app.vault.modify(file, lines.join(newline));
});
}
async editMetaElement(property, meta, file) {
if (property.type === 2 /* Tag */) {
await this.editTag(property, file);
return;
}
if (this.isYamlParentContainer(property)) {
new import_obsidian16.Notice(`Nested YAML parent '${property.key}' cannot be edited as a text value.`);
return;
}
if (this.getActiveAutoProperty(property.key)) {
await this.editAutoProperty(property, file);
return;
}
if (await this.nativeYamlMode(property, file)) return;
if (shouldUseMultiValueEditor(property, this.plugin.settings.EditMode))
await this.multiValueMode(property, file);
else
await this.standardMode(property, file);
}
/**
* Edit a single body `#tag` occurrence.
*
* Decision D: the primary action RENAMES the whole tag (a flat tag is renamed,
* not turned into a child); "Edit last segment" is offered only for nested
* tags; Tracker's `#tag:value` data syntax is offered only when the Tracker
* plugin is present. The chosen action is derived here per edit and baked into
* the replacement token, so nothing about Tracker survives on the controller
* (BUG-1). The exact occurrence is rewritten by position (BUG-2/BUG-3).
*/
async editTag(property, file) {
const tag2 = property.key;
const nested = isNestedTag(tag2);
const RENAME = "Rename tag", LEAF = "Edit last segment", TRACKER = "Tracker value (#tag:value)";
const actions = [RENAME];
if (nested) actions.push(LEAF);
if (this.hasTrackerPlugin) actions.push(TRACKER);
let action2 = RENAME;
if (actions.length > 1) {
action2 = await GenericSuggester.Suggest(this.app, actions, actions);
if (!action2) return;
}
const mode = action2 === TRACKER ? "tracker" : action2 === LEAF ? "leaf" : "rename";
let input;
const parentPath = tagParent(tag2);
if (mode === "leaf" && this.getActiveAutoProperty(parentPath)) {
const autoProp = await this.handleAutoProperties(parentPath);
if (autoProp === null) return;
input = Array.isArray(autoProp) ? autoProp.join(", ") : autoProp;
} else if (mode === "tracker") {
setPendingValueContext(null);
input = await GenericPrompt.Prompt(this.app, `Enter a Tracker value for ${tag2}`);
} else {
setPendingValueContext({ app: this.app, key: tag2, type: 2 /* Tag */, tagMode: mode });
const header = mode === "leaf" ? `Change the last segment of ${tag2} to` : `Rename ${tag2} to`;
const seed = mode === "leaf" ? tagLeaf(tag2) : stripHash(tag2);
input = await GenericPrompt.Prompt(this.app, header, seed, seed);
}
if (input === null) return;
const newToken = computeTagRewrite(tag2, input, mode);
if (!newToken || newToken === tag2) return;
if (!isValidTagToken(normalizeTagToken(newToken))) {
new import_obsidian16.Notice(`'${input.trim()}' is not a valid tag name. Tags cannot contain spaces or commas.`);
return;
}
await this.updatePropertyFromUi(property, newToken, file);
}
async handleProgressProps(meta, file) {
try {
const { enabled, properties } = this.plugin.settings.ProgressProperties;
if (!enabled) return;
const tasks = this.app.metadataCache.getFileCache(file)?.listItems?.filter((li) => li.task);
if (!tasks) return;
let total = 0, complete = 0, incomplete = 0;
total = tasks.length;
complete = tasks.filter((i) => (i.task ?? "").toLowerCase() === "x").length;
incomplete = total - complete;
const props = await this.progressPropHelper(properties, meta, { total, complete, incomplete });
await this.updateMultipleInFile(props, file);
} catch (e) {
log.logError(e);
}
}
async createNewProperty(suggestValues) {
const propName = await GenericPrompt.Prompt(this.app, "Enter a property name", "Property", "", suggestValues);
if (!propName) return null;
let propValue;
if (this.getActiveAutoProperty(propName)) {
const autoProp = await this.handleAutoProperties(propName);
if (autoProp === null) return null;
propValue = autoProp;
} else {
const entered = await GenericPrompt.Prompt(this.app, "Enter a property value", "Value").catch(() => null);
if (entered === null) return null;
propValue = entered;
}
return { propName, propValue: typeof propValue === "string" ? propValue.trim() : propValue };
}
/**
* Create a new top-level YAML property through the fluid, type-aware native
* flow: a single keyboard-first modal that mounts Obsidian's own widget for
* the adopted/chosen type. A key with an active Auto Property hands off to the
* existing Auto Property value flow (preserving its single/multi behaviour);
* everything else writes the widget's typed value directly via
* {@link createNativeYamlProperty}. Cancels are silent.
*/
async createNewYamlPropertyFluid(file, suggestValues, existingKeys) {
const result = await FluidPropertyCreatePrompt.Open(this.app, {
sourcePath: file.path,
suggestValues,
existingKeys,
hasAutoProperty: (key2) => !!this.getActiveAutoProperty(key2)
});
if (result.kind === "cancel") return;
try {
if (result.kind === "autoProperty") {
const autoValue = await this.handleAutoProperties(result.key);
if (autoValue === null) return;
await this.addYamlProp(result.key, autoValue, file);
return;
}
await this.createNativeYamlProperty(result.key, result.value, file);
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
new import_obsidian16.Notice(`MetaEdit could not add '${result.key}': ${reason}`);
}
}
/**
* Write a NEW top-level YAML property carrying the native widget's already
* type-normalized value. The chosen native type is authoritative, so - unlike
* {@link addYamlProp} - this does NOT apply the legacy EditMode single/multi
* wrap (List is the explicit array path) and does NOT canonicalize tags (the
* tags widget already yields canonical strings, so create round-trips exactly
* like native edit does). Reuses addYamlProp's guards and serialized queue,
* with a create-guard re-read inside processFrontMatter so a key added between
* modal-open and write is never clobbered.
*/
async createNativeYamlProperty(key2, value, file) {
this.assertWritableKey(key2);
let propertyExists = false;
await this.enqueueFileWrite(file, async () => {
await this.processFrontMatter(file, (frontmatter) => {
if (Object.prototype.hasOwnProperty.call(frontmatter, key2)) {
propertyExists = true;
return;
}
frontmatter[key2] = value;
});
});
if (propertyExists) {
new import_obsidian16.Notice(`Frontmatter in file '${file.name}' already has property '${key2}'. Will not add.`);
}
}
async deleteProperty(property, file) {
if (property.type === 0 /* YAML */ && (property.isNested || property.isVirtual)) {
new import_obsidian16.Notice(`Nested YAML property '${property.key}' cannot be deleted by MetaEdit yet.`);
return;
}
await this.enqueueFileWrite(file, async () => {
if (property.type === 0 /* YAML */) {
await this.processFrontMatter(file, (frontmatter) => {
delete frontmatter[property.key];
});
return;
}
const fileContent = await this.app.vault.read(file);
const newline = fileContent.includes("\r\n") ? "\r\n" : "\n";
const splitContent = fileContent.split(/\r?\n/);
const regexp = new RegExp(`^\\s*${this.escapeSpecialCharacters(property.key)}\\s*::`);
const idx = splitContent.findIndex((s) => s.match(regexp));
if (idx === -1) return;
splitContent.splice(idx, 1);
await this.app.vault.modify(file, splitContent.join(newline));
});
}
async progressPropHelper(progressProps, meta, counts) {
return progressProps.reduce((obj, el) => {
const property = meta.find((prop2) => prop2.key === el.name);
if (property) {
switch (el.type) {
case "Completed Tasks" /* TaskComplete */:
obj.push({ ...property, content: counts.complete.toString() });
break;
case "Incomplete Tasks" /* TaskIncomplete */:
obj.push({ ...property, content: counts.incomplete.toString() });
break;
case "Total Tasks" /* TaskTotal */:
obj.push({ ...property, content: counts.total.toString() });
break;
default:
break;
}
}
return obj;
}, []);
}
async standardMode(property, file) {
const newValue = await GenericPrompt.Prompt(this.app, `Enter a new value for ${property.key}`, property.content, property.content);
if (newValue) {
await this.updatePropertyFromUi(property, newValue, file);
}
}
async nativeYamlMode(property, file) {
if (!isNativeEditableYamlProperty(property)) return false;
const result = await NativePropertyPrompt.Prompt(this.app, file, property);
if (result.kind === "cancel") return true;
if (!result.changed && !result.typeChanged) return true;
const wrote = result.changed ? await this.updateNativeYamlPropertyFromUi(property, result.value, file) : true;
if (wrote && result.typeChanged) {
await this.assignPropertyType(property.key, result.type);
}
return true;
}
/**
* Persist a property's type in Obsidian's vault-wide type memory (what the
* edit prompt's type pill changed), matching Obsidian's own "Property type"
* menu. Failure is surfaced but non-fatal: the value write has already
* happened, and Obsidian will still infer a widget from the value's shape.
*/
async assignPropertyType(key2, type) {
const assigned = await assignVaultPropertyType(this.app, key2, type);
if (!assigned) {
new import_obsidian16.Notice(`MetaEdit updated '${key2}', but could not change its property type in this Obsidian version.`);
log.logMessage(`metadataTypeManager.setType unavailable or failed while setting '${key2}' to '${type}'.`);
}
}
async multiValueMode(property, file) {
const tagsKey = property.type === 0 /* YAML */ && isTagsKey(property.key);
const editsArray = tagsKey || isMultiValueYamlProperty(property);
const writeBase = tagsKey ? splitFrontmatterTags(property.content) : editsArray ? property.content : this.splitMultiValue(property);
const displayValues = editsArray ? writeBase.map((value) => (value ?? "").toString()) : writeBase;
let selectedOption;
const valueSelection = (index2) => `${VALUE_SELECTION_PREFIX}${index2}`;
if (displayValues.length == 0 || displayValues.length == 1 && displayValues[0] == "") {
const options = ["Add new value"];
selectedOption = await GenericSuggester.Suggest(this.app, options, [ADD_FIRST_SELECTION]);
} else if (displayValues.length == 1) {
const options = [displayValues[0], "Add to end", "Add to beginning"];
selectedOption = await GenericSuggester.Suggest(this.app, options, [valueSelection(0), ADD_TO_END_SELECTION, ADD_TO_BEGINNING_SELECTION]);
} else {
const options = ["Add to end", ...displayValues, "Add to beginning"];
selectedOption = await GenericSuggester.Suggest(
this.app,
options,
[ADD_TO_END_SELECTION, ...displayValues.map((_, index2) => valueSelection(index2)), ADD_TO_BEGINNING_SELECTION]
);
}
if (!selectedOption) return false;
let tempValue;
const parsedSelectedIndex = selectedOption.startsWith(VALUE_SELECTION_PREFIX) ? Number(selectedOption.substring(VALUE_SELECTION_PREFIX.length)) : -1;
const selectedIndex = Number.isInteger(parsedSelectedIndex) ? parsedSelectedIndex : -1;
const isAddCommand = selectedOption === ADD_FIRST_SELECTION || selectedOption === ADD_TO_BEGINNING_SELECTION || selectedOption === ADD_TO_END_SELECTION;
if (isAddCommand) {
tempValue = await GenericPrompt.Prompt(this.app, "Enter a new value");
} else {
const selectedValue = displayValues[selectedIndex] ?? "";
tempValue = await GenericPrompt.Prompt(this.app, `Change ${selectedValue} to`, selectedValue);
}
if (!tempValue) return false;
if (tagsKey) tempValue = canonicalizeFrontmatterTag(tempValue);
if (tagsKey && tempValue === "") return false;
const edit = selectedOption === ADD_FIRST_SELECTION ? { kind: "addFirst", value: tempValue } : selectedOption === ADD_TO_BEGINNING_SELECTION ? { kind: "prepend", value: tempValue } : selectedOption === ADD_TO_END_SELECTION ? { kind: "append", value: tempValue } : { kind: "replace", index: selectedIndex, value: tempValue };
const newList = applyMultiValueEdit(writeBase, edit);
const newValue = editsArray ? newList : newList.join(", ");
return await this.updatePropertyFromUi(property, newValue, file);
}
getActiveAutoProperty(propertyName) {
if (!this.plugin.settings.AutoProperties.enabled) return void 0;
return findAutoProperty(this.plugin.settings.AutoProperties.properties, propertyName);
}
/**
* Open the Auto Property value prompt for `propertyName`, if one is defined and
* enabled. Returns a string for a Single property, a string[] for a Multi
* property, or null when there is no auto property or the user cancels.
*/
async handleAutoProperties(propertyName, currentValue) {
const autoProp = this.getActiveAutoProperty(propertyName);
if (!autoProp) return null;
const isMulti = isMultiAutoProperty(autoProp, this.plugin.settings.EditMode, propertyName);
return await AutoPropertyValueModal.Show(this.app, autoProp, {
isMulti,
currentValue,
onSaveChoices: (values) => this.persistAutoPropertyChoices(autoProp, values)
});
}
async editAutoProperty(property, file) {
const result = await this.handleAutoProperties(property.key, property.content);
if (result === null || result === void 0) return;
const newValue = Array.isArray(result) && property.type !== 0 /* YAML */ ? result.join(", ") : result;
await this.updatePropertyFromUi(property, newValue, file);
}
async persistAutoPropertyChoices(autoProp, values) {
try {
await this.plugin.updateSettings(() => {
const list = this.plugin.settings.AutoProperties.properties;
const idx = list.indexOf(autoProp) !== -1 ? list.indexOf(autoProp) : list.findIndex((a) => a.name === autoProp.name);
if (idx === -1) return false;
let updated = list[idx];
for (const value of values) {
updated = withChoiceAdded(updated, value);
}
if (updated === list[idx]) return false;
const previous = list[idx];
list[idx] = updated;
return () => {
if (list[idx] === updated) list[idx] = previous;
};
});
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
new import_obsidian16.Notice(`MetaEdit could not save the Auto Property choice: ${reason}`);
log.logMessage(`MetaEdit could not save Auto Property choices for '${autoProp.name}': ${reason}`);
}
}
async updatePropertyInFile(property, newValue, file) {
if (!property.key) return;
if (property.type === 0 /* YAML */) this.assertWritableKey(property.key);
await this.enqueueFileWrite(file, async () => {
if (property.type === 0 /* YAML */) {
await this.processFrontMatter(file, (frontmatter) => {
if (property.path && property.path.length > 1) {
setYamlPath(frontmatter, property.path, newValue, {
createParents: false,
createLeaf: false,
expectedValue: property.content,
validateExpectedValue: true
});
} else if (isTagsKey(property.key)) {
const tags = splitFrontmatterTags(newValue);
if (tags.length === 0) delete frontmatter[property.key];
else frontmatter[property.key] = tags;
} else {
frontmatter[property.key] = newValue;
}
});
return;
}
if (property.type === 2 /* Tag */) {
await this.writeTagOccurrence(property, newValue, file);
return;
}
if (property.type !== 1 /* Dataview */ || !property.key) return;
const fileContent = await this.app.vault.read(file);
const newFileContent = this.parser.replaceInlineFieldValuesInContent(fileContent, [
{ key: property.key, value: String(newValue) }
]);
await this.app.vault.modify(file, newFileContent);
});
}
/**
* Rewrite one body-tag occurrence in place, by its parsed span. The span is
* re-validated against current file content first, so an edit that raced a
* change to the note refuses to write (with a Notice) rather than corrupt
* unrelated text. `newValue` is the full replacement token computed by the UI.
*/
async writeTagOccurrence(property, newValue, file) {
const newToken = normalizeTagToken(String(newValue));
if (!isValidTagToken(newToken)) {
throw new Error(`'${String(newValue)}' is not a valid tag name.`);
}
const content = await this.app.vault.read(file);
const updated = spliceTag(content, property.position, property.key ?? "", newToken);
if (updated === null) {
throw new Error(
`could not locate the tag '${property.key}' to edit - the note may have changed since it was opened. Reopen and try again.`
);
}
await this.app.vault.modify(file, updated);
}
escapeSpecialCharacters(text2) {
return text2.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}
/**
* Throw if `key` is a reserved object-machinery name that can never be written
* as a frontmatter property (see {@link isReservedFrontmatterKey}). Centralizes
* the refusal so every dynamic `frontmatter[key] = value` sink in the controller
* - `addYamlProp`, `updatePropertyInFile`, `updateMultipleInFile` - fails closed
* identically to the bulk editor's write boundary, instead of silently dropping
* the change (or polluting the prototype) while reporting success.
*/
assertWritableKey(key2) {
if (isReservedFrontmatterKey(key2)) {
throw new Error(`"${key2}" is a reserved property name and cannot be written to frontmatter.`);
}
}
async updateMultipleInFile(properties, file) {
for (const prop2 of properties) {
if (prop2.type !== 0 /* YAML */) continue;
if (prop2.path && prop2.path.length > 0) {
for (const segment of prop2.path) {
if (typeof segment === "string") this.assertWritableKey(segment);
}
} else {
this.assertWritableKey(prop2.key);
}
}
await this.enqueueFileWrite(file, async () => {
const yamlProperties = properties.filter((prop2) => prop2.type === 0 /* YAML */ && !prop2.path);
const yamlPathProperties = properties.filter((prop2) => prop2.type === 0 /* YAML */ && prop2.path);
const tagProperties = properties.filter((prop2) => prop2.type === 2 /* Tag */);
const textProperties = properties.filter((prop2) => prop2.type === 1 /* Dataview */ && prop2.key);
if (tagProperties.length > 0) {
let content = await this.app.vault.read(file);
for (const prop2 of [...tagProperties].sort((a, b) => (b.position?.start ?? 0) - (a.position?.start ?? 0))) {
const token = normalizeTagToken(String(prop2.content));
if (!isValidTagToken(token)) {
log.logMessage(`MetaEdit skipped tag '${prop2.key}': '${String(prop2.content)}' is not a valid tag.`);
continue;
}
const updated = spliceTag(content, prop2.position, prop2.key, token);
if (updated === null) {
log.logMessage(`MetaEdit skipped tag '${prop2.key}': its position no longer matches the note.`);
continue;
}
content = updated;
}
await this.app.vault.modify(file, content);
}
if (yamlProperties.length > 0 || yamlPathProperties.length > 0) {
await this.processFrontMatter(file, (frontmatter) => {
for (const prop2 of yamlProperties) {
frontmatter[prop2.key] = prop2.content;
}
for (const prop2 of yamlPathProperties) {
setYamlPath(frontmatter, prop2.path, prop2.content, { createParents: false, createLeaf: false });
}
});
}
if (textProperties.length > 0) {
const content = await this.app.vault.read(file);
const replacements = textProperties.map((prop2) => ({ key: prop2.key, value: String(prop2.content) }));
await this.app.vault.modify(file, this.parser.replaceInlineFieldValuesInContent(content, replacements));
}
});
}
splitMultiValue(property) {
return toValueArray(property.content);
}
async updatePropertyFromUi(property, newValue, file) {
try {
await this.updatePropertyInFile(property, newValue, file);
return true;
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
new import_obsidian16.Notice(`MetaEdit could not update '${property.key}': ${reason}`);
log.logMessage(`MetaEdit could not update '${property.key}': ${reason}`);
return false;
}
}
async updateNativeYamlPropertyFromUi(property, newValue, file) {
try {
if (property.type !== 0 /* YAML */ || property.path) {
throw new Error("native Properties editing only supports top-level YAML frontmatter.");
}
this.assertWritableKey(property.key);
await this.enqueueFileWrite(file, async () => {
await this.processFrontMatter(file, (frontmatter) => {
if (!Object.prototype.hasOwnProperty.call(frontmatter, property.key)) {
throw new Error("current value changed before update.");
}
if (!frontmatterValuesEqual(frontmatter[property.key], property.content)) {
throw new Error("current value changed before update.");
}
frontmatter[property.key] = newValue;
});
});
return true;
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
new import_obsidian16.Notice(`MetaEdit could not update '${property.key}': ${reason}`);
log.logMessage(`MetaEdit could not update '${property.key}': ${reason}`);
return false;
}
}
isYamlParentContainer(property) {
if (property.type !== 0 /* YAML */ || property.isVirtual) return false;
return isYamlParentContainerValue(property.content);
}
async getYamlPath(path, file) {
const resolvedPath = parseYamlPath(path);
const frontmatter = await this.parser.parseFrontmatterObject(file);
if (!frontmatter) return void 0;
try {
return getYamlPath(frontmatter, resolvedPath);
} catch (error) {
if (error instanceof YamlPathError) return void 0;
throw error;
}
}
async updateYamlPath(path, value, file) {
const resolvedPath = parseYamlPath(path);
await this.enqueueFileWrite(file, async () => {
await this.processFrontMatter(file, (frontmatter) => {
setYamlPath(frontmatter, resolvedPath, value, { createParents: false, createLeaf: false });
});
});
}
async addOrUpdateYamlPath(path, value, file, options = {}) {
const resolvedPath = parseYamlPath(path);
const createParents = options.createParents ?? true;
await this.enqueueFileWrite(file, async () => {
await this.processFrontMatter(file, (frontmatter) => {
setYamlPath(frontmatter, resolvedPath, value, { createParents });
});
});
}
/**
* Run a `processFrontMatter` mutation serialized through this file's write
* queue, so it interleaves safely with every other MetaEdit write to the same
* file (the inline/tag `vault.read`+`vault.modify` paths in particular, which
* Obsidian does NOT serialize against a bare `processFrontMatter`). This is the
* queue-aware entry point for collaborators that compute and apply a frontmatter
* change in one callback - e.g. the bulk editor - rather than reimplementing the
* queue.
*
* Internal: reachable via the public `plugin.controller` but NOT part of the
* `IMetaEditApi` contract; treat it as a controller-internal escape hatch. The
* `update` callback runs at the top of the queue and MUST NOT itself enqueue
* another write to the same file (e.g. call back into a queued controller
* method), because that inner write would chain behind this one's still-pending
* promise and deadlock.
*
* Because the callback assigns frontmatter keys directly, it does NOT pass
* through `assertWritableKey`: the caller owns key validation. The only caller,
* the bulk editor, already refuses reserved keys at its own boundaries
* (`isReservedFrontmatterKey`); any new caller must do the same.
*/
async enqueueFrontmatterWrite(file, update2) {
await this.enqueueFileWrite(file, () => this.processFrontMatter(file, update2));
}
async processFrontMatter(file, update2) {
await this.app.fileManager.processFrontMatter(file, update2);
}
async enqueueFileWrite(file, task) {
const key2 = (0, import_obsidian16.normalizePath)(file.path);
const previous = fileWriteQueues.get(key2) ?? Promise.resolve();
const queued = previous.catch(() => void 0).then(task);
fileWriteQueues.set(key2, queued);
try {
return await queued;
} finally {
if (fileWriteQueues.get(key2) === queued) {
fileWriteQueues.delete(key2);
}
}
}
};
// src/bulk/bulkMetadataEditor.ts
var import_obsidian18 = require("obsidian");
// src/bulk/BulkOptionModal.ts
var import_obsidian17 = require("obsidian");
var BulkOptionModal = class _BulkOptionModal extends import_obsidian17.Modal {
constructor(app, config) {
super(app);
this.config = config;
this.didChoose = false;
}
static Choose(app, config) {
const modal = new _BulkOptionModal(app, config);
const promise = new Promise((resolve) => {
modal.resolvePromise = resolve;
});
modal.open();
return promise;
}
onOpen() {
const { contentEl } = this;
contentEl.addClass("metaedit-bulk-modal");
contentEl.createEl("h3", { text: this.config.title });
if (this.config.description) {
contentEl.createEl("p", {
text: this.config.description,
cls: "metaedit-bulk-modal-description"
});
}
const list = contentEl.createDiv({ cls: "metaedit-bulk-options" });
for (const option of this.config.options) {
const button = list.createEl("button", { cls: "metaedit-bulk-option" });
if (this.config.danger) button.addClass("mod-warning");
button.createDiv({ cls: "metaedit-bulk-option-label", text: option.label });
if (option.description) {
button.createDiv({ cls: "metaedit-bulk-option-description", text: option.description });
}
button.addEventListener("click", () => this.choose(option.key));
}
}
choose(key2) {
this.didChoose = true;
this.resolvePromise(key2);
this.close();
}
onClose() {
this.contentEl.empty();
if (!this.didChoose) this.resolvePromise(null);
}
};
// src/bulk/bulkMetadata.ts
function decideBulkWrite(args) {
const { exists, currentValue, rawValue, policy: policy2, wrapInArray } = args;
if (!exists) {
const value = policy2 === "merge" ? [rawValue] : wrapScalar(rawValue, wrapInArray);
return { action: "write", value, outcome: "added" };
}
switch (policy2) {
case "skip":
return { action: "skip", outcome: "skipped" };
case "overwrite": {
const next2 = wrapScalar(rawValue, wrapInArray);
if (valuesEqual(currentValue, next2)) {
return { action: "skip", outcome: "unchanged" };
}
return { action: "write", value: next2, outcome: "overwritten" };
}
case "merge": {
if (isPlainObject(currentValue)) {
return { action: "skip", outcome: "skipped" };
}
const merged = uniqueConcat(toArray(currentValue), [rawValue]);
if (valuesEqual(currentValue, merged)) {
return { action: "skip", outcome: "unchanged" };
}
return { action: "write", value: merged, outcome: "merged" };
}
default:
return { action: "skip", outcome: "skipped" };
}
}
function emptySummary(total) {
return {
total,
added: 0,
merged: 0,
overwritten: 0,
skipped: 0,
unchanged: 0,
failed: 0,
failures: []
};
}
function recordOutcome(summary, outcome) {
summary[outcome] += 1;
}
function formatSummary(summary, key2) {
const parts = [];
const add = (n, label) => {
if (n > 0) parts.push(`${n} ${label}`);
};
add(summary.added, "added");
add(summary.merged, "merged");
add(summary.overwritten, "overwritten");
add(summary.skipped, "skipped");
add(summary.unchanged, "unchanged");
add(summary.failed, "failed");
const noteWord = summary.total === 1 ? "note" : "notes";
const detail = parts.length > 0 ? parts.join(", ") : "no changes";
const failureHint = summary.failed > 0 ? " (see console for failed notes)" : "";
return `MetaEdit bulk "${key2}": ${detail} across ${summary.total} ${noteWord}.${failureHint}`;
}
function wrapScalar(rawValue, wrapInArray) {
return wrapInArray ? [rawValue] : rawValue;
}
function isPlainObject(value) {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
function toArray(value) {
if (Array.isArray(value)) return value.slice();
if (value === null || value === void 0) return [];
return [value];
}
function uniqueConcat(base, additions) {
const seen = new Set(base.map(dedupeKey));
const out = base.slice();
for (const candidate of additions) {
const key2 = dedupeKey(candidate);
if (!seen.has(key2)) {
seen.add(key2);
out.push(candidate);
}
}
return out;
}
function valuesEqual(a, b) {
return stableStringify(a) === stableStringify(b);
}
function dedupeKey(value) {
if (value !== null && typeof value === "object") {
return `o:${stableStringify(value)}`;
}
return `s:${String(value)}`;
}
function stableStringify(value) {
if (value === null || typeof value !== "object") {
return JSON.stringify(value) ?? "null";
}
if (Array.isArray(value)) {
return `[${value.map(stableStringify).join(",")}]`;
}
const record = value;
const keys = Object.keys(record).sort();
const entries = keys.map((key2) => `${JSON.stringify(key2)}:${stableStringify(record[key2])}`);
return `{${entries.join(",")}}`;
}
// src/bulk/bulkMetadataEditor.ts
var BulkMetadataEditor = class {
constructor(app, plugin) {
this.app = app;
this.plugin = plugin;
}
/** Recursively collect markdown files within a folder. */
collectFromFolder(folder) {
return this.dedupeByPath(this.markdownFilesIn(folder));
}
/**
* Collect markdown files from an arbitrary selection of files and folders
* (e.g. a multi-selection in the file explorer), expanding folders and
* dropping duplicates so a file reached two ways is only edited once.
*/
collectFromSelection(files) {
const collected = [];
for (const file of files) {
if (file instanceof import_obsidian18.TFile) {
if (file.extension === "md") collected.push(file);
} else if (file instanceof import_obsidian18.TFolder) {
collected.push(...this.markdownFilesIn(file));
}
}
return this.dedupeByPath(collected);
}
/**
* Run the full interactive flow: prompt for the property name and value,
* choose a conflict policy when some notes already have the key, confirm
* destructive overwrites, apply, and report a single summary Notice.
*/
async run(files, scopeLabel) {
if (files.length === 0) {
new import_obsidian18.Notice("MetaEdit: no markdown notes to edit here.");
return;
}
const noteWord = files.length === 1 ? "note" : "notes";
const key2 = (await GenericPrompt.Prompt(
this.app,
`Property to add/update across ${files.length} ${noteWord} in ${scopeLabel}`,
"Property name"
).catch(() => null))?.trim();
if (!key2) return;
if (isReservedFrontmatterKey(key2)) {
new import_obsidian18.Notice(`MetaEdit: "${key2}" is a reserved property name and can't be used.`);
return;
}
const rawValue = await GenericPrompt.Prompt(this.app, `Value for "${key2}"`, "Value").catch(
() => null
);
if (!rawValue) return;
const conflicts = await this.countExisting(files, key2);
let policy2 = "skip";
if (conflicts > 0) {
const conflictWord = conflicts === 1 ? "note" : "notes";
const conflictVerb = conflicts === 1 ? "has" : "have";
const choice = await BulkOptionModal.Choose(this.app, {
title: `${conflicts} ${conflictWord} already ${conflictVerb} "${key2}"`,
description: "Choose how to handle notes that already define this property.",
options: [
{
key: "skip",
label: "Skip notes that already have it",
description: "Only add the property where it is missing. Nothing is overwritten."
},
{
key: "merge",
label: "Merge into a list",
description: `Add "${rawValue}" to the existing value(s) as a list, without duplicating.`
},
{
key: "overwrite",
label: "Overwrite existing values",
description: "Replace the current value. This cannot be undone."
}
]
});
if (!choice) return;
policy2 = choice;
if (policy2 === "overwrite") {
const confirm = await BulkOptionModal.Choose(this.app, {
title: `Overwrite "${key2}" across ${files.length} ${noteWord}?`,
description: "Existing values will be replaced wherever the property is present. Bulk edits cannot be undone with Ctrl+Z.",
danger: true,
options: [{ key: "yes", label: "Overwrite" }]
});
if (confirm !== "yes") return;
}
}
const summary = await this.apply(files, key2, rawValue, policy2);
new import_obsidian18.Notice(formatSummary(summary, key2), 1e4);
}
/** Apply the property to every note, isolating per-note failures. */
async apply(files, key2, rawValue, policy2) {
this.assertWritableKey(key2);
const wrapInArray = this.wrapInArrayFor(key2);
const summary = emptySummary(files.length);
for (const file of files) {
try {
const outcome = await this.applyToFile(file, key2, rawValue, policy2, wrapInArray);
recordOutcome(summary, outcome);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
summary.failed += 1;
summary.failures.push({ path: file.path, error: message });
}
}
if (summary.failures.length > 0) {
console.warn(
`MetaEdit bulk: failed to update ${summary.failures.length} note(s) for "${key2}":`,
summary.failures
);
}
return summary;
}
async applyToFile(file, key2, rawValue, policy2, wrapInArray) {
this.assertWritableKey(key2);
let outcome = "skipped";
await this.plugin.controller.enqueueFrontmatterWrite(file, (frontmatter) => {
const exists = Object.prototype.hasOwnProperty.call(frontmatter, key2);
const decision = decideBulkWrite({
exists,
currentValue: frontmatter[key2],
rawValue,
policy: policy2,
wrapInArray
});
outcome = decision.outcome;
if (decision.action === "write") {
frontmatter[key2] = decision.value;
}
});
return outcome;
}
markdownFilesIn(folder) {
const files = [];
for (const child2 of folder.children) {
if (child2 instanceof import_obsidian18.TFile) {
if (child2.extension === "md") files.push(child2);
} else if (child2 instanceof import_obsidian18.TFolder) {
files.push(...this.markdownFilesIn(child2));
}
}
return files;
}
dedupeByPath(files) {
const byPath = /* @__PURE__ */ new Map();
for (const file of files) {
if (!byPath.has(file.path)) byPath.set(file.path, file);
}
return [...byPath.values()];
}
async countExisting(files, key2) {
let count = 0;
for (const file of files) {
const frontmatter = await this.readLiveFrontmatter(file);
if (frontmatter && Object.prototype.hasOwnProperty.call(frontmatter, key2)) count += 1;
}
return count;
}
async readLiveFrontmatter(file) {
const content = await this.app.vault.cachedRead(file);
const lines = content.split(/\r?\n/);
const firstLine = (lines[0] ?? "").replace(/^\uFEFF/, "");
if (!/^---\s*$/.test(firstLine)) return null;
const end = lines.findIndex((line, index2) => index2 > 0 && /^(?:---|\.\.\.)\s*$/.test(line));
if (end === -1) return null;
let parsed;
try {
parsed = (0, import_obsidian18.parseYaml)(lines.slice(1, end).join("\n"));
} catch {
return null;
}
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
return parsed;
}
/**
* Throw if `key` is a reserved object-machinery name that cannot be written as
* a frontmatter property (see `isReservedFrontmatterKey`). Centralizes the
* refusal so the public `apply` boundary and the `applyToFile` write boundary
* reject identically.
*/
assertWritableKey(key2) {
if (isReservedFrontmatterKey(key2)) {
throw new Error(`"${key2}" is a reserved property name and cannot be written to frontmatter.`);
}
}
wrapInArrayFor(key2) {
const { mode, properties } = this.plugin.settings.EditMode;
return mode === "All Multi" /* AllMulti */ || mode === "Some Multi" /* SomeMulti */ && properties.includes(key2);
}
};
// src/Settings/defaultSettings.ts
var DEFAULT_SETTINGS = Object.freeze({
ProgressProperties: {
enabled: false,
properties: []
},
IgnoredProperties: {
enabled: false,
properties: [],
hideFileTags: false
},
AutoProperties: {
enabled: false,
properties: []
},
EditMode: {
mode: "All Single" /* AllSingle */,
properties: []
},
KanbanHelper: {
enabled: false,
boards: []
},
UIElements: {
enabled: true
}
});
// src/Settings/settingsMigration.ts
function isPlainObject2(value) {
return !!value && typeof value === "object" && !Array.isArray(value);
}
function mergeSettings(loaded) {
const defaults = structuredClone(DEFAULT_SETTINGS);
const stored = loaded ?? {};
const merged = { ...stored };
for (const key2 of Object.keys(defaults)) {
const def = defaults[key2];
const value = stored[key2];
merged[key2] = isPlainObject2(def) && isPlainObject2(value) ? { ...def, ...value } : def;
}
return merged;
}
function migrateIgnoredProperties(loaded, settings) {
const rawIgnored = loaded?.IgnoredProperties;
const isPreVersionData = isPlainObject2(rawIgnored) && rawIgnored.hideFileTags === void 0;
if (!isPreVersionData) return false;
const ignored = settings.IgnoredProperties;
if (!ignored.enabled && ignored.properties.length > 0) {
ignored.enabled = true;
}
return true;
}
// src/Modals/LinkMenu.ts
var import_obsidian19 = require("obsidian");
var LinkMenu = class {
constructor(plugin) {
this.plugin = plugin;
}
registerEvent() {
this.eventRef = this.plugin.app.workspace.on(
"file-menu",
(menu, file, source2) => this.onMenuOpenCallback(menu, file, source2)
);
this.plugin.registerEvent(this.eventRef);
this.filesEventRef = this.plugin.app.workspace.on(
"files-menu",
(menu, files, source2) => this.onFilesMenuOpenCallback(menu, files, source2)
);
this.plugin.registerEvent(this.filesEventRef);
}
unregisterEvent() {
if (this.eventRef) {
this.plugin.app.workspace.offref(this.eventRef);
}
if (this.filesEventRef) {
this.plugin.app.workspace.offref(this.filesEventRef);
}
}
onMenuOpenCallback(menu, file, source2) {
const bCorrectSource = source2 === "link-context-menu" || source2 === "calendar-context-menu" || source2 == "file-explorer-context-menu";
if (bCorrectSource) {
if (file instanceof import_obsidian19.TFile && file.extension === "md") {
this.targetFile = file;
this.addFileOptions(menu);
}
if (file instanceof import_obsidian19.TFolder && this.folderHasMarkdown(file)) {
this.targetFolder = file;
this.addFolderOptions(menu);
}
}
}
onFilesMenuOpenCallback(menu, files, source2) {
if (source2 !== "file-explorer-context-menu") return;
if (!Array.isArray(files) || files.length === 0) return;
const hasMarkdown = files.some((f) => f instanceof import_obsidian19.TFile && f.extension === "md" || f instanceof import_obsidian19.TFolder && this.folderHasMarkdown(f));
if (!hasMarkdown) return;
menu.addItem((item) => {
item.setIcon("pencil");
item.setTitle("Bulk edit metadata in selected notes");
item.onClick(async () => {
await this.plugin.runBulkEditForSelection(files);
});
});
}
// The bulk flow recurses into subfolders, so the menu must appear whenever a
// folder contains markdown at any depth - not only as a direct child.
folderHasMarkdown(folder) {
return folder.children?.some((child2) => child2 instanceof import_obsidian19.TFile && child2.extension === "md" || child2 instanceof import_obsidian19.TFolder && this.folderHasMarkdown(child2)) ?? false;
}
addFileOptions(menu) {
menu.addItem((item) => {
item.setIcon("pencil");
item.setTitle("Edit Meta");
item.onClick(async () => {
await this.plugin.runMetaEditForFile(this.targetFile);
});
});
}
addFolderOptions(menu) {
menu.addItem((item) => {
item.setIcon("pencil");
item.setTitle("Bulk edit metadata in this folder (and subfolders)");
item.onClick(async () => {
await this.plugin.runMetaEditForFolder(this.targetFolder);
});
});
}
};
// src/MetaEditApi.ts
var import_obsidian20 = require("obsidian");
var MetaEditApi = class {
constructor(plugin) {
this.plugin = plugin;
this.parser = new MetaEditParser(plugin.app);
}
make() {
return {
autoprop: this.getAutopropFunction(),
update: this.getUpdateFunction(),
getPropertyValue: this.getGetPropertyValueFunction(),
getFilesWithProperty: this.getGetFilesWithPropertyFunction(),
createYamlProperty: this.getCreateYamlPropertyFunction(),
addOrUpdateProperty: this.getAddOrUpdatePropertyFunction(),
appendDataviewField: this.getAppendDataviewFieldFunction(),
getYamlPath: this.getGetYamlPathFunction(),
updateYamlPath: this.getUpdateYamlPathFunction(),
addOrUpdateYamlPath: this.getAddOrUpdateYamlPathFunction(),
getPropertiesInFile: this.getGetPropertiesInFile(),
getAutoProperties: this.getGetAutoPropertiesFunction(),
setAutoProperties: this.getSetAutoPropertiesFunction(),
onMetadataChange: this.getOnMetadataChangeFunction()
};
}
getAutopropFunction() {
return (propertyName) => this.plugin.controller.handleAutoProperties(propertyName);
}
getUpdateFunction() {
return async (propertyName, propertyValue, file) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
const targetProperty = await this.getPropertyInFile(propertyName, targetFile);
if (!targetProperty) return;
return this.plugin.controller.updatePropertyInFile(targetProperty, propertyValue, targetFile);
};
}
getFileFromTFileOrPath(file) {
let targetFile;
if (file instanceof import_obsidian20.TFile)
targetFile = file;
if (typeof file === "string") {
const abstractFile = this.plugin.app.vault.getAbstractFileByPath(file);
if (abstractFile instanceof import_obsidian20.TFile) {
targetFile = abstractFile;
}
}
return targetFile;
}
getGetPropertyValueFunction() {
return async (propertyName, file) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
const targetProperty = await this.getPropertyInFile(propertyName, targetFile);
if (!targetProperty) return;
return targetProperty.content;
};
}
getGetFilesWithPropertyFunction() {
return (propertyName) => {
return this.plugin.getFilesWithProperty(propertyName);
};
}
getCreateYamlPropertyFunction() {
return async (propertyName, propertyValue, file) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
await this.plugin.controller.addYamlProp(propertyName, propertyValue, targetFile);
};
}
getAddOrUpdatePropertyFunction() {
return async (propertyName, propertyValue, file) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
const targetProperty = await this.getPropertyInFile(propertyName, targetFile);
if (targetProperty) {
await this.plugin.controller.updatePropertyInFile(targetProperty, propertyValue, targetFile);
return;
}
await this.plugin.controller.updatePropertyInFile({
key: propertyName,
type: 0 /* YAML */
}, propertyValue, targetFile);
};
}
getAppendDataviewFieldFunction() {
return async (propertyName, propertyValue, file, options) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
await this.plugin.controller.appendDataviewField(propertyName, propertyValue, targetFile, options);
};
}
getGetYamlPathFunction() {
return async (path, file) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
return await this.plugin.controller.getYamlPath(path, targetFile);
};
}
getUpdateYamlPathFunction() {
return async (path, propertyValue, file) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
await this.plugin.controller.updateYamlPath(path, propertyValue, targetFile);
};
}
getAddOrUpdateYamlPathFunction() {
return async (path, propertyValue, file, options) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return;
await this.plugin.controller.addOrUpdateYamlPath(path, propertyValue, targetFile, options);
};
}
getGetPropertiesInFile() {
return async (file) => {
const targetFile = this.getFileFromTFileOrPath(file);
if (!targetFile) return [];
return await this.plugin.controller.getPropertiesInFile(targetFile);
};
}
getGetAutoPropertiesFunction() {
return () => {
return this.cloneAutoProperties(this.plugin.settings.AutoProperties.properties);
};
}
getSetAutoPropertiesFunction() {
return async (autoProperties) => {
const nextAutoProperties = this.validateAutoProperties(autoProperties);
await this.plugin.updateSettings(() => {
const previousAutoProperties = this.plugin.settings.AutoProperties.properties;
this.plugin.settings.AutoProperties.properties = nextAutoProperties;
return () => {
if (this.plugin.settings.AutoProperties.properties === nextAutoProperties) {
this.plugin.settings.AutoProperties.properties = previousAutoProperties;
}
};
});
};
}
getOnMetadataChangeFunction() {
return (callback) => {
let unsubscribed = false;
const previousPropertiesByPath = /* @__PURE__ */ new Map();
const eventQueues = /* @__PURE__ */ new Map();
const handleChange = async (file, data, cache) => {
if (unsubscribed) return;
const previousProperties = previousPropertiesByPath.get(file.path) ?? null;
const properties = this.cloneProperties(this.getPropertiesFromEvent(data, cache));
if (unsubscribed) return;
if (previousProperties && this.propertiesSignature(previousProperties) === this.propertiesSignature(properties)) {
return;
}
previousPropertiesByPath.set(file.path, this.cloneProperties(properties));
try {
await callback({
file,
data,
cache,
properties: this.cloneProperties(properties),
previousProperties: previousProperties ? this.cloneProperties(previousProperties) : null
});
} catch (error) {
console.error("MetaEdit metadata change callback failed.", error);
}
};
const eventRef = this.plugin.app.metadataCache.on("changed", (file, data, cache) => {
const previousTask = eventQueues.get(file.path) ?? Promise.resolve();
const queuedTask = previousTask.catch(() => void 0).then(() => handleChange(file, data, cache));
eventQueues.set(file.path, queuedTask);
void queuedTask.finally(() => {
if (eventQueues.get(file.path) === queuedTask) {
eventQueues.delete(file.path);
}
});
});
const deletedEventRef = this.plugin.app.metadataCache.on("deleted", (file) => {
previousPropertiesByPath.delete(file.path);
eventQueues.delete(file.path);
});
const renameEventRef = this.plugin.app.vault.on("rename", (file, oldPath) => {
if (!(file instanceof import_obsidian20.TFile)) return;
const previousProperties = previousPropertiesByPath.get(oldPath);
previousPropertiesByPath.delete(oldPath);
if (previousProperties) {
previousPropertiesByPath.set(file.path, previousProperties);
}
});
const unsubscribe = () => {
if (unsubscribed) return;
unsubscribed = true;
previousPropertiesByPath.clear();
eventQueues.clear();
this.plugin.app.metadataCache.offref(eventRef);
this.plugin.app.metadataCache.offref(deletedEventRef);
this.plugin.app.vault.offref(renameEventRef);
};
this.plugin.register(unsubscribe);
return unsubscribe;
};
}
async getPropertyInFile(propertyName, file) {
const propsInFile = await this.plugin.controller.getPropertiesInFile(file);
return propsInFile.find((prop2) => prop2.key === propertyName && !prop2.isVirtual) ?? propsInFile.find((prop2) => prop2.key === propertyName && prop2.isVirtual && prop2.type === 0 /* YAML */);
}
cloneAutoProperties(autoProperties) {
return autoProperties.map((autoProperty) => {
const clone2 = {
name: autoProperty.name,
choices: [...autoProperty.choices]
};
if (autoProperty.description !== void 0) clone2.description = autoProperty.description;
if (autoProperty.type !== void 0) clone2.type = autoProperty.type;
return clone2;
});
}
validateAutoProperties(autoProperties) {
if (!Array.isArray(autoProperties)) {
throw new TypeError("Auto Properties must be an array.");
}
return autoProperties.map((autoProperty, index2) => {
if (!autoProperty || typeof autoProperty !== "object") {
throw new TypeError(`Auto Property at index ${index2} must be an object.`);
}
if (!Array.isArray(autoProperty.choices) || !autoProperty.choices.every((choice) => typeof choice === "string")) {
throw new TypeError(`Auto Property at index ${index2} choices must be an array of strings.`);
}
if (typeof autoProperty.name !== "string") {
throw new TypeError(`Auto Property at index ${index2} must have a string name.`);
}
if (autoProperty.description !== void 0 && typeof autoProperty.description !== "string") {
throw new TypeError(`Auto Property at index ${index2} description must be a string.`);
}
if (autoProperty.type !== void 0 && autoProperty.type !== "Single" && autoProperty.type !== "Multi") {
throw new TypeError(`Auto Property at index ${index2} type must be "Single" or "Multi".`);
}
const validated = {
name: autoProperty.name,
choices: [...autoProperty.choices]
};
if (autoProperty.description !== void 0) validated.description = autoProperty.description;
if (autoProperty.type !== void 0) validated.type = autoProperty.type;
return validated;
});
}
cloneProperties(properties) {
return properties.map((property) => {
const clone2 = {
key: property.key,
type: property.type,
content: this.cloneValue(property.content)
};
if (property.path) clone2.path = [...property.path];
if (property.rootKey !== void 0) clone2.rootKey = property.rootKey;
if (property.isNested !== void 0) clone2.isNested = property.isNested;
if (property.isVirtual !== void 0) clone2.isVirtual = property.isVirtual;
return clone2;
});
}
getPropertiesFromEvent(data, cache) {
return [
...this.getTagsFromCache(cache),
...this.parser.parseFrontmatterCache(cache),
...this.parser.parseInlineContent(data)
];
}
getTagsFromCache(cache) {
return (cache.tags ?? []).map((tag2) => ({
key: tag2.tag,
content: tag2.tag,
type: 2 /* Tag */
}));
}
cloneValue(value) {
if (value instanceof Date) {
return new Date(value.getTime());
}
if (Array.isArray(value)) {
return value.map((item) => this.cloneValue(item));
}
if (value && typeof value === "object") {
const clone2 = {};
for (const [key2, item] of Object.entries(value)) {
Object.defineProperty(clone2, key2, {
value: this.cloneValue(item),
enumerable: true,
configurable: true,
writable: true
});
}
return clone2;
}
return value;
}
propertiesSignature(properties) {
return JSON.stringify(properties.map((property) => ({
key: property.key,
type: property.type,
content: property.content,
path: property.path,
rootKey: property.rootKey,
isNested: property.isNested,
isVirtual: property.isVirtual
})));
}
};
// src/utility.ts
var import_obsidian21 = require("obsidian");
function getActiveMarkdownFile(app) {
const activeFile = app.workspace.getActiveFile();
const activeMarkdownFile = abstractFileToMarkdownTFile(activeFile);
if (!activeMarkdownFile) {
log.logMessage("MetaEdit: no active markdown file.");
return null;
}
return activeMarkdownFile;
}
function abstractFileToMarkdownTFile(file) {
if (file instanceof import_obsidian21.TFile && file.extension === "md")
return file;
return null;
}
// src/logger/logger.ts
var MetaEditLogger = class {
formatOutputString(error) {
return `MetaEdit: (${error.level}) ${error.message}`;
}
getMetaEditError(message, level) {
return { message, level, time: Date.now() };
}
};
// src/logger/consoleErrorLogger.ts
var ConsoleErrorLogger = class extends MetaEditLogger {
constructor() {
super(...arguments);
this.ErrorLog = [];
}
logError(errorMsg) {
const error = this.getMetaEditError(errorMsg, "ERROR" /* Error */);
this.addMessageToErrorLog(error);
console.error(this.formatOutputString(error));
}
logWarning(warningMsg) {
const warning = this.getMetaEditError(warningMsg, "WARNING" /* Warning */);
this.addMessageToErrorLog(warning);
console.warn(this.formatOutputString(warning));
}
logMessage(logMsg) {
const log2 = this.getMetaEditError(logMsg, "LOG" /* Log */);
this.addMessageToErrorLog(log2);
console.log(this.formatOutputString(log2));
}
addMessageToErrorLog(error) {
this.ErrorLog.push(error);
}
};
// src/logger/guiLogger.ts
var import_obsidian22 = require("obsidian");
var GuiLogger = class extends MetaEditLogger {
constructor(plugin) {
super();
this.plugin = plugin;
}
logError(msg) {
const error = this.getMetaEditError(msg, "ERROR" /* Error */);
new import_obsidian22.Notice(this.formatOutputString(error));
}
logWarning(msg) {
const warning = this.getMetaEditError(msg, "WARNING" /* Warning */);
new import_obsidian22.Notice(this.formatOutputString(warning));
}
logMessage(_msg) {
}
};
// src/uniqueQueue.ts
var UniqueQueue = class {
constructor() {
this.elements = [];
}
enqueue(item) {
if (this.elements.find((i) => i === item)) {
return false;
}
this.elements.push(item);
return true;
}
dequeue() {
return this.elements.shift();
}
peek() {
return this.elements[0];
}
isEmpty() {
return this.elements.length === 0;
}
length() {
return this.elements.length;
}
};
// src/automators/onFileModifyAutomatorManager.ts
var import_obsidian23 = require("obsidian");
// src/updatedFileCache.ts
var UpdatedFileCache = class {
constructor() {
this.map = /* @__PURE__ */ new Map();
}
get(key2) {
return this.map.get(key2);
}
set(key2, content) {
if (this.map.has(key2) && this.map.get(key2).content === content)
return false;
this.map.set(key2, { content, updateTime: Date.now() });
this.clean();
return true;
}
delete(key2) {
this.map.delete(key2);
}
clean() {
const five_minutes = 3e5;
this.map.forEach((item, key2) => {
if (item.updateTime < Date.now() - five_minutes) {
this.delete(key2);
}
});
}
};
// src/automators/onFileModifyAutomatorManager.ts
var OnFileModifyAutomatorManager = class {
constructor(plugin) {
this.updateFileQueue = new UniqueQueue();
this.updatedFileCache = new UpdatedFileCache();
this.automators = [];
this.notifyDelay = 5e3;
this.notifyAutomators = (0, import_obsidian23.debounce)(async () => {
while (!this.updateFileQueue.isEmpty()) {
const file = this.updateFileQueue.dequeue();
for (const automator of this.automators) {
await automator.onFileModify(file);
}
}
}, this.notifyDelay, true);
this.plugin = plugin;
this.app = plugin.app;
}
startAutomators() {
this.plugin.registerEvent(
this.plugin.app.vault.on("modify", (file) => this.onFileModify(file))
);
return this;
}
attach(automator) {
const isExist = this.automators.some((tAuto) => tAuto.type === automator.type);
if (isExist) {
log.logWarning(`a ${automator.type} automator is already attached.`);
return this;
}
this.automators.push(automator);
return this;
}
detach(automatorType) {
const automatorIndex = this.automators.findIndex((automator) => automator.type === automatorType);
if (automatorIndex === -1) {
log.logMessage(`automator of type '${automatorType}' does not exist.`);
return this;
}
this.automators.splice(automatorIndex, 1);
return this;
}
async onFileModify(file) {
const outfile = abstractFileToMarkdownTFile(file);
if (!outfile) return;
const metadata = await this.app.metadataCache.getFileCache(outfile);
if (metadata?.frontmatter != null) {
const keys = Object.keys(metadata.frontmatter);
if (keys && keys.some((key2) => key2.toLowerCase().contains("excalidraw"))) {
return;
}
const fileContent = await this.app.vault.cachedRead(outfile);
if (!this.updatedFileCache.set(outfile.path, fileContent)) return;
if (this.updateFileQueue.enqueue(outfile)) {
this.notifyAutomators();
}
}
}
};
// src/settingsWrites.ts
var SettingsWriter = class {
/**
* @param flush Persist the current in-memory settings to disk. Invoked only at the
* head of the queue, so it never overlaps another flush.
*/
constructor(flush) {
this.flush = flush;
this.tail = Promise.resolve();
}
/** Flush the current settings, serialized with every other settings write. */
save() {
return this.enqueue(() => this.flush());
}
/**
* Atomically read-modify-write the settings. `mutate` runs at the head of the
* queue - so it observes the freshest settings and no other writer can interleave
* between its read and the flush - then the change is persisted.
*
* `mutate` is intentionally SYNCHRONOUS: it applies its change in place and returns
* a {@link SettingsMutationResult}. Keeping it synchronous is what makes this queue
* deadlock-free - a mutation can never await a nested settings write while already
* holding the queue.
*/
update(mutate2) {
return this.enqueue(async () => {
const rollback = mutate2();
if (rollback === false) return;
try {
await this.flush();
} catch (error) {
if (typeof rollback === "function") rollback();
throw error;
}
});
}
enqueue(task) {
const queued = this.tail.catch(() => void 0).then(task);
this.tail = queued.catch(() => void 0);
return queued;
}
};
// src/automators/onFileModifyAutomators/kanbanHelper.ts
var import_obsidian24 = require("obsidian");
// src/automators/onFileModifyAutomators/onFileModifyAutomator.ts
var OnFileModifyAutomator = class {
constructor(plugin, type) {
this.plugin = plugin;
this.app = plugin.app;
this.type = type;
}
};
// src/automators/onFileModifyAutomators/kanbanHelper.ts
var CARD_LINK_PREFIX = /^-\s+\[[^\]]?\]\s+$/;
var KanbanHelper = class extends OnFileModifyAutomator {
get boards() {
return this.plugin.settings.KanbanHelper.boards;
}
constructor(plugin) {
super(plugin, "KanbanHelper" /* KanbanHelper */);
}
async onFileModify(file) {
const targetBoard = this.findBoardByName(file.basename);
if (!targetBoard) return;
const kanbanBoardFileCache = this.app.metadataCache.getFileCache(file);
if (!kanbanBoardFileCache?.links) return;
const kanbanBoardFileContent = await this.app.vault.cachedRead(file);
const boardLines = kanbanBoardFileContent.split("\n");
const laneForLine = this.buildLaneResolver(kanbanBoardFileCache.headings);
await this.updateFilesInBoard(kanbanBoardFileCache.links, targetBoard, file.path, boardLines, laneForLine);
}
findBoardByName(boardName) {
return this.boards.find((board) => board.boardName === boardName);
}
async updateFilesInBoard(links, board, sourcePath, boardLines, laneForLine) {
for (const link2 of links) {
try {
if (!this.isCardLink(link2, boardLines)) continue;
const lane = laneForLine(link2.position.start.line);
if (!lane) continue;
const linkFile = this.resolveLinkFile(link2, sourcePath);
if (!this.isMarkdownFile(linkFile)) {
log.logMessage(`${link2.link} is not updatable for the KanbanHelper.`);
continue;
}
await this.updateFileInBoard(linkFile, board, lane);
} catch (error) {
const reason = error instanceof Error ? error.message : String(error);
log.logMessage(`KanbanHelper could not update '${link2.link}': ${reason}`);
}
}
}
// A card link is the leading link of a top-level task line. We verify against the
// freshly-read board content that the cached link still sits at its recorded
// position with its recorded text; on a mismatch (the card moved or changed since
// the cache was built) the link is skipped rather than acted on with stale data.
// This validates the link's own identity only; it does not reconcile a lane
// heading that was renamed in place while the cache lagged (a transient state the
// 5s modify debounce makes negligible and that self-corrects on the next edit).
isCardLink(link2, boardLines) {
const start = link2.position?.start;
if (!start) return false;
const line = boardLines[start.line];
if (line === void 0) return false;
if (!line.slice(start.col).startsWith(link2.original)) return false;
return CARD_LINK_PREFIX.test(line.slice(0, start.col));
}
// Map any line to its lane: the text of the nearest heading at or above it.
// Headings come from the metadata cache so ATX-closed ("## Done ##") and
// setext headings resolve to their clean lane name, matching Obsidian.
buildLaneResolver(headings) {
const orderedHeadings = (headings ?? []).slice().sort((a, b) => a.position.start.line - b.position.start.line);
return (line) => {
let lane = null;
for (const heading of orderedHeadings) {
if (heading.position.start.line > line) break;
lane = heading.heading;
}
return lane;
};
}
async updateFileInBoard(linkFile, board, lane) {
const fileProperties = await this.plugin.controller.getPropertiesInFile(linkFile);
const targetProperty = fileProperties.find((prop2) => prop2.key === board.property && !prop2.isVirtual);
if (!targetProperty) {
const message = `'${board.property}' not found in "${linkFile.basename}" (Kanban board '${board.boardName}').`;
log.logWarning(message);
return;
}
const propertyHasChanged = targetProperty.content !== lane;
if (propertyHasChanged) {
console.debug(`Updating ${targetProperty.key} of file ${linkFile.name} to ${lane}`);
await this.plugin.controller.updatePropertyInFile(targetProperty, lane, linkFile);
}
}
resolveLinkFile(link2, sourcePath) {
const linkpath = this.normalizeLinkpath(link2?.link);
if (!linkpath) return null;
const candidates = this.buildLinkpathCandidates(linkpath);
const resolvedFromCache = this.resolveByMetadataCache(candidates, sourcePath);
if (resolvedFromCache) return resolvedFromCache;
const resolvedByPath = this.resolveByPathCandidates(candidates);
if (resolvedByPath) return resolvedByPath;
return this.resolveByBasenameCandidates(candidates);
}
normalizeLinkpath(link2) {
if (!link2) return null;
let normalized = link2;
try {
normalized = decodeURIComponent(normalized);
} catch {
}
normalized = normalized.replace(/^\/+/, "");
normalized = (0, import_obsidian24.normalizePath)(normalized);
return (0, import_obsidian24.getLinkpath)(normalized);
}
buildLinkpathCandidates(linkpath) {
const withoutExtension = this.stripMarkdownExtension(linkpath);
return Array.from(/* @__PURE__ */ new Set([linkpath, withoutExtension]));
}
stripMarkdownExtension(path) {
return path.toLowerCase().endsWith(".md") ? path.slice(0, -3) : path;
}
ensureMarkdownExtension(path) {
return path.toLowerCase().endsWith(".md") ? path : `${path}.md`;
}
resolveByMetadataCache(candidates, sourcePath) {
for (const candidate of candidates) {
const resolved = this.app.metadataCache.getFirstLinkpathDest(candidate, sourcePath);
if (resolved) return resolved;
}
return null;
}
// Direct path resolution is only safe for links that already name a folder path:
// an explicit path identifies at most one file. A bare (folder-less) link must NOT
// be resolved here, because getAbstractFileByPath would guess the vault-root note of
// that name - silently picking the root note even when Obsidian would link a
// folder-local same-named note, and bypassing the strict ambiguity guard in
// resolveByBasenameCandidates. Bare links fall through to that guard instead.
resolveByPathCandidates(candidates) {
for (const candidate of candidates) {
if (!candidate.includes("/")) continue;
const file = this.app.vault.getAbstractFileByPath(this.ensureMarkdownExtension(candidate));
const markdownFile = abstractFileToMarkdownTFile(file);
if (markdownFile) return markdownFile;
}
return null;
}
// Sole resolver for bare (folder-less) links the metadata cache misses (e.g. an
// as-yet-unresolved link or a cold cache). A basename is only a safe target when
// exactly one note carries it: if several notes share it we cannot know which the
// card meant, so we bail rather than write the lane to an arbitrarily-chosen
// same-named note (silent data corruption). The caller logs the skip once. When the
// cache is warm Obsidian's own shortest-path resolution in resolveByMetadataCache
// already picked the note the board displays, so this path is reached only on a miss.
resolveByBasenameCandidates(candidates) {
const markdownFiles = this.app.vault.getMarkdownFiles();
for (const candidate of candidates) {
if (candidate.includes("/")) continue;
const basename = this.stripMarkdownExtension(candidate.split("/").pop() ?? "");
if (!basename) continue;
const matches = markdownFiles.filter((f) => f.basename === basename);
if (matches.length === 1) return matches[0];
if (matches.length > 1) return null;
}
return null;
}
isMarkdownFile(file) {
return !!file && file.extension === "md";
}
};
// src/automators/onFileModifyAutomators/progressPropertyHelper.ts
var ProgressPropertyHelper = class extends OnFileModifyAutomator {
constructor(plugin) {
super(plugin, "ProgressProperties" /* ProgressProperties */);
}
async onFileModify(file) {
const data = await this.plugin.controller.getPropertiesInFile(file);
if (!data) return;
await this.plugin.controller.handleProgressProps(data, file);
}
};
// src/main.ts
var MetaEdit = class extends import_obsidian25.Plugin {
constructor() {
super(...arguments);
// Every settings write - the settings tab, the API, and the controller's Auto
// Property choice persistence - runs through this one serialization point, so two
// concurrent writers can't lost-update a shared in-memory snapshot and two disk
// flushes can't complete out of order.
this.settingsWriter = new SettingsWriter(() => this.saveData(this.settings));
}
async onload() {
console.log("Loading MetaEdit");
this.controller = new MetaController(this.app, this);
this.bulkEditor = new BulkMetadataEditor(this.app, this);
await this.loadSettings();
this.addCommand({
id: "metaEditRun",
name: "Run",
callback: async () => {
const file = getActiveMarkdownFile(this.app);
if (!file) return;
await this.runMetaEditForFile(file);
}
});
this.addSettingTab(new MetaEditSettingsTab(this.app, this));
this.linkMenu = new LinkMenu(this);
if (this.settings.UIElements.enabled) {
this.linkMenu.registerEvent();
}
this.api = new MetaEditApi(this).make();
log.register(new ConsoleErrorLogger()).register(new GuiLogger(this));
this.automatorManager = new OnFileModifyAutomatorManager(this).startAutomators();
this.toggleAutomators();
}
toggleAutomators() {
if (this.settings.KanbanHelper.enabled)
this.automatorManager.attach(new KanbanHelper(this));
else
this.automatorManager.detach("KanbanHelper" /* KanbanHelper */);
if (this.settings.ProgressProperties.enabled)
this.automatorManager.attach(new ProgressPropertyHelper(this));
else
this.automatorManager.detach("ProgressProperties" /* ProgressProperties */);
}
async runMetaEditForFile(file) {
const data = await this.controller.getPropertiesInFile(file);
if (!data) return;
const suggester = new MetaEditSuggester(this.app, this, data, file, this.controller);
suggester.open();
}
onunload() {
console.log("Unloading MetaEdit");
this.linkMenu.unregisterEvent();
}
async loadSettings() {
const loaded = await this.loadData();
this.settings = mergeSettings(loaded);
if (migrateIgnoredProperties(loaded, this.settings)) {
await this.saveSettings();
}
}
async saveSettings() {
await this.settingsWriter.save();
}
/**
* Atomically read-modify-write the settings, serialized with every other settings
* write. `mutate` runs at the head of the write queue - so it re-reads the freshest
* `this.settings` and no other writer can interleave between its read and the save -
* and applies its change in place. It returns a rollback to undo the in-memory
* change if the disk write fails, or `false` to skip the write when nothing changed.
*
* Use this for any read-modify-write of shared settings (e.g. appending an Auto
* Property choice) instead of mutating `settings` and calling `saveSettings()`
* separately, which would race a concurrent writer.
*/
updateSettings(mutate2) {
return this.settingsWriter.update(mutate2);
}
getFilesWithProperty(property) {
const markdownFiles = this.app.vault.getMarkdownFiles();
const files = [];
markdownFiles.forEach((file) => {
const fileCache = this.app.metadataCache.getFileCache(file);
if (fileCache) {
const fileFrontmatter = fileCache.frontmatter;
if (fileFrontmatter && Object.prototype.hasOwnProperty.call(fileFrontmatter, property)) {
files.push(file);
}
}
});
return files;
}
async runMetaEditForFolder(targetFolder) {
const files = this.bulkEditor.collectFromFolder(targetFolder);
await this.bulkEditor.run(files, `${targetFolder.name} (and subfolders)`);
}
async runBulkEditForSelection(selection) {
const files = this.bulkEditor.collectFromSelection(selection);
const scope = files.length === 1 ? files[0].name : `${selection.length} selected items`;
await this.bulkEditor.run(files, scope);
}
};
//# sourceMappingURL=main.js.map
/* nosourcemap */