globalThis.process ??= {};
globalThis.process.env ??= {};
import { a as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime_-UtK6b3T.mjs";
import { t as require_react } from "./react_BkIQlPcV.mjs";
import { t as require_react_dom } from "./react-dom_DPGfls0Q.mjs";
import { S as parseHomepage, _ as isValidLogoUrl, m as SETTINGS_KEYS, x as parseHideModeToggle } from "./crypto_CY2zBtG3.mjs";
import { Q as createFieldTypeRegistry, _t as parseFieldGroupDefinition, gt as parseFieldDefinition, n as FIELD_KEY_RE, r as FIELD_TYPES } from "./dist_C9SfSFSK.mjs";
import { t as DEFAULT_PRIMARY } from "./menus_BTJDxItx.mjs";
import { c as Field, d as surface, f as cva, h as require_jsx_runtime, l as useFieldControl, o as Textarea, s as Input, u as cn } from "./registry_BFIKyeP_.mjs";
import { n as generatePrivacyPolicy } from "./privacy_BpywF6sm.mjs";
import { n as useContentEntry, r as useContentList } from "./Base_R5CwkVX6.mjs";
import { a as paletteOptions, i as THEME_REGISTRY_META, o as parseActiveSelection, t as DEFAULT_SELECTION } from "./theme_BaEzwWHZ.mjs";
import { A as dispatchDiscreteCustomEvent, C as DialogTrigger, D as Root$2, E as Branch$1, F as Button, I as useComposedRefs, M as useLayoutEffect2, N as createContextScope, O as useCallbackRef, P as composeEventHandlers, S as DialogTitle, T as Portal, _ as Badge, a as SelectValue, b as DialogContent, c as Tabs, d as TabsTrigger, f as Item$1, g as createCollection, h as useDirection, i as SelectTrigger, j as useControllableState$1, k as Primitive, l as TabsContent, m as createRovingFocusGroupScope, n as SelectContent, o as VisuallyHidden, p as Root$1, r as SelectItem, s as useSize, t as Select$1, u as TabsList, v as Dialog, w as Presence, x as DialogDescription } from "./Select_DL8noTAu.mjs";
import { t as ErrorState } from "./ErrorState_28-cWrbi.mjs";
import { n as MediaLibrary, t as createHostMediaClient } from "./media-client_SENoshOf.mjs";
//#region ../../node_modules/.pnpm/use-sync-external-store@1.6.0_react@19.2.8/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js
/**
* @license React
* use-sync-external-store-shim.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var require_use_sync_external_store_shim_production = /* @__PURE__ */ __commonJSMin(((exports) => {
	var React = require_react();
	function is(x, y) {
		return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
	}
	var objectIs = "function" === typeof Object.is ? Object.is : is;
	var useState = React.useState;
	var useEffect = React.useEffect;
	var useLayoutEffect = React.useLayoutEffect;
	var useDebugValue = React.useDebugValue;
	function useSyncExternalStore$2(subscribe, getSnapshot) {
		var value = getSnapshot(), _useState = useState({ inst: {
			value,
			getSnapshot
		} }), inst = _useState[0].inst, forceUpdate = _useState[1];
		useLayoutEffect(function() {
			inst.value = value;
			inst.getSnapshot = getSnapshot;
			checkIfSnapshotChanged(inst) && forceUpdate({ inst });
		}, [
			subscribe,
			value,
			getSnapshot
		]);
		useEffect(function() {
			checkIfSnapshotChanged(inst) && forceUpdate({ inst });
			return subscribe(function() {
				checkIfSnapshotChanged(inst) && forceUpdate({ inst });
			});
		}, [subscribe]);
		useDebugValue(value);
		return value;
	}
	function checkIfSnapshotChanged(inst) {
		var latestGetSnapshot = inst.getSnapshot;
		inst = inst.value;
		try {
			var nextValue = latestGetSnapshot();
			return !objectIs(inst, nextValue);
		} catch (error) {
			return !0;
		}
	}
	function useSyncExternalStore$1(subscribe, getSnapshot) {
		return getSnapshot();
	}
	var shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
	exports.useSyncExternalStore = void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
}));
//#endregion
//#region ../../node_modules/.pnpm/use-sync-external-store@1.6.0_react@19.2.8/node_modules/use-sync-external-store/shim/index.js
var require_shim = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = require_use_sync_external_store_shim_production();
}));
//#endregion
//#region ../../node_modules/.pnpm/orderedmap@2.1.1/node_modules/orderedmap/dist/index.js
function OrderedMap(content) {
	this.content = content;
}
OrderedMap.prototype = {
	constructor: OrderedMap,
	find: function(key) {
		for (var i = 0; i < this.content.length; i += 2) if (this.content[i] === key) return i;
		return -1;
	},
	get: function(key) {
		var found = this.find(key);
		return found == -1 ? void 0 : this.content[found + 1];
	},
	update: function(key, value, newKey) {
		var self = newKey && newKey != key ? this.remove(newKey) : this;
		var found = self.find(key), content = self.content.slice();
		if (found == -1) content.push(newKey || key, value);
		else {
			content[found + 1] = value;
			if (newKey) content[found] = newKey;
		}
		return new OrderedMap(content);
	},
	remove: function(key) {
		var found = this.find(key);
		if (found == -1) return this;
		var content = this.content.slice();
		content.splice(found, 2);
		return new OrderedMap(content);
	},
	addToStart: function(key, value) {
		return new OrderedMap([key, value].concat(this.remove(key).content));
	},
	addToEnd: function(key, value) {
		var content = this.remove(key).content.slice();
		content.push(key, value);
		return new OrderedMap(content);
	},
	addBefore: function(place, key, value) {
		var without = this.remove(key), content = without.content.slice();
		var found = without.find(place);
		content.splice(found == -1 ? content.length : found, 0, key, value);
		return new OrderedMap(content);
	},
	forEach: function(f) {
		for (var i = 0; i < this.content.length; i += 2) f(this.content[i], this.content[i + 1]);
	},
	prepend: function(map) {
		map = OrderedMap.from(map);
		if (!map.size) return this;
		return new OrderedMap(map.content.concat(this.subtract(map).content));
	},
	append: function(map) {
		map = OrderedMap.from(map);
		if (!map.size) return this;
		return new OrderedMap(this.subtract(map).content.concat(map.content));
	},
	subtract: function(map) {
		var result = this;
		map = OrderedMap.from(map);
		for (var i = 0; i < map.content.length; i += 2) result = result.remove(map.content[i]);
		return result;
	},
	toObject: function() {
		var result = {};
		this.forEach(function(key, value) {
			result[key] = value;
		});
		return result;
	},
	get size() {
		return this.content.length >> 1;
	}
};
OrderedMap.from = function(value) {
	if (value instanceof OrderedMap) return value;
	var content = [];
	if (value) for (var prop in value) content.push(prop, value[prop]);
	return new OrderedMap(content);
};
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-model@1.25.11/node_modules/prosemirror-model/dist/index.js
function findDiffStart(a, b, pos) {
	for (let i = 0;; i++) {
		if (i == a.childCount || i == b.childCount) return a.childCount == b.childCount ? null : pos;
		let childA = a.child(i), childB = b.child(i);
		if (childA == childB) {
			pos += childA.nodeSize;
			continue;
		}
		if (!childA.sameMarkup(childB)) return pos;
		if (childA.isText && childA.text != childB.text) {
			let tA = childA.text, tB = childB.text, j = 0;
			for (; tA[j] == tB[j]; j++) pos++;
			if (j && j < tA.length && j < tB.length && surrogateHigh(tA.charCodeAt(j - 1)) && surrogateLow(tA.charCodeAt(j))) pos--;
			return pos;
		}
		if (childA.content.size || childB.content.size) {
			let inner = findDiffStart(childA.content, childB.content, pos + 1);
			if (inner != null) return inner;
		}
		pos += childA.nodeSize;
	}
}
function findDiffEnd(a, b, posA, posB) {
	for (let iA = a.childCount, iB = b.childCount;;) {
		if (iA == 0 || iB == 0) return iA == iB ? null : {
			a: posA,
			b: posB
		};
		let childA = a.child(--iA), childB = b.child(--iB), size = childA.nodeSize;
		if (childA == childB) {
			posA -= size;
			posB -= size;
			continue;
		}
		if (!childA.sameMarkup(childB)) return {
			a: posA,
			b: posB
		};
		if (childA.isText && childA.text != childB.text) {
			let tA = childA.text, tB = childB.text, iA = tA.length, iB = tB.length;
			while (iA > 0 && iB > 0 && tA[iA - 1] == tB[iB - 1]) {
				iA--;
				iB--;
				posA--;
				posB--;
			}
			if (iA && iB && iA < tA.length && surrogateHigh(tA.charCodeAt(iA - 1)) && surrogateLow(tA.charCodeAt(iA))) {
				posA++;
				posB++;
			}
			return {
				a: posA,
				b: posB
			};
		}
		if (childA.content.size || childB.content.size) {
			let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1);
			if (inner) return inner;
		}
		posA -= size;
		posB -= size;
	}
}
function surrogateLow(ch) {
	return ch >= 56320 && ch < 57344;
}
function surrogateHigh(ch) {
	return ch >= 55296 && ch < 56320;
}
/**
A fragment represents a node's collection of child nodes.

Like nodes, fragments are persistent data structures, and you
should not mutate them or their content. Rather, you create new
instances whenever needed. The API tries to make this easy.
*/
var Fragment$8 = class Fragment$8 {
	/**
	@internal
	*/
	constructor(content, size) {
		this.content = content;
		this.size = size || 0;
		if (size == null) for (let i = 0; i < content.length; i++) this.size += content[i].nodeSize;
	}
	/**
	Invoke a callback for all descendant nodes between the given two
	positions (relative to start of this fragment). Doesn't descend
	into a node when the callback returns `false`.
	*/
	nodesBetween(from, to, f, nodeStart = 0, parent) {
		for (let i = 0, pos = 0; pos < to; i++) {
			let child = this.content[i], end = pos + child.nodeSize;
			if (end > from && f(child, nodeStart + pos, parent || null, i) !== false && child.content.size) {
				let start = pos + 1;
				child.nodesBetween(Math.max(0, from - start), Math.min(child.content.size, to - start), f, nodeStart + start);
			}
			pos = end;
		}
	}
	/**
	Call the given callback for every descendant node. `pos` will be
	relative to the start of the fragment. The callback may return
	`false` to prevent traversal of a given node's children.
	*/
	descendants(f) {
		this.nodesBetween(0, this.size, f);
	}
	/**
	Extract the text between `from` and `to`. See the same method on
	[`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween).
	*/
	textBetween(from, to, blockSeparator, leafText) {
		let text = "", first = true;
		this.nodesBetween(from, to, (node, pos) => {
			let nodeText = node.isText ? node.text.slice(Math.max(from, pos) - pos, to - pos) : !node.isLeaf ? "" : leafText ? typeof leafText === "function" ? leafText(node) : leafText : node.type.spec.leafText ? node.type.spec.leafText(node) : "";
			if (node.isBlock && (node.isLeaf && nodeText || node.isTextblock) && blockSeparator) {
				if (first) first = false;
				else text += blockSeparator;
			}
			text += nodeText;
		}, 0);
		return text;
	}
	/**
	Create a new fragment containing the combined content of this
	fragment and the other.
	*/
	append(other) {
		if (!other.size) return this;
		if (!this.size) return other;
		let last = this.lastChild, first = other.firstChild, content = this.content.slice(), i = 0;
		if (last.isText && last.sameMarkup(first)) {
			content[content.length - 1] = last.withText(last.text + first.text);
			i = 1;
		}
		for (; i < other.content.length; i++) content.push(other.content[i]);
		return new Fragment$8(content, this.size + other.size);
	}
	/**
	Cut out the sub-fragment between the two given positions.
	*/
	cut(from, to = this.size) {
		if (from == 0 && to == this.size) return this;
		let result = [], size = 0;
		if (to > from) for (let i = 0, pos = 0; pos < to; i++) {
			let child = this.content[i], end = pos + child.nodeSize;
			if (end > from) {
				if (pos < from || end > to) {
					if (child.isText) child = child.cut(Math.max(0, from - pos), Math.min(child.text.length, to - pos));
					else child = child.cut(Math.max(0, from - pos - 1), Math.min(child.content.size, to - pos - 1));
				}
				result.push(child);
				size += child.nodeSize;
			}
			pos = end;
		}
		return new Fragment$8(result, size);
	}
	/**
	@internal
	*/
	cutByIndex(from, to) {
		if (from == to) return Fragment$8.empty;
		if (from == 0 && to == this.content.length) return this;
		return new Fragment$8(this.content.slice(from, to));
	}
	/**
	Create a new fragment in which the node at the given index is
	replaced by the given node.
	*/
	replaceChild(index, node) {
		let current = this.content[index];
		if (current == node) return this;
		let copy = this.content.slice();
		let size = this.size + node.nodeSize - current.nodeSize;
		copy[index] = node;
		return new Fragment$8(copy, size);
	}
	/**
	Create a new fragment by prepending the given node to this
	fragment.
	*/
	addToStart(node) {
		return new Fragment$8([node].concat(this.content), this.size + node.nodeSize);
	}
	/**
	Create a new fragment by appending the given node to this
	fragment.
	*/
	addToEnd(node) {
		return new Fragment$8(this.content.concat(node), this.size + node.nodeSize);
	}
	/**
	Compare this fragment to another one.
	*/
	eq(other) {
		if (this.content.length != other.content.length) return false;
		for (let i = 0; i < this.content.length; i++) if (!this.content[i].eq(other.content[i])) return false;
		return true;
	}
	/**
	The first child of the fragment, or `null` if it is empty.
	*/
	get firstChild() {
		return this.content.length ? this.content[0] : null;
	}
	/**
	The last child of the fragment, or `null` if it is empty.
	*/
	get lastChild() {
		return this.content.length ? this.content[this.content.length - 1] : null;
	}
	/**
	The number of child nodes in this fragment.
	*/
	get childCount() {
		return this.content.length;
	}
	/**
	Get the child node at the given index. Raise an error when the
	index is out of range.
	*/
	child(index) {
		let found = this.content[index];
		if (!found) throw new RangeError("Index " + index + " out of range for " + this);
		return found;
	}
	/**
	Get the child node at the given index, if it exists.
	*/
	maybeChild(index) {
		return this.content[index] || null;
	}
	/**
	Call `f` for every child node, passing the node, its offset
	into this parent node, and its index.
	*/
	forEach(f) {
		for (let i = 0, p = 0; i < this.content.length; i++) {
			let child = this.content[i];
			f(child, p, i);
			p += child.nodeSize;
		}
	}
	/**
	Find the first position at which this fragment and another
	fragment differ, or `null` if they are the same.
	*/
	findDiffStart(other, pos = 0) {
		return findDiffStart(this, other, pos);
	}
	/**
	Find the first position, searching from the end, at which this
	fragment and the given fragment differ, or `null` if they are
	the same. Since this position will not be the same in both
	nodes, an object with two separate positions is returned.
	*/
	findDiffEnd(other, pos = this.size, otherPos = other.size) {
		return findDiffEnd(this, other, pos, otherPos);
	}
	/**
	Find the index and inner offset corresponding to a given relative
	position in this fragment. The result object will be reused
	(overwritten) the next time the function is called. @internal
	*/
	findIndex(pos) {
		if (pos == 0) return retIndex(0, pos);
		if (pos == this.size) return retIndex(this.content.length, pos);
		if (pos > this.size || pos < 0) throw new RangeError(`Position ${pos} outside of fragment (${this})`);
		for (let i = 0, curPos = 0;; i++) {
			let cur = this.child(i), end = curPos + cur.nodeSize;
			if (end >= pos) {
				if (end == pos) return retIndex(i + 1, end);
				return retIndex(i, curPos);
			}
			curPos = end;
		}
	}
	/**
	Return a debugging string that describes this fragment.
	*/
	toString() {
		return "<" + this.toStringInner() + ">";
	}
	/**
	@internal
	*/
	toStringInner() {
		return this.content.join(", ");
	}
	/**
	Create a JSON-serializeable representation of this fragment.
	*/
	toJSON() {
		return this.content.length ? this.content.map((n) => n.toJSON()) : null;
	}
	/**
	Deserialize a fragment from its JSON representation.
	*/
	static fromJSON(schema, value) {
		if (!value) return Fragment$8.empty;
		if (!Array.isArray(value)) throw new RangeError("Invalid input for Fragment.fromJSON");
		return Fragment$8.fromArray(value.map(schema.nodeFromJSON));
	}
	/**
	Build a fragment from an array of nodes. Ensures that adjacent
	text nodes with the same marks are joined together.
	*/
	static fromArray(array) {
		if (!array.length) return Fragment$8.empty;
		let joined, size = 0;
		for (let i = 0; i < array.length; i++) {
			let node = array[i];
			size += node.nodeSize;
			if (i && node.isText && array[i - 1].sameMarkup(node)) {
				if (!joined) joined = array.slice(0, i);
				joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text);
			} else if (joined) joined.push(node);
		}
		return new Fragment$8(joined || array, size);
	}
	/**
	Create a fragment from something that can be interpreted as a
	set of nodes. For `null`, it returns the empty fragment. For a
	fragment, the fragment itself. For a node or array of nodes, a
	fragment containing those nodes.
	*/
	static from(nodes) {
		if (!nodes) return Fragment$8.empty;
		if (nodes instanceof Fragment$8) return nodes;
		if (Array.isArray(nodes)) return this.fromArray(nodes);
		if (nodes.attrs) return new Fragment$8([nodes], nodes.nodeSize);
		throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
	}
};
/**
An empty fragment. Intended to be reused whenever a node doesn't
contain anything (rather than allocating a new empty fragment for
each leaf node).
*/
Fragment$8.empty = new Fragment$8([], 0);
var found = {
	index: 0,
	offset: 0
};
function retIndex(index, offset) {
	found.index = index;
	found.offset = offset;
	return found;
}
function compareDeep(a, b) {
	if (a === b) return true;
	if (!(a && typeof a == "object") || !(b && typeof b == "object")) return false;
	let array = Array.isArray(a);
	if (Array.isArray(b) != array) return false;
	if (array) {
		if (a.length != b.length) return false;
		for (let i = 0; i < a.length; i++) if (!compareDeep(a[i], b[i])) return false;
	} else {
		for (let p in a) if (!(p in b) || !compareDeep(a[p], b[p])) return false;
		for (let p in b) if (!(p in a)) return false;
	}
	return true;
}
/**
A mark is a piece of information that can be attached to a node,
such as it being emphasized, in code font, or a link. It has a
type and optionally a set of attributes that provide further
information (such as the target of the link). Marks are created
through a `Schema`, which controls which types exist and which
attributes they have.
*/
var Mark$1 = class Mark$1 {
	/**
	@internal
	*/
	constructor(type, attrs) {
		this.type = type;
		this.attrs = attrs;
	}
	/**
	Given a set of marks, create a new set which contains this one as
	well, in the right position. If this mark is already in the set,
	the set itself is returned. If any marks that are set to be
	[exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present,
	those are replaced by this one.
	*/
	addToSet(set) {
		let copy, placed = false;
		for (let i = 0; i < set.length; i++) {
			let other = set[i];
			if (this.eq(other)) return set;
			if (this.type.excludes(other.type)) {
				if (!copy) copy = set.slice(0, i);
			} else if (other.type.excludes(this.type)) return set;
			else {
				if (!placed && other.type.rank > this.type.rank) {
					if (!copy) copy = set.slice(0, i);
					copy.push(this);
					placed = true;
				}
				if (copy) copy.push(other);
			}
		}
		if (!copy) copy = set.slice();
		if (!placed) copy.push(this);
		return copy;
	}
	/**
	Remove this mark from the given set, returning a new set. If this
	mark is not in the set, the set itself is returned.
	*/
	removeFromSet(set) {
		for (let i = 0; i < set.length; i++) if (this.eq(set[i])) return set.slice(0, i).concat(set.slice(i + 1));
		return set;
	}
	/**
	Test whether this mark is in the given set of marks.
	*/
	isInSet(set) {
		for (let i = 0; i < set.length; i++) if (this.eq(set[i])) return true;
		return false;
	}
	/**
	Test whether this mark has the same type and attributes as
	another mark.
	*/
	eq(other) {
		return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs);
	}
	/**
	Convert this mark to a JSON-serializeable representation.
	*/
	toJSON() {
		let obj = { type: this.type.name };
		for (let _ in this.attrs) {
			obj.attrs = this.attrs;
			break;
		}
		return obj;
	}
	/**
	Deserialize a mark from JSON.
	*/
	static fromJSON(schema, json) {
		if (!json) throw new RangeError("Invalid input for Mark.fromJSON");
		let type = schema.marks[json.type];
		if (!type) throw new RangeError(`There is no mark type ${json.type} in this schema`);
		let mark = type.create(json.attrs);
		type.checkAttrs(mark.attrs);
		return mark;
	}
	/**
	Test whether two sets of marks are identical.
	*/
	static sameSet(a, b) {
		if (a == b) return true;
		if (a.length != b.length) return false;
		for (let i = 0; i < a.length; i++) if (!a[i].eq(b[i])) return false;
		return true;
	}
	/**
	Create a properly sorted mark set from null, a single mark, or an
	unsorted array of marks.
	*/
	static setFrom(marks) {
		if (!marks || Array.isArray(marks) && marks.length == 0) return Mark$1.none;
		if (marks instanceof Mark$1) return [marks];
		let copy = marks.slice();
		copy.sort((a, b) => a.type.rank - b.type.rank);
		return copy;
	}
};
/**
The empty set of marks.
*/
Mark$1.none = [];
/**
Error type raised by [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) when
given an invalid replacement.
*/
var ReplaceError = class extends Error {};
/**
A slice represents a piece cut out of a larger document. It
stores not only a fragment, but also the depth up to which nodes on
both side are ‘open’ (cut through).
*/
var Slice = class Slice {
	/**
	Create a slice. When specifying a non-zero open depth, you must
	make sure that there are nodes of at least that depth at the
	appropriate side of the fragment—i.e. if the fragment is an
	empty paragraph node, `openStart` and `openEnd` can't be greater
	than 1.
	
	It is not necessary for the content of open nodes to conform to
	the schema's content constraints, though it should be a valid
	start/end/middle for such a node, depending on which sides are
	open.
	*/
	constructor(content, openStart, openEnd) {
		this.content = content;
		this.openStart = openStart;
		this.openEnd = openEnd;
	}
	/**
	The size this slice would add when inserted into a document.
	*/
	get size() {
		return this.content.size - this.openStart - this.openEnd;
	}
	/**
	@internal
	*/
	insertAt(pos, fragment) {
		let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
		return content && new Slice(content, this.openStart, this.openEnd);
	}
	/**
	@internal
	*/
	removeBetween(from, to) {
		return new Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
	}
	/**
	Tests whether this slice is equal to another slice.
	*/
	eq(other) {
		return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
	}
	/**
	@internal
	*/
	toString() {
		return this.content + "(" + this.openStart + "," + this.openEnd + ")";
	}
	/**
	Convert a slice to a JSON-serializable representation.
	*/
	toJSON() {
		if (!this.content.size) return null;
		let json = { content: this.content.toJSON() };
		if (this.openStart > 0) json.openStart = this.openStart;
		if (this.openEnd > 0) json.openEnd = this.openEnd;
		return json;
	}
	/**
	Deserialize a slice from its JSON representation.
	*/
	static fromJSON(schema, json) {
		if (!json) return Slice.empty;
		let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
		if (typeof openStart != "number" || typeof openEnd != "number") throw new RangeError("Invalid input for Slice.fromJSON");
		return new Slice(Fragment$8.fromJSON(schema, json.content), openStart, openEnd);
	}
	/**
	Create a slice from a fragment by taking the maximum possible
	open value on both side of the fragment.
	*/
	static maxOpen(fragment, openIsolating = true) {
		let openStart = 0, openEnd = 0;
		for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild) openStart++;
		for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild) openEnd++;
		return new Slice(fragment, openStart, openEnd);
	}
};
/**
The empty slice.
*/
Slice.empty = new Slice(Fragment$8.empty, 0, 0);
function removeRange(content, from, to) {
	let { index, offset } = content.findIndex(from), child = content.maybeChild(index);
	let { index: indexTo, offset: offsetTo } = content.findIndex(to);
	if (offset == from || child.isText) {
		if (offsetTo != to && !content.child(indexTo).isText) throw new RangeError("Removing non-flat range");
		return content.cut(0, from).append(content.cut(to));
	}
	if (index != indexTo) throw new RangeError("Removing non-flat range");
	return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
}
function insertInto(content, dist, insert, openStart, openEnd, parent) {
	let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
	if (offset == dist || child.isText) {
		if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert)) return null;
		return content.cut(0, dist).append(insert).append(content.cut(dist));
	}
	let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child);
	return inner && content.replaceChild(index, child.copy(inner));
}
function replace($from, $to, slice) {
	if (slice.openStart > $from.depth) throw new ReplaceError("Inserted content deeper than insertion position");
	if ($from.depth - slice.openStart != $to.depth - slice.openEnd) throw new ReplaceError("Inconsistent open depths");
	return replaceOuter($from, $to, slice, 0);
}
function replaceOuter($from, $to, slice, depth) {
	let index = $from.index(depth), node = $from.node(depth);
	if (index == $to.index(depth) && depth < $from.depth - slice.openStart) {
		let inner = replaceOuter($from, $to, slice, depth + 1);
		return node.copy(node.content.replaceChild(index, inner));
	} else if (!slice.content.size) return close(node, replaceTwoWay($from, $to, depth));
	else if (!slice.openStart && !slice.openEnd && $from.depth == depth && $to.depth == depth) {
		let parent = $from.parent, content = parent.content;
		return close(parent, content.cut(0, $from.parentOffset).append(slice.content).append(content.cut($to.parentOffset)));
	} else {
		let { start, end } = prepareSliceForReplace(slice, $from);
		return close(node, replaceThreeWay($from, start, end, $to, depth));
	}
}
function checkJoin(main, sub) {
	if (!sub.type.compatibleContent(main.type)) throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main.type.name);
}
function joinable$1($before, $after, depth) {
	let node = $before.node(depth);
	checkJoin(node, $after.node(depth));
	return node;
}
function addNode(child, target) {
	let last = target.length - 1;
	if (last >= 0 && child.isText && child.sameMarkup(target[last])) target[last] = child.withText(target[last].text + child.text);
	else target.push(child);
}
function addRange($start, $end, depth, target) {
	let node = ($end || $start).node(depth);
	let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount;
	if ($start) {
		startIndex = $start.index(depth);
		if ($start.depth > depth) startIndex++;
		else if ($start.textOffset) {
			addNode($start.nodeAfter, target);
			startIndex++;
		}
	}
	for (let i = startIndex; i < endIndex; i++) addNode(node.child(i), target);
	if ($end && $end.depth == depth && $end.textOffset) addNode($end.nodeBefore, target);
}
function close(node, content) {
	if (!node.type.validContent(content)) throw new ReplaceError("Invalid content for node " + node.type.name);
	return node.copy(content);
}
function replaceThreeWay($from, $start, $end, $to, depth) {
	let openStart = $from.depth > depth && joinable$1($from, $start, depth + 1);
	let openEnd = $to.depth > depth && joinable$1($end, $to, depth + 1);
	let content = [];
	addRange(null, $from, depth, content);
	if (openStart && openEnd && $start.index(depth) == $end.index(depth)) {
		checkJoin(openStart, openEnd);
		addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content);
	} else {
		if (openStart) addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content);
		addRange($start, $end, depth, content);
		if (openEnd) addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
	}
	addRange($to, null, depth, content);
	return new Fragment$8(content);
}
function replaceTwoWay($from, $to, depth) {
	let content = [];
	addRange(null, $from, depth, content);
	if ($from.depth > depth) addNode(close(joinable$1($from, $to, depth + 1), replaceTwoWay($from, $to, depth + 1)), content);
	addRange($to, null, depth, content);
	return new Fragment$8(content);
}
function prepareSliceForReplace(slice, $along) {
	let extra = $along.depth - slice.openStart;
	let node = $along.node(extra).copy(slice.content);
	for (let i = extra - 1; i >= 0; i--) node = $along.node(i).copy(Fragment$8.from(node));
	return {
		start: node.resolveNoCache(slice.openStart + extra),
		end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
	};
}
/**
You can [_resolve_](https://prosemirror.net/docs/ref/#model.Node.resolve) a position to get more
information about it. Objects of this class represent such a
resolved position, providing various pieces of context
information, and some helper methods.

Throughout this interface, methods that take an optional `depth`
parameter will interpret undefined as `this.depth` and negative
numbers as `this.depth + value`.
*/
var ResolvedPos = class ResolvedPos {
	/**
	@internal
	*/
	constructor(pos, path, parentOffset) {
		this.pos = pos;
		this.path = path;
		this.parentOffset = parentOffset;
		this.depth = path.length / 3 - 1;
	}
	/**
	@internal
	*/
	resolveDepth(val) {
		if (val == null) return this.depth;
		if (val < 0) return this.depth + val;
		return val;
	}
	/**
	The parent node that the position points into. Note that even if
	a position points into a text node, that node is not considered
	the parent—text nodes are ‘flat’ in this model, and have no content.
	*/
	get parent() {
		return this.node(this.depth);
	}
	/**
	The root node in which the position was resolved.
	*/
	get doc() {
		return this.node(0);
	}
	/**
	The ancestor node at the given level. `p.node(p.depth)` is the
	same as `p.parent`.
	*/
	node(depth) {
		return this.path[this.resolveDepth(depth) * 3];
	}
	/**
	The index into the ancestor at the given level. If this points
	at the 3rd node in the 2nd paragraph on the top level, for
	example, `p.index(0)` is 1 and `p.index(1)` is 2.
	*/
	index(depth) {
		return this.path[this.resolveDepth(depth) * 3 + 1];
	}
	/**
	The index pointing after this position into the ancestor at the
	given level.
	*/
	indexAfter(depth) {
		depth = this.resolveDepth(depth);
		return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1);
	}
	/**
	The (absolute) position at the start of the node at the given
	level.
	*/
	start(depth) {
		depth = this.resolveDepth(depth);
		return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
	}
	/**
	The (absolute) position at the end of the node at the given
	level.
	*/
	end(depth) {
		depth = this.resolveDepth(depth);
		return this.start(depth) + this.node(depth).content.size;
	}
	/**
	The (absolute) position directly before the wrapping node at the
	given level, or, when `depth` is `this.depth + 1`, the original
	position.
	*/
	before(depth) {
		depth = this.resolveDepth(depth);
		if (!depth) throw new RangeError("There is no position before the top-level node");
		return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1];
	}
	/**
	The (absolute) position directly after the wrapping node at the
	given level, or the original position when `depth` is `this.depth + 1`.
	*/
	after(depth) {
		depth = this.resolveDepth(depth);
		if (!depth) throw new RangeError("There is no position after the top-level node");
		return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize;
	}
	/**
	When this position points into a text node, this returns the
	distance between the position and the start of the text node.
	Will be zero for positions that point between nodes.
	*/
	get textOffset() {
		return this.pos - this.path[this.path.length - 1];
	}
	/**
	Get the node directly after the position, if any. If the position
	points into a text node, only the part of that node after the
	position is returned.
	*/
	get nodeAfter() {
		let parent = this.parent, index = this.index(this.depth);
		if (index == parent.childCount) return null;
		let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index);
		return dOff ? parent.child(index).cut(dOff) : child;
	}
	/**
	Get the node directly before the position, if any. If the
	position points into a text node, only the part of that node
	before the position is returned.
	*/
	get nodeBefore() {
		let index = this.index(this.depth);
		let dOff = this.pos - this.path[this.path.length - 1];
		if (dOff) return this.parent.child(index).cut(0, dOff);
		return index == 0 ? null : this.parent.child(index - 1);
	}
	/**
	Get the position at the given index in the parent node at the
	given depth (which defaults to `this.depth`).
	*/
	posAtIndex(index, depth) {
		depth = this.resolveDepth(depth);
		let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
		for (let i = 0; i < index; i++) pos += node.child(i).nodeSize;
		return pos;
	}
	/**
	Get the marks at this position, factoring in the surrounding
	marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the
	position is at the start of a non-empty node, the marks of the
	node after it (if any) are returned.
	*/
	marks() {
		let parent = this.parent, index = this.index();
		if (parent.content.size == 0) return Mark$1.none;
		if (this.textOffset) return parent.child(index).marks;
		let main = parent.maybeChild(index - 1), other = parent.maybeChild(index);
		if (!main) {
			let tmp = main;
			main = other;
			other = tmp;
		}
		let marks = main.marks;
		for (var i = 0; i < marks.length; i++) if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks))) marks = marks[i--].removeFromSet(marks);
		return marks;
	}
	/**
	Get the marks after the current position, if any, except those
	that are non-inclusive and not present at position `$end`. This
	is mostly useful for getting the set of marks to preserve after a
	deletion. Will return `null` if this position is at the end of
	its parent node or its parent node isn't a textblock (in which
	case no marks should be preserved).
	*/
	marksAcross($end) {
		let after = this.parent.maybeChild(this.index());
		if (!after || !after.isInline) return null;
		let marks = after.marks, next = $end.parent.maybeChild($end.index());
		for (var i = 0; i < marks.length; i++) if (marks[i].type.spec.inclusive === false && (!next || !marks[i].isInSet(next.marks))) marks = marks[i--].removeFromSet(marks);
		return marks;
	}
	/**
	The depth up to which this position and the given (non-resolved)
	position share the same parent nodes.
	*/
	sharedDepth(pos) {
		for (let depth = this.depth; depth > 0; depth--) if (this.start(depth) <= pos && this.end(depth) >= pos) return depth;
		return 0;
	}
	/**
	Returns a range based on the place where this position and the
	given position diverge around block content. If both point into
	the same textblock, for example, a range around that textblock
	will be returned. If they point into different blocks, the range
	around those blocks in their shared ancestor is returned. You can
	pass in an optional predicate that will be called with a parent
	node to see if a range into that parent is acceptable.
	*/
	blockRange(other = this, pred) {
		if (other.pos < this.pos) return other.blockRange(this);
		for (let d = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d >= 0; d--) if (other.pos <= this.end(d) && (!pred || pred(this.node(d)))) return new NodeRange(this, other, d);
		return null;
	}
	/**
	Query whether the given position shares the same parent node.
	*/
	sameParent(other) {
		return this.pos - this.parentOffset == other.pos - other.parentOffset;
	}
	/**
	Return the greater of this and the given position.
	*/
	max(other) {
		return other.pos > this.pos ? other : this;
	}
	/**
	Return the smaller of this and the given position.
	*/
	min(other) {
		return other.pos < this.pos ? other : this;
	}
	/**
	@internal
	*/
	toString() {
		let str = "";
		for (let i = 1; i <= this.depth; i++) str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1);
		return str + ":" + this.parentOffset;
	}
	/**
	@internal
	*/
	static resolve(doc, pos) {
		if (!(pos >= 0 && pos <= doc.content.size)) throw new RangeError("Position " + pos + " out of range");
		let path = [];
		let start = 0, parentOffset = pos;
		for (let node = doc;;) {
			let { index, offset } = node.content.findIndex(parentOffset);
			let rem = parentOffset - offset;
			path.push(node, index, start + offset);
			if (!rem) break;
			node = node.child(index);
			if (node.isText) break;
			parentOffset = rem - 1;
			start += offset + 1;
		}
		return new ResolvedPos(pos, path, parentOffset);
	}
	/**
	@internal
	*/
	static resolveCached(doc, pos) {
		let cache = resolveCache.get(doc);
		if (cache) for (let i = 0; i < cache.elts.length; i++) {
			let elt = cache.elts[i];
			if (elt.pos == pos) return elt;
		}
		else resolveCache.set(doc, cache = new ResolveCache());
		let result = cache.elts[cache.i] = ResolvedPos.resolve(doc, pos);
		cache.i = (cache.i + 1) % resolveCacheSize;
		return result;
	}
};
var ResolveCache = class {
	constructor() {
		this.elts = [];
		this.i = 0;
	}
};
var resolveCacheSize = 12;
var resolveCache = /* @__PURE__ */ new WeakMap();
/**
Represents a flat range of content, i.e. one that starts and
ends in the same node.
*/
var NodeRange = class {
	/**
	Construct a node range. `$from` and `$to` should point into the
	same node until at least the given `depth`, since a node range
	denotes an adjacent set of nodes in a single parent node.
	*/
	constructor($from, $to, depth) {
		this.$from = $from;
		this.$to = $to;
		this.depth = depth;
	}
	/**
	The position at the start of the range.
	*/
	get start() {
		return this.$from.before(this.depth + 1);
	}
	/**
	The position at the end of the range.
	*/
	get end() {
		return this.$to.after(this.depth + 1);
	}
	/**
	The parent node that the range points into.
	*/
	get parent() {
		return this.$from.node(this.depth);
	}
	/**
	The start index of the range in the parent node.
	*/
	get startIndex() {
		return this.$from.index(this.depth);
	}
	/**
	The end index of the range in the parent node.
	*/
	get endIndex() {
		return this.$to.indexAfter(this.depth);
	}
};
var emptyAttrs = Object.create(null);
/**
This class represents a node in the tree that makes up a
ProseMirror document. So a document is an instance of `Node`, with
children that are also instances of `Node`.

Nodes are persistent data structures. Instead of changing them, you
create new ones with the content you want. Old ones keep pointing
at the old document shape. This is made cheaper by sharing
structure between the old and new data as much as possible, which a
tree shape like this (without back pointers) makes easy.

**Do not** directly mutate the properties of a `Node` object. See
[the guide](https://prosemirror.net/docs/guide/#doc) for more information.
*/
var Node$1 = class Node$1 {
	/**
	@internal
	*/
	constructor(type, attrs, content, marks = Mark$1.none) {
		this.type = type;
		this.attrs = attrs;
		this.marks = marks;
		this.content = content || Fragment$8.empty;
	}
	/**
	The array of this node's child nodes.
	*/
	get children() {
		return this.content.content;
	}
	/**
	The size of this node, as defined by the integer-based [indexing
	scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the
	amount of characters. For other leaf nodes, it is one. For
	non-leaf nodes, it is the size of the content plus two (the
	start and end token).
	*/
	get nodeSize() {
		return this.isLeaf ? 1 : 2 + this.content.size;
	}
	/**
	The number of children that the node has.
	*/
	get childCount() {
		return this.content.childCount;
	}
	/**
	Get the child node at the given index. Raises an error when the
	index is out of range.
	*/
	child(index) {
		return this.content.child(index);
	}
	/**
	Get the child node at the given index, if it exists.
	*/
	maybeChild(index) {
		return this.content.maybeChild(index);
	}
	/**
	Call `f` for every child node, passing the node, its offset
	into this parent node, and its index.
	*/
	forEach(f) {
		this.content.forEach(f);
	}
	/**
	Invoke a callback for all descendant nodes recursively overlapping
	the given two positions that are relative to start of this
	node's content. This includes all ancestors of the nodes
	containing the two positions. The callback is invoked with the
	node, its position relative to the original node (method receiver),
	its parent node, and its child index. When the callback returns
	false for a given node, that node's children will not be
	recursed over. The last parameter can be used to specify a
	starting position to count from.
	*/
	nodesBetween(from, to, f, startPos = 0) {
		this.content.nodesBetween(from, to, f, startPos, this);
	}
	/**
	Call the given callback for every descendant node. Doesn't
	descend into a node when the callback returns `false`.
	*/
	descendants(f) {
		this.nodesBetween(0, this.content.size, f);
	}
	/**
	Concatenates all the text nodes found in this fragment and its
	children.
	*/
	get textContent() {
		return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, "");
	}
	/**
	Get all text between positions `from` and `to`. When
	`blockSeparator` is given, it will be inserted to separate text
	from different block nodes. If `leafText` is given, it'll be
	inserted for every non-text leaf node encountered, otherwise
	[`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
	*/
	textBetween(from, to, blockSeparator, leafText) {
		return this.content.textBetween(from, to, blockSeparator, leafText);
	}
	/**
	Returns this node's first child, or `null` if there are no
	children.
	*/
	get firstChild() {
		return this.content.firstChild;
	}
	/**
	Returns this node's last child, or `null` if there are no
	children.
	*/
	get lastChild() {
		return this.content.lastChild;
	}
	/**
	Test whether two nodes represent the same piece of document.
	*/
	eq(other) {
		return this == other || this.sameMarkup(other) && this.content.eq(other.content);
	}
	/**
	Compare the markup (type, attributes, and marks) of this node to
	those of another. Returns `true` if both have the same markup.
	*/
	sameMarkup(other) {
		return this.hasMarkup(other.type, other.attrs, other.marks);
	}
	/**
	Check whether this node's markup correspond to the given type,
	attributes, and marks.
	*/
	hasMarkup(type, attrs, marks) {
		return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark$1.sameSet(this.marks, marks || Mark$1.none);
	}
	/**
	Create a new node with the same markup as this node, containing
	the given content (or empty, if no content is given).
	*/
	copy(content = null) {
		if (content == this.content) return this;
		return new Node$1(this.type, this.attrs, content, this.marks);
	}
	/**
	Create a copy of this node, with the given set of marks instead
	of the node's own marks.
	*/
	mark(marks) {
		return marks == this.marks ? this : new Node$1(this.type, this.attrs, this.content, marks);
	}
	/**
	Create a copy of this node with only the content between the
	given positions. If `to` is not given, it defaults to the end of
	the node.
	*/
	cut(from, to = this.content.size) {
		if (from == 0 && to == this.content.size) return this;
		return this.copy(this.content.cut(from, to));
	}
	/**
	Cut out the part of the document between the given positions, and
	return it as a `Slice` object.
	*/
	slice(from, to = this.content.size, includeParents = false) {
		if (from == to) return Slice.empty;
		let $from = this.resolve(from), $to = this.resolve(to);
		let depth = includeParents ? 0 : $from.sharedDepth(to);
		let start = $from.start(depth);
		return new Slice($from.node(depth).content.cut($from.pos - start, $to.pos - start), $from.depth - depth, $to.depth - depth);
	}
	/**
	Replace the part of the document between the given positions with
	the given slice. The slice must 'fit', meaning its open sides
	must be able to connect to the surrounding content, and its
	content nodes must be valid children for the node they are placed
	into. If any of this is violated, an error of type
	[`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown.
	*/
	replace(from, to, slice) {
		return replace(this.resolve(from), this.resolve(to), slice);
	}
	/**
	Find the node directly after the given position.
	*/
	nodeAt(pos) {
		for (let node = this;;) {
			let { index, offset } = node.content.findIndex(pos);
			node = node.maybeChild(index);
			if (!node) return null;
			if (offset == pos || node.isText) return node;
			pos -= offset + 1;
		}
	}
	/**
	Find the (direct) child node after the given offset, if any,
	and return it along with its index and offset relative to this
	node.
	*/
	childAfter(pos) {
		let { index, offset } = this.content.findIndex(pos);
		return {
			node: this.content.maybeChild(index),
			index,
			offset
		};
	}
	/**
	Find the (direct) child node before the given offset, if any,
	and return it along with its index and offset relative to this
	node.
	*/
	childBefore(pos) {
		if (pos == 0) return {
			node: null,
			index: 0,
			offset: 0
		};
		let { index, offset } = this.content.findIndex(pos);
		if (offset < pos) return {
			node: this.content.child(index),
			index,
			offset
		};
		let node = this.content.child(index - 1);
		return {
			node,
			index: index - 1,
			offset: offset - node.nodeSize
		};
	}
	/**
	Resolve the given position in the document, returning an
	[object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context.
	*/
	resolve(pos) {
		return ResolvedPos.resolveCached(this, pos);
	}
	/**
	@internal
	*/
	resolveNoCache(pos) {
		return ResolvedPos.resolve(this, pos);
	}
	/**
	Test whether a given mark or mark type occurs in this document
	between the two given positions.
	*/
	rangeHasMark(from, to, type) {
		let found = false;
		if (to > from) this.nodesBetween(from, to, (node) => {
			if (type.isInSet(node.marks)) found = true;
			return !found;
		});
		return found;
	}
	/**
	True when this is a block (non-inline node)
	*/
	get isBlock() {
		return this.type.isBlock;
	}
	/**
	True when this is a textblock node, a block node with inline
	content.
	*/
	get isTextblock() {
		return this.type.isTextblock;
	}
	/**
	True when this node allows inline content.
	*/
	get inlineContent() {
		return this.type.inlineContent;
	}
	/**
	True when this is an inline node (a text node or a node that can
	appear among text).
	*/
	get isInline() {
		return this.type.isInline;
	}
	/**
	True when this is a text node.
	*/
	get isText() {
		return this.type.isText;
	}
	/**
	True when this is a leaf node.
	*/
	get isLeaf() {
		return this.type.isLeaf;
	}
	/**
	True when this is an atom, i.e. when it does not have directly
	editable content. This is usually the same as `isLeaf`, but can
	be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom)
	on a node's spec (typically used when the node is displayed as
	an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)).
	*/
	get isAtom() {
		return this.type.isAtom;
	}
	/**
	Return a string representation of this node for debugging
	purposes.
	*/
	toString() {
		if (this.type.spec.toDebugString) return this.type.spec.toDebugString(this);
		let name = this.type.name;
		if (this.content.size) name += "(" + this.content.toStringInner() + ")";
		return wrapMarks(this.marks, name);
	}
	/**
	Get the content match in this node at the given index.
	*/
	contentMatchAt(index) {
		let match = this.type.contentMatch.matchFragment(this.content, 0, index);
		if (!match) throw new Error("Called contentMatchAt on a node with invalid content");
		return match;
	}
	/**
	Test whether replacing the range between `from` and `to` (by
	child index) with the given replacement fragment (which defaults
	to the empty fragment) would leave the node's content valid. You
	can optionally pass `start` and `end` indices into the
	replacement fragment.
	*/
	canReplace(from, to, replacement = Fragment$8.empty, start = 0, end = replacement.childCount) {
		let one = this.contentMatchAt(from).matchFragment(replacement, start, end);
		let two = one && one.matchFragment(this.content, to);
		if (!two || !two.validEnd) return false;
		for (let i = start; i < end; i++) if (!this.type.allowsMarks(replacement.child(i).marks)) return false;
		return true;
	}
	/**
	Test whether replacing the range `from` to `to` (by index) with
	a node of the given type would leave the node's content valid.
	*/
	canReplaceWith(from, to, type, marks) {
		if (marks && !this.type.allowsMarks(marks)) return false;
		let start = this.contentMatchAt(from).matchType(type);
		let end = start && start.matchFragment(this.content, to);
		return end ? end.validEnd : false;
	}
	/**
	Test whether the given node's content could be appended to this
	node. If that node is empty, this will only return true if there
	is at least one node type that can appear in both nodes (to avoid
	merging completely incompatible nodes).
	*/
	canAppend(other) {
		if (other.content.size) return this.canReplace(this.childCount, this.childCount, other.content);
		else return this.type.compatibleContent(other.type);
	}
	/**
	Check whether this node and its descendants conform to the
	schema, and raise an exception when they do not.
	*/
	check() {
		this.type.checkContent(this.content);
		this.type.checkAttrs(this.attrs);
		let copy = Mark$1.none;
		for (let i = 0; i < this.marks.length; i++) {
			let mark = this.marks[i];
			mark.type.checkAttrs(mark.attrs);
			copy = mark.addToSet(copy);
		}
		if (!Mark$1.sameSet(copy, this.marks)) throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m) => m.type.name)}`);
		this.content.forEach((node) => node.check());
	}
	/**
	Return a JSON-serializeable representation of this node.
	*/
	toJSON() {
		let obj = { type: this.type.name };
		for (let _ in this.attrs) {
			obj.attrs = this.attrs;
			break;
		}
		if (this.content.size) obj.content = this.content.toJSON();
		if (this.marks.length) obj.marks = this.marks.map((n) => n.toJSON());
		return obj;
	}
	/**
	Deserialize a node from its JSON representation.
	*/
	static fromJSON(schema, json) {
		if (!json) throw new RangeError("Invalid input for Node.fromJSON");
		let marks = void 0;
		if (json.marks) {
			if (!Array.isArray(json.marks)) throw new RangeError("Invalid mark data for Node.fromJSON");
			marks = json.marks.map(schema.markFromJSON);
		}
		if (json.type == "text") {
			if (typeof json.text != "string") throw new RangeError("Invalid text node in JSON");
			return schema.text(json.text, marks);
		}
		let content = Fragment$8.fromJSON(schema, json.content);
		let node = schema.nodeType(json.type).create(json.attrs, content, marks);
		node.type.checkAttrs(node.attrs);
		return node;
	}
};
Node$1.prototype.text = void 0;
var TextNode = class TextNode extends Node$1 {
	/**
	@internal
	*/
	constructor(type, attrs, content, marks) {
		super(type, attrs, null, marks);
		if (!content) throw new RangeError("Empty text nodes are not allowed");
		this.text = content;
	}
	toString() {
		if (this.type.spec.toDebugString) return this.type.spec.toDebugString(this);
		return wrapMarks(this.marks, JSON.stringify(this.text));
	}
	get textContent() {
		return this.text;
	}
	textBetween(from, to) {
		return this.text.slice(from, to);
	}
	get nodeSize() {
		return this.text.length;
	}
	mark(marks) {
		return marks == this.marks ? this : new TextNode(this.type, this.attrs, this.text, marks);
	}
	withText(text) {
		if (text == this.text) return this;
		return new TextNode(this.type, this.attrs, text, this.marks);
	}
	cut(from = 0, to = this.text.length) {
		if (from == 0 && to == this.text.length) return this;
		return this.withText(this.text.slice(from, to));
	}
	eq(other) {
		return this.sameMarkup(other) && this.text == other.text;
	}
	toJSON() {
		let base = super.toJSON();
		base.text = this.text;
		return base;
	}
};
function wrapMarks(marks, str) {
	for (let i = marks.length - 1; i >= 0; i--) str = marks[i].type.name + "(" + str + ")";
	return str;
}
/**
Instances of this class represent a match state of a node type's
[content expression](https://prosemirror.net/docs/ref/#model.NodeSpec.content), and can be used to
find out whether further content matches here, and whether a given
position is a valid end of the node.
*/
var ContentMatch = class ContentMatch {
	/**
	@internal
	*/
	constructor(validEnd) {
		this.validEnd = validEnd;
		/**
		@internal
		*/
		this.next = [];
		/**
		@internal
		*/
		this.wrapCache = [];
	}
	/**
	@internal
	*/
	static parse(string, nodeTypes) {
		let stream = new TokenStream(string, nodeTypes);
		if (stream.next == null) return ContentMatch.empty;
		let expr = parseExpr(stream);
		if (stream.next) stream.err("Unexpected trailing text");
		let match = dfa(nfa(expr));
		checkForDeadEnds(match, stream);
		return match;
	}
	/**
	Match a node type, returning a match after that node if
	successful.
	*/
	matchType(type) {
		for (let i = 0; i < this.next.length; i++) if (this.next[i].type == type) return this.next[i].next;
		return null;
	}
	/**
	Try to match a fragment. Returns the resulting match when
	successful.
	*/
	matchFragment(frag, start = 0, end = frag.childCount) {
		let cur = this;
		for (let i = start; cur && i < end; i++) cur = cur.matchType(frag.child(i).type);
		return cur;
	}
	/**
	@internal
	*/
	get inlineContent() {
		return this.next.length != 0 && this.next[0].type.isInline;
	}
	/**
	Get the first matching node type at this match position that can
	be generated.
	*/
	get defaultType() {
		for (let i = 0; i < this.next.length; i++) {
			let { type } = this.next[i];
			if (!(type.isText || type.hasRequiredAttrs())) return type;
		}
		return null;
	}
	/**
	@internal
	*/
	compatible(other) {
		for (let i = 0; i < this.next.length; i++) for (let j = 0; j < other.next.length; j++) if (this.next[i].type == other.next[j].type) return true;
		return false;
	}
	/**
	Try to match the given fragment, and if that fails, see if it can
	be made to match by inserting nodes in front of it. When
	successful, return a fragment of inserted nodes (which may be
	empty if nothing had to be inserted). When `toEnd` is true, only
	return a fragment if the resulting match goes to the end of the
	content expression.
	*/
	fillBefore(after, toEnd = false, startIndex = 0) {
		let seen = [this];
		function search(match, types) {
			let finished = match.matchFragment(after, startIndex);
			if (finished && (!toEnd || finished.validEnd)) return Fragment$8.from(types.map((tp) => tp.createAndFill()));
			for (let i = 0; i < match.next.length; i++) {
				let { type, next } = match.next[i];
				if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
					seen.push(next);
					let found = search(next, types.concat(type));
					if (found) return found;
				}
			}
			return null;
		}
		return search(this, []);
	}
	/**
	Find a set of wrapping node types that would allow a node of the
	given type to appear at this position. The result may be empty
	(when it fits directly) and will be null when no such wrapping
	exists.
	*/
	findWrapping(target) {
		for (let i = 0; i < this.wrapCache.length; i += 2) if (this.wrapCache[i] == target) return this.wrapCache[i + 1];
		let computed = this.computeWrapping(target);
		this.wrapCache.push(target, computed);
		return computed;
	}
	/**
	@internal
	*/
	computeWrapping(target) {
		let seen = Object.create(null), active = [{
			match: this,
			type: null,
			via: null
		}];
		while (active.length) {
			let current = active.shift(), match = current.match;
			if (match.matchType(target)) {
				let result = [];
				for (let obj = current; obj.type; obj = obj.via) result.push(obj.type);
				return result.reverse();
			}
			for (let i = 0; i < match.next.length; i++) {
				let { type, next } = match.next[i];
				if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) {
					active.push({
						match: type.contentMatch,
						type,
						via: current
					});
					seen[type.name] = true;
				}
			}
		}
		return null;
	}
	/**
	The number of outgoing edges this node has in the finite
	automaton that describes the content expression.
	*/
	get edgeCount() {
		return this.next.length;
	}
	/**
	Get the _n_​th outgoing edge from this node in the finite
	automaton that describes the content expression.
	*/
	edge(n) {
		if (n >= this.next.length) throw new RangeError(`There's no ${n}th edge in this content match`);
		return this.next[n];
	}
	/**
	@internal
	*/
	toString() {
		let seen = [];
		function scan(m) {
			seen.push(m);
			for (let i = 0; i < m.next.length; i++) if (seen.indexOf(m.next[i].next) == -1) scan(m.next[i].next);
		}
		scan(this);
		return seen.map((m, i) => {
			let out = i + (m.validEnd ? "*" : " ") + " ";
			for (let i = 0; i < m.next.length; i++) out += (i ? ", " : "") + m.next[i].type.name + "->" + seen.indexOf(m.next[i].next);
			return out;
		}).join("\n");
	}
};
/**
@internal
*/
ContentMatch.empty = new ContentMatch(true);
var TokenStream = class {
	constructor(string, nodeTypes) {
		this.string = string;
		this.nodeTypes = nodeTypes;
		this.inline = null;
		this.pos = 0;
		this.tokens = string.split(/\s*(?=\b|\W|$)/);
		if (this.tokens[this.tokens.length - 1] == "") this.tokens.pop();
		if (this.tokens[0] == "") this.tokens.shift();
	}
	get next() {
		return this.tokens[this.pos];
	}
	eat(tok) {
		return this.next == tok && (this.pos++ || true);
	}
	err(str) {
		throw new SyntaxError(str + " (in content expression '" + this.string + "')");
	}
};
function parseExpr(stream) {
	let exprs = [];
	do
		exprs.push(parseExprSeq(stream));
	while (stream.eat("|"));
	return exprs.length == 1 ? exprs[0] : {
		type: "choice",
		exprs
	};
}
function parseExprSeq(stream) {
	let exprs = [];
	do
		exprs.push(parseExprSubscript(stream));
	while (stream.next && stream.next != ")" && stream.next != "|");
	return exprs.length == 1 ? exprs[0] : {
		type: "seq",
		exprs
	};
}
function parseExprSubscript(stream) {
	let expr = parseExprAtom(stream);
	for (;;) if (stream.eat("+")) expr = {
		type: "plus",
		expr
	};
	else if (stream.eat("*")) expr = {
		type: "star",
		expr
	};
	else if (stream.eat("?")) expr = {
		type: "opt",
		expr
	};
	else if (stream.eat("{")) expr = parseExprRange(stream, expr);
	else break;
	return expr;
}
function parseNum(stream) {
	if (/\D/.test(stream.next)) stream.err("Expected number, got '" + stream.next + "'");
	let result = Number(stream.next);
	stream.pos++;
	return result;
}
function parseExprRange(stream, expr) {
	let min = parseNum(stream), max = min;
	if (stream.eat(",")) {
		if (stream.next != "}") max = parseNum(stream);
		else max = -1;
	}
	if (!stream.eat("}")) stream.err("Unclosed braced range");
	return {
		type: "range",
		min,
		max,
		expr
	};
}
function resolveName(stream, name) {
	let types = stream.nodeTypes, type = types[name];
	if (type) return [type];
	let result = [];
	for (let typeName in types) {
		let type = types[typeName];
		if (type.isInGroup(name)) result.push(type);
	}
	if (result.length == 0) stream.err("No node type or group '" + name + "' found");
	return result;
}
function parseExprAtom(stream) {
	if (stream.eat("(")) {
		let expr = parseExpr(stream);
		if (!stream.eat(")")) stream.err("Missing closing paren");
		return expr;
	} else if (!/\W/.test(stream.next)) {
		let exprs = resolveName(stream, stream.next).map((type) => {
			if (stream.inline == null) stream.inline = type.isInline;
			else if (stream.inline != type.isInline) stream.err("Mixing inline and block content");
			return {
				type: "name",
				value: type
			};
		});
		stream.pos++;
		return exprs.length == 1 ? exprs[0] : {
			type: "choice",
			exprs
		};
	} else stream.err("Unexpected token '" + stream.next + "'");
}
function nfa(expr) {
	let nfa = [[]];
	connect(compile(expr, 0), node());
	return nfa;
	function node() {
		return nfa.push([]) - 1;
	}
	function edge(from, to, term) {
		let edge = {
			term,
			to
		};
		nfa[from].push(edge);
		return edge;
	}
	function connect(edges, to) {
		edges.forEach((edge) => edge.to = to);
	}
	function compile(expr, from) {
		if (expr.type == "choice") return expr.exprs.reduce((out, expr) => out.concat(compile(expr, from)), []);
		else if (expr.type == "seq") for (let i = 0;; i++) {
			let next = compile(expr.exprs[i], from);
			if (i == expr.exprs.length - 1) return next;
			connect(next, from = node());
		}
		else if (expr.type == "star") {
			let loop = node();
			edge(from, loop);
			connect(compile(expr.expr, loop), loop);
			return [edge(loop)];
		} else if (expr.type == "plus") {
			let loop = node();
			connect(compile(expr.expr, from), loop);
			connect(compile(expr.expr, loop), loop);
			return [edge(loop)];
		} else if (expr.type == "opt") return [edge(from)].concat(compile(expr.expr, from));
		else if (expr.type == "range") {
			let cur = from;
			for (let i = 0; i < expr.min; i++) {
				let next = node();
				connect(compile(expr.expr, cur), next);
				cur = next;
			}
			if (expr.max == -1) connect(compile(expr.expr, cur), cur);
			else for (let i = expr.min; i < expr.max; i++) {
				let next = node();
				edge(cur, next);
				connect(compile(expr.expr, cur), next);
				cur = next;
			}
			return [edge(cur)];
		} else if (expr.type == "name") return [edge(from, void 0, expr.value)];
		else throw new Error("Unknown expr type");
	}
}
function cmp(a, b) {
	return b - a;
}
function nullFrom(nfa, node) {
	let result = [];
	scan(node);
	return result.sort(cmp);
	function scan(node) {
		let edges = nfa[node];
		if (edges.length == 1 && !edges[0].term) return scan(edges[0].to);
		result.push(node);
		for (let i = 0; i < edges.length; i++) {
			let { term, to } = edges[i];
			if (!term && result.indexOf(to) == -1) scan(to);
		}
	}
}
function dfa(nfa) {
	let labeled = Object.create(null);
	return explore(nullFrom(nfa, 0));
	function explore(states) {
		let out = [];
		states.forEach((node) => {
			nfa[node].forEach(({ term, to }) => {
				if (!term) return;
				let set;
				for (let i = 0; i < out.length; i++) if (out[i][0] == term) set = out[i][1];
				nullFrom(nfa, to).forEach((node) => {
					if (!set) out.push([term, set = []]);
					if (set.indexOf(node) == -1) set.push(node);
				});
			});
		});
		let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa.length - 1) > -1);
		for (let i = 0; i < out.length; i++) {
			let states = out[i][1].sort(cmp);
			state.next.push({
				type: out[i][0],
				next: labeled[states.join(",")] || explore(states)
			});
		}
		return state;
	}
}
function checkForDeadEnds(match, stream) {
	for (let i = 0, work = [match]; i < work.length; i++) {
		let state = work[i], dead = !state.validEnd, nodes = [];
		for (let j = 0; j < state.next.length; j++) {
			let { type, next } = state.next[j];
			nodes.push(type.name);
			if (dead && !(type.isText || type.hasRequiredAttrs())) dead = false;
			if (work.indexOf(next) == -1) work.push(next);
		}
		if (dead) stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)");
	}
}
function defaultAttrs(attrs) {
	let defaults = Object.create(null);
	for (let attrName in attrs) {
		let attr = attrs[attrName];
		if (!attr.hasDefault) return null;
		defaults[attrName] = attr.default;
	}
	return defaults;
}
function computeAttrs(attrs, value) {
	let built = Object.create(null);
	for (let name in attrs) {
		let given = value && value[name];
		if (given === void 0) {
			let attr = attrs[name];
			if (attr.hasDefault) given = attr.default;
			else throw new RangeError("No value supplied for attribute " + name);
		}
		built[name] = given;
	}
	return built;
}
function checkAttrs(attrs, values, type, name) {
	for (let attr in values) if (!(attr in attrs)) throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
	for (let attr in attrs) if (attrs[attr].validate) attrs[attr].validate(values[attr]);
}
function initAttrs(typeName, attrs) {
	let result = Object.create(null);
	if (attrs) for (let name in attrs) result[name] = new Attribute(typeName, name, attrs[name]);
	return result;
}
/**
Node types are objects allocated once per `Schema` and used to
[tag](https://prosemirror.net/docs/ref/#model.Node.type) `Node` instances. They contain information
about the node type, such as its name and what kind of node it
represents.
*/
var NodeType$1 = class NodeType$1 {
	/**
	@internal
	*/
	constructor(name, schema, spec) {
		this.name = name;
		this.schema = schema;
		this.spec = spec;
		/**
		The set of marks allowed in this node. `null` means all marks
		are allowed.
		*/
		this.markSet = null;
		this.groups = spec.group ? spec.group.split(" ") : [];
		this.attrs = initAttrs(name, spec.attrs);
		this.defaultAttrs = defaultAttrs(this.attrs);
		this.contentMatch = null;
		this.inlineContent = null;
		this.isBlock = !(spec.inline || name == "text");
		this.isText = name == "text";
	}
	/**
	True if this is an inline type.
	*/
	get isInline() {
		return !this.isBlock;
	}
	/**
	True if this is a textblock type, a block that contains inline
	content.
	*/
	get isTextblock() {
		return this.isBlock && this.inlineContent;
	}
	/**
	True for node types that allow no content.
	*/
	get isLeaf() {
		return this.contentMatch == ContentMatch.empty;
	}
	/**
	True when this node is an atom, i.e. when it does not have
	directly editable content.
	*/
	get isAtom() {
		return this.isLeaf || !!this.spec.atom;
	}
	/**
	Return true when this node type is part of the given
	[group](https://prosemirror.net/docs/ref/#model.NodeSpec.group).
	*/
	isInGroup(group) {
		return this.groups.indexOf(group) > -1;
	}
	/**
	The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option.
	*/
	get whitespace() {
		return this.spec.whitespace || (this.spec.code ? "pre" : "normal");
	}
	/**
	Tells you whether this node type has any required attributes.
	*/
	hasRequiredAttrs() {
		for (let n in this.attrs) if (this.attrs[n].isRequired) return true;
		return false;
	}
	/**
	Indicates whether this node allows some of the same content as
	the given node type.
	*/
	compatibleContent(other) {
		return this == other || this.contentMatch.compatible(other.contentMatch);
	}
	/**
	@internal
	*/
	computeAttrs(attrs) {
		if (!attrs && this.defaultAttrs) return this.defaultAttrs;
		else return computeAttrs(this.attrs, attrs);
	}
	/**
	Create a `Node` of this type. The given attributes are
	checked and defaulted (you can pass `null` to use the type's
	defaults entirely, if no required attributes exist). `content`
	may be a `Fragment`, a node, an array of nodes, or
	`null`. Similarly `marks` may be `null` to default to the empty
	set of marks.
	*/
	create(attrs = null, content, marks) {
		if (this.isText) throw new Error("NodeType.create can't construct text nodes");
		return new Node$1(this, this.computeAttrs(attrs), Fragment$8.from(content), Mark$1.setFrom(marks));
	}
	/**
	Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but check the given content
	against the node type's content restrictions, and throw an error
	if it doesn't match.
	*/
	createChecked(attrs = null, content, marks) {
		content = Fragment$8.from(content);
		this.checkContent(content);
		return new Node$1(this, this.computeAttrs(attrs), content, Mark$1.setFrom(marks));
	}
	/**
	Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but see if it is
	necessary to add nodes to the start or end of the given fragment
	to make it fit the node. If no fitting wrapping can be found,
	return null. Note that, due to the fact that required nodes can
	always be created, this will always succeed if you pass null or
	`Fragment.empty` as content.
	*/
	createAndFill(attrs = null, content, marks) {
		attrs = this.computeAttrs(attrs);
		content = Fragment$8.from(content);
		if (content.size) {
			let before = this.contentMatch.fillBefore(content);
			if (!before) return null;
			content = before.append(content);
		}
		let matched = this.contentMatch.matchFragment(content);
		let after = matched && matched.fillBefore(Fragment$8.empty, true);
		if (!after) return null;
		return new Node$1(this, attrs, content.append(after), Mark$1.setFrom(marks));
	}
	/**
	Returns true if the given fragment is valid content for this node
	type.
	*/
	validContent(content) {
		let result = this.contentMatch.matchFragment(content);
		if (!result || !result.validEnd) return false;
		for (let i = 0; i < content.childCount; i++) if (!this.allowsMarks(content.child(i).marks)) return false;
		return true;
	}
	/**
	Throws a RangeError if the given fragment is not valid content for this
	node type.
	@internal
	*/
	checkContent(content) {
		if (!this.validContent(content)) throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
	}
	/**
	@internal
	*/
	checkAttrs(attrs) {
		checkAttrs(this.attrs, attrs, "node", this.name);
	}
	/**
	Check whether the given mark type is allowed in this node.
	*/
	allowsMarkType(markType) {
		return this.markSet == null || this.markSet.indexOf(markType) > -1;
	}
	/**
	Test whether the given set of marks are allowed in this node.
	*/
	allowsMarks(marks) {
		if (this.markSet == null) return true;
		for (let i = 0; i < marks.length; i++) if (!this.allowsMarkType(marks[i].type)) return false;
		return true;
	}
	/**
	Removes the marks that are not allowed in this node from the given set.
	*/
	allowedMarks(marks) {
		if (this.markSet == null) return marks;
		let copy;
		for (let i = 0; i < marks.length; i++) if (!this.allowsMarkType(marks[i].type)) {
			if (!copy) copy = marks.slice(0, i);
		} else if (copy) copy.push(marks[i]);
		return !copy ? marks : copy.length ? copy : Mark$1.none;
	}
	/**
	@internal
	*/
	static compile(nodes, schema) {
		let result = Object.create(null);
		nodes.forEach((name, spec) => result[name] = new NodeType$1(name, schema, spec));
		let topType = schema.spec.topNode || "doc";
		if (!result[topType]) throw new RangeError("Schema is missing its top node type ('" + topType + "')");
		if (!result.text) throw new RangeError("Every schema needs a 'text' type");
		for (let _ in result.text.attrs) throw new RangeError("The text node type should not have attributes");
		return result;
	}
};
function validateType(typeName, attrName, type) {
	let types = type.split("|");
	return (value) => {
		let name = value === null ? "null" : typeof value;
		if (types.indexOf(name) < 0) throw new RangeError(`Expected value of type ${types} for attribute ${attrName} on type ${typeName}, got ${name}`);
	};
}
var Attribute = class {
	constructor(typeName, attrName, options) {
		this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default");
		this.default = options.default;
		this.validate = typeof options.validate == "string" ? validateType(typeName, attrName, options.validate) : options.validate;
	}
	get isRequired() {
		return !this.hasDefault;
	}
};
/**
Like nodes, marks (which are associated with nodes to signify
things like emphasis or being part of a link) are
[tagged](https://prosemirror.net/docs/ref/#model.Mark.type) with type objects, which are
instantiated once per `Schema`.
*/
var MarkType = class MarkType {
	/**
	@internal
	*/
	constructor(name, rank, schema, spec) {
		this.name = name;
		this.rank = rank;
		this.schema = schema;
		this.spec = spec;
		this.attrs = initAttrs(name, spec.attrs);
		this.excluded = null;
		let defaults = defaultAttrs(this.attrs);
		this.instance = defaults ? new Mark$1(this, defaults) : null;
	}
	/**
	Create a mark of this type. `attrs` may be `null` or an object
	containing only some of the mark's attributes. The others, if
	they have defaults, will be added.
	*/
	create(attrs = null) {
		if (!attrs && this.instance) return this.instance;
		return new Mark$1(this, computeAttrs(this.attrs, attrs));
	}
	/**
	@internal
	*/
	static compile(marks, schema) {
		let result = Object.create(null), rank = 0;
		marks.forEach((name, spec) => result[name] = new MarkType(name, rank++, schema, spec));
		return result;
	}
	/**
	When there is a mark of this type in the given set, a new set
	without it is returned. Otherwise, the input set is returned.
	*/
	removeFromSet(set) {
		for (var i = 0; i < set.length; i++) if (set[i].type == this) {
			set = set.slice(0, i).concat(set.slice(i + 1));
			i--;
		}
		return set;
	}
	/**
	Tests whether there is a mark of this type in the given set.
	*/
	isInSet(set) {
		for (let i = 0; i < set.length; i++) if (set[i].type == this) return set[i];
	}
	/**
	@internal
	*/
	checkAttrs(attrs) {
		checkAttrs(this.attrs, attrs, "mark", this.name);
	}
	/**
	Queries whether a given mark type is
	[excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
	*/
	excludes(other) {
		return this.excluded.indexOf(other) > -1;
	}
};
/**
A document schema. Holds [node](https://prosemirror.net/docs/ref/#model.NodeType) and [mark
type](https://prosemirror.net/docs/ref/#model.MarkType) objects for the nodes and marks that may
occur in conforming documents, and provides functionality for
creating and deserializing such documents.

When given, the type parameters provide the names of the nodes and
marks in this schema.
*/
var Schema = class {
	/**
	Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec).
	*/
	constructor(spec) {
		/**
		The [linebreak
		replacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement) node defined
		in this schema, if any.
		*/
		this.linebreakReplacement = null;
		/**
		An object for storing whatever values modules may want to
		compute and cache per schema. (If you want to store something
		in it, try to use property names unlikely to clash.)
		*/
		this.cached = Object.create(null);
		let instanceSpec = this.spec = {};
		for (let prop in spec) instanceSpec[prop] = spec[prop];
		instanceSpec.nodes = OrderedMap.from(spec.nodes), instanceSpec.marks = OrderedMap.from(spec.marks || {}), this.nodes = NodeType$1.compile(this.spec.nodes, this);
		this.marks = MarkType.compile(this.spec.marks, this);
		let contentExprCache = Object.create(null);
		for (let prop in this.nodes) {
			if (prop in this.marks) throw new RangeError(prop + " can not be both a node and a mark");
			let type = this.nodes[prop], contentExpr = type.spec.content || "", markExpr = type.spec.marks;
			type.contentMatch = contentExprCache[contentExpr] || (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes));
			type.inlineContent = type.contentMatch.inlineContent;
			if (type.spec.linebreakReplacement) {
				if (this.linebreakReplacement) throw new RangeError("Multiple linebreak nodes defined");
				if (!type.isInline || !type.isLeaf) throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");
				this.linebreakReplacement = type;
			}
			type.markSet = markExpr == "_" ? null : markExpr ? gatherMarks(this, markExpr.split(" ")) : markExpr == "" || !type.inlineContent ? [] : null;
		}
		for (let prop in this.marks) {
			let type = this.marks[prop], excl = type.spec.excludes;
			type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" "));
		}
		this.nodeFromJSON = (json) => Node$1.fromJSON(this, json);
		this.markFromJSON = (json) => Mark$1.fromJSON(this, json);
		this.topNodeType = this.nodes[this.spec.topNode || "doc"];
		this.cached.wrappings = Object.create(null);
	}
	/**
	Create a node in this schema. The `type` may be a string or a
	`NodeType` instance. Attributes will be extended with defaults,
	`content` may be a `Fragment`, `null`, a `Node`, or an array of
	nodes.
	*/
	node(type, attrs = null, content, marks) {
		if (typeof type == "string") type = this.nodeType(type);
		else if (!(type instanceof NodeType$1)) throw new RangeError("Invalid node type: " + type);
		else if (type.schema != this) throw new RangeError("Node type from different schema used (" + type.name + ")");
		return type.createChecked(attrs, content, marks);
	}
	/**
	Create a text node in the schema. Empty text nodes are not
	allowed.
	*/
	text(text, marks) {
		let type = this.nodes.text;
		return new TextNode(type, type.defaultAttrs, text, Mark$1.setFrom(marks));
	}
	/**
	Create a mark with the given type and attributes.
	*/
	mark(type, attrs) {
		if (typeof type == "string") type = this.marks[type];
		return type.create(attrs);
	}
	/**
	@internal
	*/
	nodeType(name) {
		let found = this.nodes[name];
		if (!found) throw new RangeError("Unknown node type: " + name);
		return found;
	}
};
function gatherMarks(schema, marks) {
	let found = [];
	for (let i = 0; i < marks.length; i++) {
		let name = marks[i], mark = schema.marks[name], ok = mark;
		if (mark) found.push(mark);
		else for (let prop in schema.marks) {
			let mark = schema.marks[prop];
			if (name == "_" || mark.spec.group && mark.spec.group.split(" ").indexOf(name) > -1) found.push(ok = mark);
		}
		if (!ok) throw new SyntaxError("Unknown mark type: '" + marks[i] + "'");
	}
	return found;
}
function isTagRule(rule) {
	return rule.tag != null;
}
function isStyleRule(rule) {
	return rule.style != null;
}
/**
A DOM parser represents a strategy for parsing DOM content into a
ProseMirror document conforming to a given schema. Its behavior is
defined by an array of [rules](https://prosemirror.net/docs/ref/#model.ParseRule).
*/
var DOMParser$1 = class DOMParser$1 {
	/**
	Create a parser that targets the given schema, using the given
	parsing rules.
	*/
	constructor(schema, rules) {
		this.schema = schema;
		this.rules = rules;
		/**
		@internal
		*/
		this.tags = [];
		/**
		@internal
		*/
		this.styles = [];
		let matchedStyles = this.matchedStyles = [];
		rules.forEach((rule) => {
			if (isTagRule(rule)) this.tags.push(rule);
			else if (isStyleRule(rule)) {
				let prop = /[^=]*/.exec(rule.style)[0];
				if (matchedStyles.indexOf(prop) < 0) matchedStyles.push(prop);
				this.styles.push(rule);
			}
		});
		this.normalizeLists = !this.tags.some((r) => {
			if (!/^(ul|ol)\b/.test(r.tag) || !r.node) return false;
			let node = schema.nodes[r.node];
			return node.contentMatch.matchType(node);
		});
	}
	/**
	Parse a document from the content of a DOM node.
	*/
	parse(dom, options = {}) {
		let context = new ParseContext(this, options, false);
		context.addAll(dom, Mark$1.none, options.from, options.to);
		return context.finish();
	}
	/**
	Parses the content of the given DOM node, like
	[`parse`](https://prosemirror.net/docs/ref/#model.DOMParser.parse), and takes the same set of
	options. But unlike that method, which produces a whole node,
	this one returns a slice that is open at the sides, meaning that
	the schema constraints aren't applied to the start of nodes to
	the left of the input and the end of nodes at the end.
	*/
	parseSlice(dom, options = {}) {
		let context = new ParseContext(this, options, true);
		context.addAll(dom, Mark$1.none, options.from, options.to);
		return Slice.maxOpen(context.finish());
	}
	/**
	@internal
	*/
	matchTag(dom, context, after) {
		for (let i = after ? this.tags.indexOf(after) + 1 : 0; i < this.tags.length; i++) {
			let rule = this.tags[i];
			if (matches(dom, rule.tag) && (rule.namespace === void 0 || dom.namespaceURI == rule.namespace) && (!rule.context || context.matchesContext(rule.context))) {
				if (rule.getAttrs) {
					let result = rule.getAttrs(dom);
					if (result === false) continue;
					rule.attrs = result || void 0;
				}
				return rule;
			}
		}
	}
	/**
	@internal
	*/
	matchStyle(prop, value, context, after) {
		for (let i = after ? this.styles.indexOf(after) + 1 : 0; i < this.styles.length; i++) {
			let rule = this.styles[i], style = rule.style;
			if (style.indexOf(prop) != 0 || rule.context && !context.matchesContext(rule.context) || style.length > prop.length && (style.charCodeAt(prop.length) != 61 || style.slice(prop.length + 1) != value)) continue;
			if (rule.getAttrs) {
				let result = rule.getAttrs(value);
				if (result === false) continue;
				rule.attrs = result || void 0;
			}
			return rule;
		}
	}
	/**
	@internal
	*/
	static schemaRules(schema) {
		let result = [];
		function insert(rule) {
			let priority = rule.priority == null ? 50 : rule.priority, i = 0;
			for (; i < result.length; i++) {
				let next = result[i];
				if ((next.priority == null ? 50 : next.priority) < priority) break;
			}
			result.splice(i, 0, rule);
		}
		for (let name in schema.marks) {
			let rules = schema.marks[name].spec.parseDOM;
			if (rules) rules.forEach((rule) => {
				insert(rule = copy(rule));
				if (!(rule.mark || rule.ignore || rule.clearMark)) rule.mark = name;
			});
		}
		for (let name in schema.nodes) {
			let rules = schema.nodes[name].spec.parseDOM;
			if (rules) rules.forEach((rule) => {
				insert(rule = copy(rule));
				if (!(rule.node || rule.ignore || rule.mark)) rule.node = name;
			});
		}
		return result;
	}
	/**
	Construct a DOM parser using the parsing rules listed in a
	schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by
	[priority](https://prosemirror.net/docs/ref/#model.GenericParseRule.priority).
	*/
	static fromSchema(schema) {
		return schema.cached.domParser || (schema.cached.domParser = new DOMParser$1(schema, DOMParser$1.schemaRules(schema)));
	}
};
var blockTags = {
	address: true,
	article: true,
	aside: true,
	blockquote: true,
	body: true,
	canvas: true,
	dd: true,
	div: true,
	dl: true,
	fieldset: true,
	figcaption: true,
	figure: true,
	footer: true,
	form: true,
	h1: true,
	h2: true,
	h3: true,
	h4: true,
	h5: true,
	h6: true,
	header: true,
	hgroup: true,
	hr: true,
	li: true,
	noscript: true,
	ol: true,
	output: true,
	p: true,
	pre: true,
	section: true,
	table: true,
	tfoot: true,
	ul: true
};
var ignoreTags = {
	head: true,
	noscript: true,
	object: true,
	script: true,
	style: true,
	title: true
};
var listTags = {
	ol: true,
	ul: true
};
var OPT_PRESERVE_WS = 1;
var OPT_PRESERVE_WS_FULL = 2;
var OPT_OPEN_LEFT = 4;
function wsOptionsFor(type, preserveWhitespace, base) {
	if (preserveWhitespace != null) return (preserveWhitespace ? OPT_PRESERVE_WS : 0) | (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0);
	return type && type.whitespace == "pre" ? 3 : base & -5;
}
var NodeContext = class {
	constructor(type, attrs, marks, solid, match, options) {
		this.type = type;
		this.attrs = attrs;
		this.marks = marks;
		this.solid = solid;
		this.options = options;
		this.content = [];
		this.activeMarks = Mark$1.none;
		this.match = match || (options & OPT_OPEN_LEFT ? null : type.contentMatch);
	}
	findWrapping(node) {
		if (!this.match) {
			if (!this.type) return [];
			let fill = this.type.contentMatch.fillBefore(Fragment$8.from(node));
			if (fill) this.match = this.type.contentMatch.matchFragment(fill);
			else {
				let start = this.type.contentMatch, wrap;
				if (wrap = start.findWrapping(node.type)) {
					this.match = start;
					return wrap;
				} else return null;
			}
		}
		return this.match.findWrapping(node.type);
	}
	finish(openEnd) {
		if (!(this.options & OPT_PRESERVE_WS)) {
			let last = this.content[this.content.length - 1], m;
			if (last && last.isText && (m = /[ \t\r\n\u000c]+$/.exec(last.text))) {
				let text = last;
				if (last.text.length == m[0].length) this.content.pop();
				else this.content[this.content.length - 1] = text.withText(text.text.slice(0, text.text.length - m[0].length));
			}
		}
		let content = Fragment$8.from(this.content);
		if (!openEnd && this.match) content = content.append(this.match.fillBefore(Fragment$8.empty, true));
		return this.type ? this.type.create(this.attrs, content, this.marks) : content;
	}
	inlineContext(node) {
		if (this.type) return this.type.inlineContent;
		if (this.content.length) return this.content[0].isInline;
		return node.parentNode && !blockTags.hasOwnProperty(node.parentNode.nodeName.toLowerCase());
	}
};
var ParseContext = class {
	constructor(parser, options, isOpen) {
		this.parser = parser;
		this.options = options;
		this.isOpen = isOpen;
		this.open = 0;
		this.localPreserveWS = false;
		let topNode = options.topNode, topContext;
		let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
		if (topNode) topContext = new NodeContext(topNode.type, topNode.attrs, Mark$1.none, true, options.topMatch || topNode.type.contentMatch, topOptions);
		else if (isOpen) topContext = new NodeContext(null, null, Mark$1.none, true, null, topOptions);
		else topContext = new NodeContext(parser.schema.topNodeType, null, Mark$1.none, true, null, topOptions);
		this.nodes = [topContext];
		this.find = options.findPositions;
		this.needsBlock = false;
	}
	get top() {
		return this.nodes[this.open];
	}
	addDOM(dom, marks) {
		if (dom.nodeType == 3) this.addTextNode(dom, marks);
		else if (dom.nodeType == 1) this.addElement(dom, marks);
	}
	addTextNode(dom, marks) {
		let value = dom.nodeValue;
		let top = this.top, preserveWS = top.options & OPT_PRESERVE_WS_FULL ? "full" : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0;
		let { schema } = this.parser;
		if (preserveWS === "full" || top.inlineContext(dom) || /[^ \t\r\n\u000c]/.test(value)) {
			if (!preserveWS) {
				value = value.replace(/[ \t\r\n\u000c]+/g, " ");
				if (/^[ \t\r\n\u000c]/.test(value) && this.open == this.nodes.length - 1) {
					let nodeBefore = top.content[top.content.length - 1];
					let domNodeBefore = dom.previousSibling;
					if (!nodeBefore || domNodeBefore && domNodeBefore.nodeName == "BR" || nodeBefore.isText && /[ \t\r\n\u000c]$/.test(nodeBefore.text)) value = value.slice(1);
				}
			} else if (preserveWS === "full") value = value.replace(/\r\n?/g, "\n");
			else if (schema.linebreakReplacement && /[\r\n]/.test(value) && this.top.findWrapping(schema.linebreakReplacement.create())) {
				let lines = value.split(/\r?\n|\r/);
				for (let i = 0; i < lines.length; i++) {
					if (i) this.insertNode(schema.linebreakReplacement.create(), marks, true);
					if (lines[i]) this.insertNode(schema.text(lines[i]), marks, !/\S/.test(lines[i]));
				}
				value = "";
			} else value = value.replace(/\r?\n|\r/g, " ");
			if (value) this.insertNode(schema.text(value), marks, !/\S/.test(value));
			this.findInText(dom);
		} else this.findInside(dom);
	}
	addElement(dom, marks, matchAfter) {
		let outerWS = this.localPreserveWS, top = this.top;
		if (dom.tagName == "PRE" || /pre/.test(dom.style && dom.style.whiteSpace)) this.localPreserveWS = true;
		let name = dom.nodeName.toLowerCase(), ruleID;
		if (listTags.hasOwnProperty(name) && this.parser.normalizeLists) normalizeList(dom);
		let rule = this.options.ruleFromNode && this.options.ruleFromNode(dom) || (ruleID = this.parser.matchTag(dom, this, matchAfter));
		out: if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
			this.findInside(dom);
			this.ignoreFallback(dom, marks);
		} else if (!rule || rule.skip || rule.closeParent) {
			if (rule && rule.closeParent) this.open = Math.max(0, this.open - 1);
			else if (rule && rule.skip.nodeType) dom = rule.skip;
			let sync, oldNeedsBlock = this.needsBlock;
			if (blockTags.hasOwnProperty(name)) {
				if (top.content.length && top.content[0].isInline && this.open) {
					this.open--;
					top = this.top;
				}
				sync = true;
				if (!top.type) this.needsBlock = true;
			} else if (!dom.firstChild) {
				this.leafFallback(dom, marks);
				break out;
			}
			let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
			if (innerMarks) this.addAll(dom, innerMarks);
			if (sync) this.sync(top);
			this.needsBlock = oldNeedsBlock;
		} else {
			let innerMarks = this.readStyles(dom, marks);
			if (innerMarks) this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : void 0);
		}
		this.localPreserveWS = outerWS;
	}
	leafFallback(dom, marks) {
		if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent) this.addTextNode(dom.ownerDocument.createTextNode("\n"), marks);
	}
	ignoreFallback(dom, marks) {
		if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent)) this.findPlace(this.parser.schema.text("-"), marks, true);
	}
	readStyles(dom, marks) {
		let styles = dom.style;
		if (styles && styles.length) for (let i = 0; i < this.parser.matchedStyles.length; i++) {
			let name = this.parser.matchedStyles[i], value = styles.getPropertyValue(name);
			if (value) for (let after = void 0;;) {
				let rule = this.parser.matchStyle(name, value, this, after);
				if (!rule) break;
				if (rule.ignore) return null;
				if (rule.clearMark) marks = marks.filter((m) => !rule.clearMark(m));
				else marks = marks.concat(this.parser.schema.marks[rule.mark].create(rule.attrs));
				if (rule.consuming === false) after = rule;
				else break;
			}
		}
		return marks;
	}
	addElementByRule(dom, rule, marks, continueAfter) {
		let sync, nodeType;
		if (rule.node) {
			nodeType = this.parser.schema.nodes[rule.node];
			if (!nodeType.isLeaf) {
				let inner = this.enter(nodeType, rule.attrs || null, marks, rule.preserveWhitespace);
				if (inner) {
					sync = true;
					marks = inner;
				}
			} else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) this.leafFallback(dom, marks);
		} else {
			let markType = this.parser.schema.marks[rule.mark];
			marks = marks.concat(markType.create(rule.attrs));
		}
		let startIn = this.top;
		if (nodeType && nodeType.isLeaf) this.findInside(dom);
		else if (continueAfter) this.addElement(dom, marks, continueAfter);
		else if (rule.getContent) {
			this.findInside(dom);
			rule.getContent(dom, this.parser.schema).forEach((node) => this.insertNode(node, marks, false));
		} else {
			let contentDOM = dom;
			if (typeof rule.contentElement == "string") contentDOM = dom.querySelector(rule.contentElement);
			else if (typeof rule.contentElement == "function") contentDOM = rule.contentElement(dom);
			else if (rule.contentElement) contentDOM = rule.contentElement;
			this.findAround(dom, contentDOM, true);
			this.addAll(contentDOM, marks);
			this.findAround(dom, contentDOM, false);
		}
		if (sync && this.sync(startIn)) this.open--;
	}
	addAll(parent, marks, startIndex, endIndex) {
		let index = startIndex || 0;
		for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index) {
			this.findAtPoint(parent, index);
			this.addDOM(dom, marks);
		}
		this.findAtPoint(parent, index);
	}
	findPlace(node, marks, cautious) {
		let route, sync;
		for (let depth = this.open, penalty = 0; depth >= 0; depth--) {
			let cx = this.nodes[depth];
			let found = cx.findWrapping(node);
			if (found && (!route || route.length > found.length + penalty)) {
				route = found;
				sync = cx;
				if (!found.length) break;
			}
			if (cx.solid) {
				if (cautious) break;
				penalty += 2;
			}
		}
		if (!route) return null;
		this.sync(sync);
		for (let i = 0; i < route.length; i++) marks = this.enterInner(route[i], null, marks, false);
		return marks;
	}
	insertNode(node, marks, cautious) {
		if (node.isInline && this.needsBlock && !this.top.type) {
			let block = this.textblockFromContext();
			if (block) marks = this.enterInner(block, null, marks);
		}
		let innerMarks = this.findPlace(node, marks, cautious);
		if (innerMarks) {
			this.closeExtra();
			let top = this.top;
			if (top.match) top.match = top.match.matchType(node.type);
			let nodeMarks = Mark$1.none;
			for (let m of innerMarks.concat(node.marks)) if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, node.type)) nodeMarks = m.addToSet(nodeMarks);
			top.content.push(node.mark(nodeMarks));
			return true;
		}
		return false;
	}
	enter(type, attrs, marks, preserveWS) {
		let innerMarks = this.findPlace(type.create(attrs), marks, false);
		if (innerMarks) innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
		return innerMarks;
	}
	enterInner(type, attrs, marks, solid = false, preserveWS) {
		this.closeExtra();
		let top = this.top;
		top.match = top.match && top.match.matchType(type);
		let options = wsOptionsFor(type, preserveWS, top.options);
		if (top.options & OPT_OPEN_LEFT && top.content.length == 0) options |= OPT_OPEN_LEFT;
		let applyMarks = Mark$1.none;
		marks = marks.filter((m) => {
			if (top.type ? top.type.allowsMarkType(m.type) : markMayApply(m.type, type)) {
				applyMarks = m.addToSet(applyMarks);
				return false;
			}
			return true;
		});
		this.nodes.push(new NodeContext(type, attrs, applyMarks, solid, null, options));
		this.open++;
		return marks;
	}
	closeExtra(openEnd = false) {
		let i = this.nodes.length - 1;
		if (i > this.open) {
			for (; i > this.open; i--) this.nodes[i - 1].content.push(this.nodes[i].finish(openEnd));
			this.nodes.length = this.open + 1;
		}
	}
	finish() {
		this.open = 0;
		this.closeExtra(this.isOpen);
		return this.nodes[0].finish(!!(this.isOpen || this.options.topOpen));
	}
	sync(to) {
		for (let i = this.open; i >= 0; i--) if (this.nodes[i] == to) {
			this.open = i;
			return true;
		} else if (this.localPreserveWS) this.nodes[i].options |= OPT_PRESERVE_WS;
		return false;
	}
	get currentPos() {
		this.closeExtra();
		let pos = 0;
		for (let i = this.open; i >= 0; i--) {
			let content = this.nodes[i].content;
			for (let j = content.length - 1; j >= 0; j--) pos += content[j].nodeSize;
			if (i) pos++;
		}
		return pos;
	}
	findAtPoint(parent, offset) {
		if (this.find) {
			for (let i = 0; i < this.find.length; i++) if (this.find[i].node == parent && this.find[i].offset == offset) this.find[i].pos = this.currentPos;
		}
	}
	findInside(parent) {
		if (this.find) {
			for (let i = 0; i < this.find.length; i++) if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node)) this.find[i].pos = this.currentPos;
		}
	}
	findAround(parent, content, before) {
		if (parent != content && this.find) {
			for (let i = 0; i < this.find.length; i++) if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node)) {
				if (content.compareDocumentPosition(this.find[i].node) & (before ? 2 : 4)) this.find[i].pos = this.currentPos;
			}
		}
	}
	findInText(textNode) {
		if (this.find) {
			for (let i = 0; i < this.find.length; i++) if (this.find[i].node == textNode) this.find[i].pos = this.currentPos - (textNode.nodeValue.length - this.find[i].offset);
		}
	}
	matchesContext(context) {
		if (context.indexOf("|") > -1) return context.split(/\s*\|\s*/).some(this.matchesContext, this);
		let parts = context.split("/");
		let option = this.options.context;
		let useRoot = !this.isOpen && (!option || option.parent.type == this.nodes[0].type);
		let minDepth = -(option ? option.depth + 1 : 0) + (useRoot ? 0 : 1);
		let match = (i, depth) => {
			for (; i >= 0; i--) {
				let part = parts[i];
				if (part == "") {
					if (i == parts.length - 1 || i == 0) continue;
					for (; depth >= minDepth; depth--) if (match(i - 1, depth)) return true;
					return false;
				} else {
					let next = depth > 0 || depth == 0 && useRoot ? this.nodes[depth].type : option && depth >= minDepth ? option.node(depth - minDepth).type : null;
					if (!next || next.name != part && !next.isInGroup(part)) return false;
					depth--;
				}
			}
			return true;
		};
		return match(parts.length - 1, this.open);
	}
	textblockFromContext() {
		let $context = this.options.context;
		if ($context) for (let d = $context.depth; d >= 0; d--) {
			let deflt = $context.node(d).contentMatchAt($context.indexAfter(d)).defaultType;
			if (deflt && deflt.isTextblock && deflt.defaultAttrs) return deflt;
		}
		for (let name in this.parser.schema.nodes) {
			let type = this.parser.schema.nodes[name];
			if (type.isTextblock && type.defaultAttrs) return type;
		}
	}
};
function normalizeList(dom) {
	for (let child = dom.firstChild, prevItem = null; child; child = child.nextSibling) {
		let name = child.nodeType == 1 ? child.nodeName.toLowerCase() : null;
		if (name && listTags.hasOwnProperty(name) && prevItem) {
			prevItem.appendChild(child);
			child = prevItem;
		} else if (name == "li") prevItem = child;
		else if (name) prevItem = null;
	}
}
function matches(dom, selector) {
	return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector);
}
function copy(obj) {
	let copy = {};
	for (let prop in obj) copy[prop] = obj[prop];
	return copy;
}
function markMayApply(markType, nodeType) {
	let nodes = nodeType.schema.nodes;
	for (let name in nodes) {
		let parent = nodes[name];
		if (!parent.allowsMarkType(markType)) continue;
		let seen = [], scan = (match) => {
			seen.push(match);
			for (let i = 0; i < match.edgeCount; i++) {
				let { type, next } = match.edge(i);
				if (type == nodeType) return true;
				if (seen.indexOf(next) < 0 && scan(next)) return true;
			}
		};
		if (scan(parent.contentMatch)) return true;
	}
}
/**
A DOM serializer knows how to convert ProseMirror nodes and
marks of various types to DOM nodes.
*/
var DOMSerializer = class DOMSerializer {
	/**
	Create a serializer. `nodes` should map node names to functions
	that take a node and return a description of the corresponding
	DOM. `marks` does the same for mark names, but also gets an
	argument that tells it whether the mark's content is block or
	inline content (for typical use, it'll always be inline). A mark
	serializer may be `null` to indicate that marks of that type
	should not be serialized.
	*/
	constructor(nodes, marks) {
		this.nodes = nodes;
		this.marks = marks;
	}
	/**
	Serialize the content of this fragment to a DOM fragment. When
	not in the browser, the `document` option, containing a DOM
	document, should be passed so that the serializer can create
	nodes.
	*/
	serializeFragment(fragment, options = {}, target) {
		if (!target) target = doc$1(options).createDocumentFragment();
		let top = target, active = [];
		fragment.forEach((node) => {
			if (active.length || node.marks.length) {
				let keep = 0, rendered = 0;
				while (keep < active.length && rendered < node.marks.length) {
					let next = node.marks[rendered];
					if (!this.marks[next.type.name]) {
						rendered++;
						continue;
					}
					if (!next.eq(active[keep][0]) || next.type.spec.spanning === false) break;
					keep++;
					rendered++;
				}
				while (keep < active.length) top = active.pop()[1];
				while (rendered < node.marks.length) {
					let add = node.marks[rendered++];
					let markDOM = this.serializeMark(add, node.isInline, options);
					if (markDOM) {
						active.push([add, top]);
						top.appendChild(markDOM.dom);
						top = markDOM.contentDOM || markDOM.dom;
					}
				}
			}
			top.appendChild(this.serializeNodeInner(node, options));
		});
		return target;
	}
	/**
	@internal
	*/
	serializeNodeInner(node, options) {
		if (node.isText) return doc$1(options).createTextNode(node.text);
		let { dom, contentDOM } = renderSpec(doc$1(options), this.nodes[node.type.name](node), null, node.attrs);
		if (contentDOM) {
			if (node.isLeaf) throw new RangeError("Content hole not allowed in a leaf node spec");
			this.serializeFragment(node.content, options, contentDOM);
		}
		return dom;
	}
	/**
	Serialize this node to a DOM node. This can be useful when you
	need to serialize a part of a document, as opposed to the whole
	document. To serialize a whole document, use
	[`serializeFragment`](https://prosemirror.net/docs/ref/#model.DOMSerializer.serializeFragment) on
	its [content](https://prosemirror.net/docs/ref/#model.Node.content).
	*/
	serializeNode(node, options = {}) {
		let dom = this.serializeNodeInner(node, options);
		for (let i = node.marks.length - 1; i >= 0; i--) {
			let wrap = this.serializeMark(node.marks[i], node.isInline, options);
			if (wrap) {
				(wrap.contentDOM || wrap.dom).appendChild(dom);
				dom = wrap.dom;
			}
		}
		return dom;
	}
	/**
	@internal
	*/
	serializeMark(mark, inline, options = {}) {
		let toDOM = this.marks[mark.type.name];
		return toDOM && renderSpec(doc$1(options), toDOM(mark, inline), null, mark.attrs);
	}
	static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
		if (typeof structure == "string") return { dom: doc.createTextNode(structure) };
		return renderSpec(doc, structure, xmlNS, blockArraysIn);
	}
	/**
	Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM)
	properties in a schema's node and mark specs.
	*/
	static fromSchema(schema) {
		return schema.cached.domSerializer || (schema.cached.domSerializer = new DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema)));
	}
	/**
	Gather the serializers in a schema's node specs into an object.
	This can be useful as a base to build a custom serializer from.
	*/
	static nodesFromSchema(schema) {
		let result = gatherToDOM(schema.nodes);
		if (!result.text) result.text = (node) => node.text;
		return result;
	}
	/**
	Gather the serializers in a schema's mark specs into an object.
	*/
	static marksFromSchema(schema) {
		return gatherToDOM(schema.marks);
	}
};
function gatherToDOM(obj) {
	let result = {};
	for (let name in obj) {
		let toDOM = obj[name].spec.toDOM;
		if (toDOM) result[name] = toDOM;
	}
	return result;
}
function doc$1(options) {
	return options.document || window.document;
}
var suspiciousAttributeCache = /* @__PURE__ */ new WeakMap();
function suspiciousAttributes(attrs) {
	let value = suspiciousAttributeCache.get(attrs);
	if (value === void 0) suspiciousAttributeCache.set(attrs, value = suspiciousAttributesInner(attrs));
	return value;
}
function suspiciousAttributesInner(attrs) {
	let result = null;
	function scan(value) {
		if (value && typeof value == "object") {
			if (Array.isArray(value)) {
				if (typeof value[0] == "string") {
					if (!result) result = [];
					result.push(value);
				} else for (let i = 0; i < value.length; i++) scan(value[i]);
			} else for (let prop in value) scan(value[prop]);
		}
	}
	scan(attrs);
	return result;
}
function renderSpec(doc, structure, xmlNS, blockArraysIn) {
	if (structure.nodeType == 1) return { dom: structure };
	if (structure.dom && structure.dom.nodeType == 1) return structure;
	let tagName = structure[0], suspicious;
	if (typeof tagName != "string") throw new RangeError("Invalid array passed to renderSpec");
	if (blockArraysIn && (suspicious = suspiciousAttributes(blockArraysIn)) && suspicious.indexOf(structure) > -1) throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");
	let space = tagName.indexOf(" ");
	if (space > 0) {
		xmlNS = tagName.slice(0, space);
		tagName = tagName.slice(space + 1);
	}
	let contentDOM;
	let dom = xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName);
	let attrs = structure[1], start = 1;
	if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
		start = 2;
		for (let name in attrs) if (attrs[name] != null) {
			let space = name.indexOf(" ");
			if (space > 0) dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
			else if (name == "style" && dom.style) dom.style.cssText = attrs[name];
			else dom.setAttribute(name, attrs[name]);
		}
	}
	for (let i = start; i < structure.length; i++) {
		let child = structure[i];
		if (child === 0) {
			if (i < structure.length - 1 || i > start) throw new RangeError("Content hole must be the only child of its parent node");
			return {
				dom,
				contentDOM: dom
			};
		} else if (typeof child == "string") dom.appendChild(doc.createTextNode(child));
		else {
			let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
			dom.appendChild(inner);
			if (innerContent) {
				if (contentDOM) throw new RangeError("Multiple content holes");
				contentDOM = innerContent;
			}
		}
	}
	return {
		dom,
		contentDOM
	};
}
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-transform@1.12.0/node_modules/prosemirror-transform/dist/index.js
var lower16 = 65535;
var factor16 = Math.pow(2, 16);
function makeRecover(index, offset) {
	return index + offset * factor16;
}
function recoverIndex(value) {
	return value & lower16;
}
function recoverOffset(value) {
	return (value - (value & lower16)) / factor16;
}
var DEL_BEFORE = 1;
var DEL_AFTER = 2;
var DEL_ACROSS = 4;
var DEL_SIDE = 8;
/**
An object representing a mapped position with extra
information.
*/
var MapResult = class {
	/**
	@internal
	*/
	constructor(pos, delInfo, recover) {
		this.pos = pos;
		this.delInfo = delInfo;
		this.recover = recover;
	}
	/**
	Tells you whether the position was deleted, that is, whether the
	step removed the token on the side queried (via the `assoc`)
	argument from the document.
	*/
	get deleted() {
		return (this.delInfo & DEL_SIDE) > 0;
	}
	/**
	Tells you whether the token before the mapped position was deleted.
	*/
	get deletedBefore() {
		return (this.delInfo & 5) > 0;
	}
	/**
	True when the token after the mapped position was deleted.
	*/
	get deletedAfter() {
		return (this.delInfo & 6) > 0;
	}
	/**
	Tells whether any of the steps mapped through deletes across the
	position (including both the token before and after the
	position).
	*/
	get deletedAcross() {
		return (this.delInfo & DEL_ACROSS) > 0;
	}
};
/**
A map describing the deletions and insertions made by a step, which
can be used to find the correspondence between positions in the
pre-step version of a document and the same position in the
post-step version.
*/
var StepMap = class StepMap {
	/**
	Create a position map. The modifications to the document are
	represented as an array of numbers, in which each group of three
	represents a modified chunk as `[start, oldSize, newSize]`.
	*/
	constructor(ranges, inverted = false) {
		this.ranges = ranges;
		this.inverted = inverted;
		if (!ranges.length && StepMap.empty) return StepMap.empty;
	}
	/**
	@internal
	*/
	recover(value) {
		let diff = 0, index = recoverIndex(value);
		if (!this.inverted) for (let i = 0; i < index; i++) diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1];
		return this.ranges[index * 3] + diff + recoverOffset(value);
	}
	mapResult(pos, assoc = 1) {
		return this._map(pos, assoc, false);
	}
	map(pos, assoc = 1) {
		return this._map(pos, assoc, true);
	}
	/**
	@internal
	*/
	_map(pos, assoc, simple) {
		let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
		for (let i = 0; i < this.ranges.length; i += 3) {
			let start = this.ranges[i] - (this.inverted ? diff : 0);
			if (start > pos) break;
			let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize;
			if (pos <= end) {
				let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc;
				let result = start + diff + (side < 0 ? 0 : newSize);
				if (simple) return result;
				let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i / 3, pos - start);
				let del = pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS;
				if (assoc < 0 ? pos != start : pos != end) del |= DEL_SIDE;
				return new MapResult(result, del, recover);
			}
			diff += newSize - oldSize;
		}
		return simple ? pos + diff : new MapResult(pos + diff, 0, null);
	}
	/**
	@internal
	*/
	touches(pos, recover) {
		let diff = 0, index = recoverIndex(recover);
		let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
		for (let i = 0; i < this.ranges.length; i += 3) {
			let start = this.ranges[i] - (this.inverted ? diff : 0);
			if (start > pos) break;
			let oldSize = this.ranges[i + oldIndex];
			if (pos <= start + oldSize && i == index * 3) return true;
			diff += this.ranges[i + newIndex] - oldSize;
		}
		return false;
	}
	/**
	Calls the given function on each of the changed ranges included in
	this map.
	*/
	forEach(f) {
		let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2;
		for (let i = 0, diff = 0; i < this.ranges.length; i += 3) {
			let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff);
			let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex];
			f(oldStart, oldStart + oldSize, newStart, newStart + newSize);
			diff += newSize - oldSize;
		}
	}
	/**
	Create an inverted version of this map. The result can be used to
	map positions in the post-step document to the pre-step document.
	*/
	invert() {
		return new StepMap(this.ranges, !this.inverted);
	}
	/**
	@internal
	*/
	toString() {
		return (this.inverted ? "-" : "") + JSON.stringify(this.ranges);
	}
	/**
	Create a map that moves all positions by offset `n` (which may be
	negative). This can be useful when applying steps meant for a
	sub-document to a larger document, or vice-versa.
	*/
	static offset(n) {
		return n == 0 ? StepMap.empty : new StepMap(n < 0 ? [
			0,
			-n,
			0
		] : [
			0,
			0,
			n
		]);
	}
};
/**
A StepMap that contains no changed ranges.
*/
StepMap.empty = new StepMap([]);
/**
A mapping represents a pipeline of zero or more [step
maps](https://prosemirror.net/docs/ref/#transform.StepMap). It has special provisions for losslessly
handling mapping positions through a series of steps in which some
steps are inverted versions of earlier steps. (This comes up when
‘[rebasing](https://prosemirror.net/docs/guide/#transform.rebasing)’ steps for
collaboration or history management.)
*/
var Mapping = class Mapping {
	/**
	Create a new mapping with the given position maps.
	*/
	constructor(maps, mirror, from = 0, to = maps ? maps.length : 0) {
		this.mirror = mirror;
		this.from = from;
		this.to = to;
		this._maps = maps || [];
		this.ownData = !(maps || mirror);
	}
	/**
	The step maps in this mapping.
	*/
	get maps() {
		return this._maps;
	}
	/**
	Create a mapping that maps only through a part of this one.
	*/
	slice(from = 0, to = this.maps.length) {
		return new Mapping(this._maps, this.mirror, from, to);
	}
	/**
	Add a step map to the end of this mapping. If `mirrors` is
	given, it should be the index of the step map that is the mirror
	image of this one.
	*/
	appendMap(map, mirrors) {
		if (!this.ownData) {
			this._maps = this._maps.slice();
			this.mirror = this.mirror && this.mirror.slice();
			this.ownData = true;
		}
		this.to = this._maps.push(map);
		if (mirrors != null) this.setMirror(this._maps.length - 1, mirrors);
	}
	/**
	Add all the step maps in a given mapping to this one (preserving
	mirroring information).
	*/
	appendMapping(mapping) {
		for (let i = 0, startSize = this._maps.length; i < mapping._maps.length; i++) {
			let mirr = mapping.getMirror(i);
			this.appendMap(mapping._maps[i], mirr != null && mirr < i ? startSize + mirr : void 0);
		}
	}
	/**
	Finds the offset of the step map that mirrors the map at the
	given offset, in this mapping (as per the second argument to
	`appendMap`).
	*/
	getMirror(n) {
		if (this.mirror) {
			for (let i = 0; i < this.mirror.length; i++) if (this.mirror[i] == n) return this.mirror[i + (i % 2 ? -1 : 1)];
		}
	}
	/**
	@internal
	*/
	setMirror(n, m) {
		if (!this.mirror) this.mirror = [];
		this.mirror.push(n, m);
	}
	/**
	Append the inverse of the given mapping to this one.
	*/
	appendMappingInverted(mapping) {
		for (let i = mapping.maps.length - 1, totalSize = this._maps.length + mapping._maps.length; i >= 0; i--) {
			let mirr = mapping.getMirror(i);
			this.appendMap(mapping._maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : void 0);
		}
	}
	/**
	Create an inverted version of this mapping.
	*/
	invert() {
		let inverse = new Mapping();
		inverse.appendMappingInverted(this);
		return inverse;
	}
	/**
	Map a position through this mapping.
	*/
	map(pos, assoc = 1) {
		if (this.mirror) return this._map(pos, assoc, true);
		for (let i = this.from; i < this.to; i++) pos = this._maps[i].map(pos, assoc);
		return pos;
	}
	/**
	Map a position through this mapping, returning a mapping
	result.
	*/
	mapResult(pos, assoc = 1) {
		return this._map(pos, assoc, false);
	}
	/**
	@internal
	*/
	_map(pos, assoc, simple) {
		let delInfo = 0;
		for (let i = this.from; i < this.to; i++) {
			let result = this._maps[i].mapResult(pos, assoc);
			if (result.recover != null) {
				let corr = this.getMirror(i);
				if (corr != null && corr > i && corr < this.to) {
					i = corr;
					pos = this._maps[corr].recover(result.recover);
					continue;
				}
			}
			delInfo |= result.delInfo;
			pos = result.pos;
		}
		return simple ? pos : new MapResult(pos, delInfo, null);
	}
};
var stepsByID = Object.create(null);
/**
A step object represents an atomic change. It generally applies
only to the document it was created for, since the positions
stored in it will only make sense for that document.

New steps are defined by creating classes that extend `Step`,
overriding the `apply`, `invert`, `map`, `getMap` and `fromJSON`
methods, and registering your class with a unique
JSON-serialization identifier using
[`Step.jsonID`](https://prosemirror.net/docs/ref/#transform.Step^jsonID).
*/
var Step = class {
	/**
	Get the step map that represents the changes made by this step,
	and which can be used to transform between positions in the old
	and the new document.
	*/
	getMap() {
		return StepMap.empty;
	}
	/**
	Try to merge this step with another one, to be applied directly
	after it. Returns the merged step when possible, null if the
	steps can't be merged.
	*/
	merge(other) {
		return null;
	}
	/**
	Deserialize a step from its JSON representation. Will call
	through to the step class' own implementation of this method.
	*/
	static fromJSON(schema, json) {
		if (!json || !json.stepType) throw new RangeError("Invalid input for Step.fromJSON");
		let type = stepsByID[json.stepType];
		if (!type) throw new RangeError(`No step type ${json.stepType} defined`);
		return type.fromJSON(schema, json);
	}
	/**
	To be able to serialize steps to JSON, each step needs a string
	ID to attach to its JSON representation. Use this method to
	register an ID for your step classes. Try to pick something
	that's unlikely to clash with steps from other modules.
	*/
	static jsonID(id, stepClass) {
		if (id in stepsByID) throw new RangeError("Duplicate use of step JSON ID " + id);
		stepsByID[id] = stepClass;
		stepClass.prototype.jsonID = id;
		return stepClass;
	}
};
/**
The result of [applying](https://prosemirror.net/docs/ref/#transform.Step.apply) a step. Contains either a
new document or a failure value.
*/
var StepResult = class StepResult {
	/**
	@internal
	*/
	constructor(doc, failed) {
		this.doc = doc;
		this.failed = failed;
	}
	/**
	Create a successful step result.
	*/
	static ok(doc) {
		return new StepResult(doc, null);
	}
	/**
	Create a failed step result.
	*/
	static fail(message) {
		return new StepResult(null, message);
	}
	/**
	Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given
	arguments. Create a successful result if it succeeds, and a
	failed one if it throws a `ReplaceError`.
	*/
	static fromReplace(doc, from, to, slice) {
		try {
			return StepResult.ok(doc.replace(from, to, slice));
		} catch (e) {
			if (e instanceof ReplaceError) return StepResult.fail(e.message);
			throw e;
		}
	}
};
function mapFragment(fragment, f, parent) {
	let mapped = [];
	for (let i = 0; i < fragment.childCount; i++) {
		let child = fragment.child(i);
		if (child.content.size) child = child.copy(mapFragment(child.content, f, child));
		if (child.isInline) child = f(child, parent, i);
		mapped.push(child);
	}
	return Fragment$8.fromArray(mapped);
}
/**
Add a mark to all inline content between two positions.
*/
var AddMarkStep = class AddMarkStep extends Step {
	/**
	Create a mark step.
	*/
	constructor(from, to, mark) {
		super();
		this.from = from;
		this.to = to;
		this.mark = mark;
	}
	apply(doc) {
		let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from);
		let parent = $from.node($from.sharedDepth(this.to));
		let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {
			if (!node.isAtom || !parent.type.allowsMarkType(this.mark.type)) return node;
			return node.mark(this.mark.addToSet(node.marks));
		}, parent), oldSlice.openStart, oldSlice.openEnd);
		return StepResult.fromReplace(doc, this.from, this.to, slice);
	}
	invert() {
		return new RemoveMarkStep(this.from, this.to, this.mark);
	}
	map(mapping) {
		let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
		if (from.deleted && to.deleted || from.pos >= to.pos) return null;
		return new AddMarkStep(from.pos, to.pos, this.mark);
	}
	merge(other) {
		if (other instanceof AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) return new AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
		return null;
	}
	toJSON() {
		return {
			stepType: "addMark",
			mark: this.mark.toJSON(),
			from: this.from,
			to: this.to
		};
	}
	/**
	@internal
	*/
	static fromJSON(schema, json) {
		if (typeof json.from != "number" || typeof json.to != "number") throw new RangeError("Invalid input for AddMarkStep.fromJSON");
		return new AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
	}
};
Step.jsonID("addMark", AddMarkStep);
/**
Remove a mark from all inline content between two positions.
*/
var RemoveMarkStep = class RemoveMarkStep extends Step {
	/**
	Create a mark-removing step.
	*/
	constructor(from, to, mark) {
		super();
		this.from = from;
		this.to = to;
		this.mark = mark;
	}
	apply(doc) {
		let oldSlice = doc.slice(this.from, this.to);
		let slice = new Slice(mapFragment(oldSlice.content, (node) => {
			return node.mark(this.mark.removeFromSet(node.marks));
		}, doc), oldSlice.openStart, oldSlice.openEnd);
		return StepResult.fromReplace(doc, this.from, this.to, slice);
	}
	invert() {
		return new AddMarkStep(this.from, this.to, this.mark);
	}
	map(mapping) {
		let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
		if (from.deleted && to.deleted || from.pos >= to.pos) return null;
		return new RemoveMarkStep(from.pos, to.pos, this.mark);
	}
	merge(other) {
		if (other instanceof RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) return new RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark);
		return null;
	}
	toJSON() {
		return {
			stepType: "removeMark",
			mark: this.mark.toJSON(),
			from: this.from,
			to: this.to
		};
	}
	/**
	@internal
	*/
	static fromJSON(schema, json) {
		if (typeof json.from != "number" || typeof json.to != "number") throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");
		return new RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark));
	}
};
Step.jsonID("removeMark", RemoveMarkStep);
/**
Add a mark to a specific node.
*/
var AddNodeMarkStep = class AddNodeMarkStep extends Step {
	/**
	Create a node mark step.
	*/
	constructor(pos, mark) {
		super();
		this.pos = pos;
		this.mark = mark;
	}
	apply(doc) {
		let node = doc.nodeAt(this.pos);
		if (!node) return StepResult.fail("No node at mark step's position");
		let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
		return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment$8.from(updated), 0, node.isLeaf ? 0 : 1));
	}
	invert(doc) {
		let node = doc.nodeAt(this.pos);
		if (node) {
			let newSet = this.mark.addToSet(node.marks);
			if (newSet.length == node.marks.length) {
				for (let i = 0; i < node.marks.length; i++) if (!node.marks[i].isInSet(newSet)) return new AddNodeMarkStep(this.pos, node.marks[i]);
				return new AddNodeMarkStep(this.pos, this.mark);
			}
		}
		return new RemoveNodeMarkStep(this.pos, this.mark);
	}
	map(mapping) {
		let pos = mapping.mapResult(this.pos, 1);
		return pos.deletedAfter ? null : new AddNodeMarkStep(pos.pos, this.mark);
	}
	toJSON() {
		return {
			stepType: "addNodeMark",
			pos: this.pos,
			mark: this.mark.toJSON()
		};
	}
	/**
	@internal
	*/
	static fromJSON(schema, json) {
		if (typeof json.pos != "number") throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");
		return new AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
	}
};
Step.jsonID("addNodeMark", AddNodeMarkStep);
/**
Remove a mark from a specific node.
*/
var RemoveNodeMarkStep = class RemoveNodeMarkStep extends Step {
	/**
	Create a mark-removing step.
	*/
	constructor(pos, mark) {
		super();
		this.pos = pos;
		this.mark = mark;
	}
	apply(doc) {
		let node = doc.nodeAt(this.pos);
		if (!node) return StepResult.fail("No node at mark step's position");
		let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
		return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment$8.from(updated), 0, node.isLeaf ? 0 : 1));
	}
	invert(doc) {
		let node = doc.nodeAt(this.pos);
		if (!node || !this.mark.isInSet(node.marks)) return this;
		return new AddNodeMarkStep(this.pos, this.mark);
	}
	map(mapping) {
		let pos = mapping.mapResult(this.pos, 1);
		return pos.deletedAfter ? null : new RemoveNodeMarkStep(pos.pos, this.mark);
	}
	toJSON() {
		return {
			stepType: "removeNodeMark",
			pos: this.pos,
			mark: this.mark.toJSON()
		};
	}
	/**
	@internal
	*/
	static fromJSON(schema, json) {
		if (typeof json.pos != "number") throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");
		return new RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark));
	}
};
Step.jsonID("removeNodeMark", RemoveNodeMarkStep);
/**
Replace a part of the document with a slice of new content.
*/
var ReplaceStep = class ReplaceStep extends Step {
	/**
	The given `slice` should fit the 'gap' between `from` and
	`to`—the depths must line up, and the surrounding nodes must be
	able to be joined with the open sides of the slice. When
	`structure` is true, the step will fail if the content between
	from and to is not just a sequence of closing and then opening
	tokens (this is to guard against rebased replace steps
	overwriting something they weren't supposed to).
	*/
	constructor(from, to, slice, structure = false) {
		super();
		this.from = from;
		this.to = to;
		this.slice = slice;
		this.structure = structure;
	}
	apply(doc) {
		if (this.structure && contentBetween(doc, this.from, this.to)) return StepResult.fail("Structure replace would overwrite content");
		return StepResult.fromReplace(doc, this.from, this.to, this.slice);
	}
	getMap() {
		return new StepMap([
			this.from,
			this.to - this.from,
			this.slice.size
		]);
	}
	invert(doc) {
		return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
	}
	map(mapping) {
		let to = mapping.mapResult(this.to, -1);
		let from = this.from == this.to && ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1);
		if (from.deletedAcross && to.deletedAcross) return null;
		return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
	}
	merge(other) {
		if (!(other instanceof ReplaceStep) || other.structure || this.structure) return null;
		if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) {
			let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd);
			return new ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure);
		} else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) {
			let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd);
			return new ReplaceStep(other.from, this.to, slice, this.structure);
		} else return null;
	}
	toJSON() {
		let json = {
			stepType: "replace",
			from: this.from,
			to: this.to
		};
		if (this.slice.size) json.slice = this.slice.toJSON();
		if (this.structure) json.structure = true;
		return json;
	}
	/**
	@internal
	*/
	static fromJSON(schema, json) {
		if (typeof json.from != "number" || typeof json.to != "number") throw new RangeError("Invalid input for ReplaceStep.fromJSON");
		return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
	}
};
/**
By default, for backwards compatibility, an inserting step
mapped over an insertion at that same position fill move after
the inserted content. In a collaborative editing situation, that
can make redone insertions appear in unexpected places. You can
set this to -1 to make such mapping keep the step before the
insertion instead.
*/
ReplaceStep.MAP_BIAS = 1;
Step.jsonID("replace", ReplaceStep);
/**
Replace a part of the document with a slice of content, but
preserve a range of the replaced content by moving it into the
slice.
*/
var ReplaceAroundStep = class ReplaceAroundStep extends Step {
	/**
	Create a replace-around step with the given range and gap.
	`insert` should be the point in the slice into which the content
	of the gap should be moved. `structure` has the same meaning as
	it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class.
	*/
	constructor(from, to, gapFrom, gapTo, slice, insert, structure = false) {
		super();
		this.from = from;
		this.to = to;
		this.gapFrom = gapFrom;
		this.gapTo = gapTo;
		this.slice = slice;
		this.insert = insert;
		this.structure = structure;
	}
	apply(doc) {
		if (this.structure && (contentBetween(doc, this.from, this.gapFrom) || contentBetween(doc, this.gapTo, this.to))) return StepResult.fail("Structure gap-replace would overwrite content");
		let gap = doc.slice(this.gapFrom, this.gapTo);
		if (gap.openStart || gap.openEnd) return StepResult.fail("Gap is not a flat range");
		let inserted = this.slice.insertAt(this.insert, gap.content);
		if (!inserted) return StepResult.fail("Content does not fit in gap");
		return StepResult.fromReplace(doc, this.from, this.to, inserted);
	}
	getMap() {
		return new StepMap([
			this.from,
			this.gapFrom - this.from,
			this.insert,
			this.gapTo,
			this.to - this.gapTo,
			this.slice.size - this.insert
		]);
	}
	invert(doc) {
		let gap = this.gapTo - this.gapFrom;
		return new ReplaceAroundStep(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure);
	}
	map(mapping) {
		let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
		let gapFrom = this.from == this.gapFrom ? from.pos : mapping.map(this.gapFrom, -1);
		let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1);
		if (from.deletedAcross && to.deletedAcross || gapFrom < from.pos || gapTo > to.pos) return null;
		return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure);
	}
	toJSON() {
		let json = {
			stepType: "replaceAround",
			from: this.from,
			to: this.to,
			gapFrom: this.gapFrom,
			gapTo: this.gapTo,
			insert: this.insert
		};
		if (this.slice.size) json.slice = this.slice.toJSON();
		if (this.structure) json.structure = true;
		return json;
	}
	/**
	@internal
	*/
	static fromJSON(schema, json) {
		if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");
		return new ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure);
	}
};
Step.jsonID("replaceAround", ReplaceAroundStep);
function contentBetween(doc, from, to) {
	let $from = doc.resolve(from), dist = to - from, depth = $from.depth;
	while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) {
		depth--;
		dist--;
	}
	if (dist > 0) {
		let next = $from.node(depth).maybeChild($from.indexAfter(depth));
		while (dist > 0) {
			if (!next || next.isLeaf) return true;
			next = next.firstChild;
			dist--;
		}
	}
	return false;
}
function addMark(tr, from, to, mark) {
	let removed = [], added = [];
	let removing, adding;
	tr.doc.nodesBetween(from, to, (node, pos, parent) => {
		if (!node.isInline) return;
		let marks = node.marks;
		if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {
			let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to);
			let newSet = mark.addToSet(marks);
			for (let i = 0; i < marks.length; i++) if (!marks[i].isInSet(newSet)) {
				if (removing && removing.to == start && removing.mark.eq(marks[i])) removing.to = end;
				else removed.push(removing = new RemoveMarkStep(start, end, marks[i]));
			}
			if (adding && adding.to == start) adding.to = end;
			else added.push(adding = new AddMarkStep(start, end, mark));
		}
	});
	removed.forEach((s) => tr.step(s));
	added.forEach((s) => tr.step(s));
}
function removeMark(tr, from, to, mark) {
	let matched = [], step = 0;
	tr.doc.nodesBetween(from, to, (node, pos) => {
		if (!node.isInline) return;
		step++;
		let toRemove = null;
		if (mark instanceof MarkType) {
			let set = node.marks, found;
			while (found = mark.isInSet(set)) {
				(toRemove || (toRemove = [])).push(found);
				set = found.removeFromSet(set);
			}
		} else if (mark) {
			if (mark.isInSet(node.marks)) toRemove = [mark];
		} else toRemove = node.marks;
		if (toRemove && toRemove.length) {
			let end = Math.min(pos + node.nodeSize, to);
			for (let i = 0; i < toRemove.length; i++) {
				let style = toRemove[i], found;
				for (let j = 0; j < matched.length; j++) {
					let m = matched[j];
					if (m.step == step - 1 && style.eq(matched[j].style)) found = m;
				}
				if (found) {
					found.to = end;
					found.step = step;
				} else matched.push({
					style,
					from: Math.max(pos, from),
					to: end,
					step
				});
			}
		}
	});
	matched.forEach((m) => tr.step(new RemoveMarkStep(m.from, m.to, m.style)));
}
function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch, clearNewlines = true) {
	let node = tr.doc.nodeAt(pos);
	let replSteps = [], cur = pos + 1;
	for (let i = 0; i < node.childCount; i++) {
		let child = node.child(i), end = cur + child.nodeSize;
		let allowed = match.matchType(child.type);
		if (!allowed) replSteps.push(new ReplaceStep(cur, end, Slice.empty));
		else {
			match = allowed;
			for (let j = 0; j < child.marks.length; j++) if (!parentType.allowsMarkType(child.marks[j].type)) tr.step(new RemoveMarkStep(cur, end, child.marks[j]));
			if (clearNewlines && child.isText && parentType.whitespace != "pre") {
				let m, newline = /\r?\n|\r/g, slice;
				while (m = newline.exec(child.text)) {
					if (!slice) slice = new Slice(Fragment$8.from(parentType.schema.text(" ", parentType.allowedMarks(child.marks))), 0, 0);
					replSteps.push(new ReplaceStep(cur + m.index, cur + m.index + m[0].length, slice));
				}
			}
		}
		cur = end;
	}
	if (!match.validEnd) {
		let fill = match.fillBefore(Fragment$8.empty, true);
		tr.replace(cur, cur, new Slice(fill, 0, 0));
	}
	for (let i = replSteps.length - 1; i >= 0; i--) tr.step(replSteps[i]);
}
function canCut(node, start, end) {
	return (start == 0 || node.canReplace(start, node.childCount)) && (end == node.childCount || node.canReplace(0, end));
}
/**
Try to find a target depth to which the content in the given range
can be lifted. Will not go across
[isolating](https://prosemirror.net/docs/ref/#model.NodeSpec.isolating) parent nodes.
*/
function liftTarget(range) {
	let content = range.parent.content.cutByIndex(range.startIndex, range.endIndex);
	for (let depth = range.depth, contentBefore = 0, contentAfter = 0;; --depth) {
		let node = range.$from.node(depth);
		let index = range.$from.index(depth) + contentBefore, endIndex = range.$to.indexAfter(depth) - contentAfter;
		if (depth < range.depth && node.canReplace(index, endIndex, content)) return depth;
		if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) break;
		if (index) contentBefore = 1;
		if (endIndex < node.childCount) contentAfter = 1;
	}
	return null;
}
function lift$2(tr, range, target) {
	let { $from, $to, depth } = range;
	let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1);
	let start = gapStart, end = gapEnd;
	let before = Fragment$8.empty, openStart = 0;
	for (let d = depth, splitting = false; d > target; d--) if (splitting || $from.index(d) > 0) {
		splitting = true;
		before = Fragment$8.from($from.node(d).copy(before));
		openStart++;
	} else start--;
	let after = Fragment$8.empty, openEnd = 0;
	for (let d = depth, splitting = false; d > target; d--) if (splitting || $to.after(d + 1) < $to.end(d)) {
		splitting = true;
		after = Fragment$8.from($to.node(d).copy(after));
		openEnd++;
	} else end++;
	tr.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, new Slice(before.append(after), openStart, openEnd), before.size - openStart, true));
}
/**
Try to find a valid way to wrap the content in the given range in a
node of the given type. May introduce extra nodes around and inside
the wrapper node, if necessary. Returns null if no valid wrapping
could be found. When `innerRange` is given, that range's content is
used as the content to fit into the wrapping, instead of the
content of `range`.
*/
function findWrapping(range, nodeType, attrs = null, innerRange = range) {
	let around = findWrappingOutside(range, nodeType);
	let inner = around && findWrappingInside(innerRange, nodeType);
	if (!inner) return null;
	return around.map(withAttrs).concat({
		type: nodeType,
		attrs
	}).concat(inner.map(withAttrs));
}
function withAttrs(type) {
	return {
		type,
		attrs: null
	};
}
function findWrappingOutside(range, type) {
	let { parent, startIndex, endIndex } = range;
	let around = parent.contentMatchAt(startIndex).findWrapping(type);
	if (!around) return null;
	let outer = around.length ? around[0] : type;
	return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null;
}
function findWrappingInside(range, type) {
	let { parent, startIndex, endIndex } = range;
	let inner = parent.child(startIndex);
	let inside = type.contentMatch.findWrapping(inner.type);
	if (!inside) return null;
	let innerMatch = (inside.length ? inside[inside.length - 1] : type).contentMatch;
	for (let i = startIndex; innerMatch && i < endIndex; i++) innerMatch = innerMatch.matchType(parent.child(i).type);
	if (!innerMatch || !innerMatch.validEnd) return null;
	return inside;
}
function wrap(tr, range, wrappers) {
	let content = Fragment$8.empty;
	for (let i = wrappers.length - 1; i >= 0; i--) {
		if (content.size) {
			let match = wrappers[i].type.contentMatch.matchFragment(content);
			if (!match || !match.validEnd) throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper");
		}
		content = Fragment$8.from(wrappers[i].type.create(wrappers[i].attrs, content));
	}
	let start = range.start, end = range.end;
	tr.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true));
}
function setBlockType$1(tr, from, to, type, attrs) {
	if (!type.isTextblock) throw new RangeError("Type given to setBlockType should be a textblock");
	let mapFrom = tr.steps.length;
	tr.doc.nodesBetween(from, to, (node, pos) => {
		let attrsHere = typeof attrs == "function" ? attrs(node) : attrs;
		if (node.isTextblock && !node.hasMarkup(type, attrsHere) && canChangeType(tr.doc, tr.mapping.slice(mapFrom).map(pos), type)) {
			let convertNewlines = null;
			if (type.schema.linebreakReplacement) {
				let pre = type.whitespace == "pre", supportLinebreak = !!type.contentMatch.matchType(type.schema.linebreakReplacement);
				if (pre && !supportLinebreak) convertNewlines = false;
				else if (!pre && supportLinebreak) convertNewlines = true;
			}
			if (convertNewlines === false) replaceLinebreaks(tr, node, pos, mapFrom);
			clearIncompatible(tr, tr.mapping.slice(mapFrom).map(pos, 1), type, void 0, convertNewlines === null);
			let mapping = tr.mapping.slice(mapFrom);
			let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1);
			tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment$8.from(type.create(attrsHere, null, node.marks)), 0, 0), 1, true));
			if (convertNewlines === true) replaceNewlines(tr, node, pos, mapFrom);
			return false;
		}
	});
}
function replaceNewlines(tr, node, pos, mapFrom) {
	node.forEach((child, offset) => {
		if (child.isText) {
			let m, newline = /\r?\n|\r/g;
			while (m = newline.exec(child.text)) {
				let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset + m.index);
				tr.replaceWith(start, start + 1, node.type.schema.linebreakReplacement.create());
			}
		}
	});
}
function replaceLinebreaks(tr, node, pos, mapFrom) {
	node.forEach((child, offset) => {
		if (child.type == child.type.schema.linebreakReplacement) {
			let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset);
			tr.replaceWith(start, start + 1, node.type.schema.text("\n"));
		}
	});
}
function canChangeType(doc, pos, type) {
	let $pos = doc.resolve(pos), index = $pos.index();
	return $pos.parent.canReplaceWith(index, index + 1, type);
}
/**
Change the type, attributes, and/or marks of the node at `pos`.
When `type` isn't given, the existing node type is preserved,
*/
function setNodeMarkup(tr, pos, type, attrs, marks) {
	let node = tr.doc.nodeAt(pos);
	if (!node) throw new RangeError("No node at given position");
	if (!type) type = node.type;
	let newNode = type.create(attrs, null, marks || node.marks);
	if (node.isLeaf) return tr.replaceWith(pos, pos + node.nodeSize, newNode);
	if (!type.validContent(node.content)) throw new RangeError("Invalid content for node type " + type.name);
	tr.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, new Slice(Fragment$8.from(newNode), 0, 0), 1, true));
}
/**
Check whether splitting at the given position is allowed.
*/
function canSplit(doc, pos, depth = 1, typesAfter) {
	let $pos = doc.resolve(pos), base = $pos.depth - depth;
	let innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent;
	if (base < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) return false;
	for (let d = $pos.depth - 1, i = depth - 2; d > base; d--, i--) {
		let node = $pos.node(d), index = $pos.index(d);
		if (node.type.spec.isolating) return false;
		let rest = node.content.cutByIndex(index, node.childCount);
		let overrideChild = typesAfter && typesAfter[i + 1];
		if (overrideChild) rest = rest.replaceChild(0, overrideChild.type.create(overrideChild.attrs));
		let after = typesAfter && typesAfter[i] || node;
		if (!node.canReplace(index + 1, node.childCount) || !after.type.validContent(rest)) return false;
	}
	let index = $pos.indexAfter(base);
	let baseType = typesAfter && typesAfter[0];
	return $pos.node(base).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base + 1).type);
}
function split(tr, pos, depth = 1, typesAfter) {
	let $pos = tr.doc.resolve(pos), before = Fragment$8.empty, after = Fragment$8.empty;
	for (let d = $pos.depth, e = $pos.depth - depth, i = depth - 1; d > e; d--, i--) {
		before = Fragment$8.from($pos.node(d).copy(before));
		let typeAfter = typesAfter && typesAfter[i];
		after = Fragment$8.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d).copy(after));
	}
	tr.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true));
}
/**
Test whether the blocks before and after a given position can be
joined.
*/
function canJoin(doc, pos) {
	let $pos = doc.resolve(pos), index = $pos.index();
	return joinable($pos.nodeBefore, $pos.nodeAfter) && $pos.parent.canReplace(index, index + 1);
}
function canAppendWithSubstitutedLinebreaks(a, b) {
	if (!b.content.size) a.type.compatibleContent(b.type);
	let match = a.contentMatchAt(a.childCount);
	let { linebreakReplacement } = a.type.schema;
	for (let i = 0; i < b.childCount; i++) {
		let child = b.child(i);
		let type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type;
		match = match.matchType(type);
		if (!match) return false;
		if (!a.type.allowsMarks(child.marks)) return false;
	}
	return match.validEnd;
}
function joinable(a, b) {
	return !!(a && b && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b));
}
/**
Find an ancestor of the given position that can be joined to the
block before (or after if `dir` is positive). Returns the joinable
point, if any.
*/
function joinPoint(doc, pos, dir = -1) {
	let $pos = doc.resolve(pos);
	for (let d = $pos.depth;; d--) {
		let before, after, index = $pos.index(d);
		if (d == $pos.depth) {
			before = $pos.nodeBefore;
			after = $pos.nodeAfter;
		} else if (dir > 0) {
			before = $pos.node(d + 1);
			index++;
			after = $pos.node(d).maybeChild(index);
		} else {
			before = $pos.node(d).maybeChild(index - 1);
			after = $pos.node(d + 1);
		}
		if (before && !before.isTextblock && joinable(before, after) && $pos.node(d).canReplace(index, index + 1)) return pos;
		if (d == 0) break;
		pos = dir < 0 ? $pos.before(d) : $pos.after(d);
	}
}
function join(tr, pos, depth) {
	let convertNewlines = null;
	let { linebreakReplacement } = tr.doc.type.schema;
	let $before = tr.doc.resolve(pos - depth), beforeType = $before.node().type;
	if (linebreakReplacement && beforeType.inlineContent) {
		let pre = beforeType.whitespace == "pre";
		let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement);
		if (pre && !supportLinebreak) convertNewlines = false;
		else if (!pre && supportLinebreak) convertNewlines = true;
	}
	let mapFrom = tr.steps.length;
	if (convertNewlines === false) {
		let $after = tr.doc.resolve(pos + depth);
		replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom);
	}
	if (beforeType.inlineContent) clearIncompatible(tr, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null);
	let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos - depth);
	tr.step(new ReplaceStep(start, mapping.map(pos + depth, -1), Slice.empty, true));
	if (convertNewlines === true) {
		let $full = tr.doc.resolve(start);
		replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length);
	}
	return tr;
}
/**
Try to find a point where a node of the given type can be inserted
near `pos`, by searching up the node hierarchy when `pos` itself
isn't a valid place but is at the start or end of a node. Return
null if no position was found.
*/
function insertPoint(doc, pos, nodeType) {
	let $pos = doc.resolve(pos);
	if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) return pos;
	if ($pos.parentOffset == 0) for (let d = $pos.depth - 1; d >= 0; d--) {
		let index = $pos.index(d);
		if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.before(d + 1);
		if (index > 0) return null;
	}
	if ($pos.parentOffset == $pos.parent.content.size) for (let d = $pos.depth - 1; d >= 0; d--) {
		let index = $pos.indexAfter(d);
		if ($pos.node(d).canReplaceWith(index, index, nodeType)) return $pos.after(d + 1);
		if (index < $pos.node(d).childCount) return null;
	}
	return null;
}
/**
Finds a position at or around the given position where the given
slice can be inserted. Will look at parent nodes' nearest boundary
and try there, even if the original position wasn't directly at the
start or end of that node. Returns null when no position was found.
*/
function dropPoint(doc, pos, slice) {
	let $pos = doc.resolve(pos);
	if (!slice.content.size) return pos;
	let content = slice.content;
	for (let i = 0; i < slice.openStart; i++) content = content.firstChild.content;
	for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) for (let d = $pos.depth; d >= 0; d--) {
		let bias = d == $pos.depth ? 0 : $pos.pos <= ($pos.start(d + 1) + $pos.end(d + 1)) / 2 ? -1 : 1;
		let insertPos = $pos.index(d) + (bias > 0 ? 1 : 0);
		let parent = $pos.node(d), fits = false;
		if (pass == 1) fits = parent.canReplace(insertPos, insertPos, content);
		else {
			let wrapping = parent.contentMatchAt(insertPos).findWrapping(content.firstChild.type);
			fits = wrapping && parent.canReplaceWith(insertPos, insertPos, wrapping[0]);
		}
		if (fits) return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d + 1) : $pos.after(d + 1);
	}
	return null;
}
/**
‘Fit’ a slice into a given position in the document, producing a
[step](https://prosemirror.net/docs/ref/#transform.Step) that inserts it. Will return null if
there's no meaningful way to insert the slice here, or inserting it
would be a no-op (an empty slice over an empty range).
*/
function replaceStep(doc, from, to = from, slice = Slice.empty) {
	if (from == to && !slice.size) return null;
	let $from = doc.resolve(from), $to = doc.resolve(to);
	if (fitsTrivially($from, $to, slice)) return new ReplaceStep(from, to, slice);
	return new Fitter($from, $to, slice).fit();
}
function fitsTrivially($from, $to, slice) {
	return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && $from.parent.canReplace($from.index(), $to.index(), slice.content);
}
var Fitter = class {
	constructor($from, $to, unplaced) {
		this.$from = $from;
		this.$to = $to;
		this.unplaced = unplaced;
		this.frontier = [];
		this.placed = Fragment$8.empty;
		for (let i = 0; i <= $from.depth; i++) {
			let node = $from.node(i);
			this.frontier.push({
				type: node.type,
				match: node.contentMatchAt($from.indexAfter(i))
			});
		}
		for (let i = $from.depth; i > 0; i--) this.placed = Fragment$8.from($from.node(i).copy(this.placed));
	}
	get depth() {
		return this.frontier.length - 1;
	}
	fit() {
		while (this.unplaced.size) {
			let fit = this.findFittable();
			if (fit) this.placeNodes(fit);
			else this.openMore() || this.dropNode();
		}
		let moveInline = this.mustMoveInline(), placedSize = this.placed.size - this.depth - this.$from.depth;
		let $from = this.$from, $to = this.close(moveInline < 0 ? this.$to : $from.doc.resolve(moveInline));
		if (!$to) return null;
		let content = this.placed, openStart = $from.depth, openEnd = $to.depth;
		while (openStart && openEnd && content.childCount == 1) {
			content = content.firstChild.content;
			openStart--;
			openEnd--;
		}
		let slice = new Slice(content, openStart, openEnd);
		if (moveInline > -1) return new ReplaceAroundStep($from.pos, moveInline, this.$to.pos, this.$to.end(), slice, placedSize);
		if (slice.size || $from.pos != this.$to.pos) return new ReplaceStep($from.pos, $to.pos, slice);
		return null;
	}
	findFittable() {
		let startDepth = this.unplaced.openStart;
		for (let cur = this.unplaced.content, d = 0, openEnd = this.unplaced.openEnd; d < startDepth; d++) {
			let node = cur.firstChild;
			if (cur.childCount > 1) openEnd = 0;
			if (node.type.spec.isolating && openEnd <= d) {
				startDepth = d;
				break;
			}
			cur = node.content;
		}
		for (let pass = 1; pass <= 2; pass++) for (let sliceDepth = pass == 1 ? startDepth : this.unplaced.openStart; sliceDepth >= 0; sliceDepth--) {
			let fragment, parent = null;
			if (sliceDepth) {
				parent = contentAt(this.unplaced.content, sliceDepth - 1).firstChild;
				fragment = parent.content;
			} else fragment = this.unplaced.content;
			let first = fragment.firstChild;
			for (let frontierDepth = this.depth; frontierDepth >= 0; frontierDepth--) {
				let { type, match } = this.frontier[frontierDepth], wrap, inject = null;
				if (pass == 1 && (first ? match.matchType(first.type) || (inject = match.fillBefore(Fragment$8.from(first), false)) : parent && type.compatibleContent(parent.type))) return {
					sliceDepth,
					frontierDepth,
					parent,
					inject
				};
				else if (pass == 2 && first && (wrap = match.findWrapping(first.type))) return {
					sliceDepth,
					frontierDepth,
					parent,
					wrap
				};
				if (parent && match.matchType(parent.type)) break;
			}
		}
	}
	openMore() {
		let { content, openStart, openEnd } = this.unplaced;
		let inner = contentAt(content, openStart);
		if (!inner.childCount || inner.firstChild.isLeaf) return false;
		this.unplaced = new Slice(content, openStart + 1, Math.max(openEnd, inner.size + openStart >= content.size - openEnd ? openStart + 1 : 0));
		return true;
	}
	dropNode() {
		let { content, openStart, openEnd } = this.unplaced;
		let inner = contentAt(content, openStart);
		if (inner.childCount <= 1 && openStart > 0) {
			let openAtEnd = content.size - openStart <= openStart + inner.size;
			this.unplaced = new Slice(dropFromFragment(content, openStart - 1, 1), openStart - 1, openAtEnd ? openStart - 1 : openEnd);
		} else this.unplaced = new Slice(dropFromFragment(content, openStart, 1), openStart, openEnd);
	}
	placeNodes({ sliceDepth, frontierDepth, parent, inject, wrap }) {
		while (this.depth > frontierDepth) this.closeFrontierNode();
		if (wrap) for (let i = 0; i < wrap.length; i++) this.openFrontierNode(wrap[i]);
		let slice = this.unplaced, fragment = parent ? parent.content : slice.content;
		let openStart = slice.openStart - sliceDepth;
		let taken = 0, add = [];
		let { match, type } = this.frontier[frontierDepth];
		if (inject) {
			for (let i = 0; i < inject.childCount; i++) add.push(inject.child(i));
			match = match.matchFragment(inject);
		}
		let openEndCount = fragment.size + sliceDepth - (slice.content.size - slice.openEnd);
		while (taken < fragment.childCount) {
			let next = fragment.child(taken), matches = match.matchType(next.type);
			if (!matches) break;
			taken++;
			if (taken > 1 || openStart == 0 || next.content.size) {
				match = matches;
				add.push(closeNodeStart(next.mark(type.allowedMarks(next.marks)), taken == 1 ? openStart : 0, taken == fragment.childCount ? openEndCount : -1));
			}
		}
		let toEnd = taken == fragment.childCount;
		if (!toEnd) openEndCount = -1;
		this.placed = addToFragment(this.placed, frontierDepth, Fragment$8.from(add));
		this.frontier[frontierDepth].match = match;
		if (toEnd && openEndCount < 0 && parent && parent.type == this.frontier[this.depth].type && this.frontier.length > 1) this.closeFrontierNode();
		for (let i = 0, cur = fragment; i < openEndCount; i++) {
			let node = cur.lastChild;
			this.frontier.push({
				type: node.type,
				match: node.contentMatchAt(node.childCount)
			});
			cur = node.content;
		}
		this.unplaced = !toEnd ? new Slice(dropFromFragment(slice.content, sliceDepth, taken), slice.openStart, slice.openEnd) : sliceDepth == 0 ? Slice.empty : new Slice(dropFromFragment(slice.content, sliceDepth - 1, 1), sliceDepth - 1, openEndCount < 0 ? slice.openEnd : sliceDepth - 1);
	}
	mustMoveInline() {
		if (!this.$to.parent.isTextblock) return -1;
		let top = this.frontier[this.depth], level;
		if (!top.type.isTextblock || !contentAfterFits(this.$to, this.$to.depth, top.type, top.match, false) || this.$to.depth == this.depth && (level = this.findCloseLevel(this.$to)) && level.depth == this.depth) return -1;
		let { depth } = this.$to, after = this.$to.after(depth);
		while (depth > 1 && after == this.$to.end(--depth)) ++after;
		return after;
	}
	findCloseLevel($to) {
		scan: for (let i = Math.min(this.depth, $to.depth); i >= 0; i--) {
			let { match, type } = this.frontier[i];
			let dropInner = i < $to.depth && $to.end(i + 1) == $to.pos + ($to.depth - (i + 1));
			let fit = contentAfterFits($to, i, type, match, dropInner);
			if (!fit) continue;
			for (let d = i - 1; d >= 0; d--) {
				let { match, type } = this.frontier[d];
				let matches = contentAfterFits($to, d, type, match, true);
				if (!matches || matches.childCount) continue scan;
			}
			return {
				depth: i,
				fit,
				move: dropInner ? $to.doc.resolve($to.after(i + 1)) : $to
			};
		}
	}
	close($to) {
		let close = this.findCloseLevel($to);
		if (!close) return null;
		while (this.depth > close.depth) this.closeFrontierNode();
		if (close.fit.childCount) this.placed = addToFragment(this.placed, close.depth, close.fit);
		$to = close.move;
		for (let d = close.depth + 1; d <= $to.depth; d++) {
			let node = $to.node(d), add = node.type.contentMatch.fillBefore(node.content, true, $to.index(d));
			this.openFrontierNode(node.type, node.attrs, add);
		}
		return $to;
	}
	openFrontierNode(type, attrs = null, content) {
		let top = this.frontier[this.depth];
		top.match = top.match.matchType(type);
		this.placed = addToFragment(this.placed, this.depth, Fragment$8.from(type.create(attrs, content)));
		this.frontier.push({
			type,
			match: type.contentMatch
		});
	}
	closeFrontierNode() {
		let add = this.frontier.pop().match.fillBefore(Fragment$8.empty, true);
		if (add.childCount) this.placed = addToFragment(this.placed, this.frontier.length, add);
	}
};
function dropFromFragment(fragment, depth, count) {
	if (depth == 0) return fragment.cutByIndex(count, fragment.childCount);
	return fragment.replaceChild(0, fragment.firstChild.copy(dropFromFragment(fragment.firstChild.content, depth - 1, count)));
}
function addToFragment(fragment, depth, content) {
	if (depth == 0) return fragment.append(content);
	return fragment.replaceChild(fragment.childCount - 1, fragment.lastChild.copy(addToFragment(fragment.lastChild.content, depth - 1, content)));
}
function contentAt(fragment, depth) {
	for (let i = 0; i < depth; i++) fragment = fragment.firstChild.content;
	return fragment;
}
function closeNodeStart(node, openStart, openEnd) {
	if (openStart <= 0) return node;
	let frag = node.content;
	if (openStart > 1) frag = frag.replaceChild(0, closeNodeStart(frag.firstChild, openStart - 1, frag.childCount == 1 ? openEnd - 1 : 0));
	if (openStart > 0) {
		frag = node.type.contentMatch.fillBefore(frag).append(frag);
		if (openEnd <= 0) frag = frag.append(node.type.contentMatch.matchFragment(frag).fillBefore(Fragment$8.empty, true));
	}
	return node.copy(frag);
}
function contentAfterFits($to, depth, type, match, open) {
	let node = $to.node(depth), index = open ? $to.indexAfter(depth) : $to.index(depth);
	if (index == node.childCount && !type.compatibleContent(node.type)) return null;
	let fit = match.fillBefore(node.content, true, index);
	return fit && !invalidMarks(type, node.content, index) ? fit : null;
}
function invalidMarks(type, fragment, start) {
	for (let i = start; i < fragment.childCount; i++) if (!type.allowsMarks(fragment.child(i).marks)) return true;
	return false;
}
function definesContent(type) {
	return type.spec.defining || type.spec.definingForContent;
}
function replaceRange(tr, from, to, slice) {
	if (!slice.size) return tr.deleteRange(from, to);
	let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
	if (fitsTrivially($from, $to, slice)) return tr.step(new ReplaceStep(from, to, slice));
	let targetDepths = coveredDepths($from, $to);
	if (targetDepths[targetDepths.length - 1] == 0) targetDepths.pop();
	let preferredTarget = -($from.depth + 1);
	targetDepths.unshift(preferredTarget);
	for (let d = $from.depth, pos = $from.pos - 1; d > 0; d--, pos--) {
		let spec = $from.node(d).type.spec;
		if (spec.defining || spec.definingAsContext || spec.isolating) break;
		if (targetDepths.indexOf(d) > -1) preferredTarget = d;
		else if ($from.before(d) == pos) targetDepths.splice(1, 0, -d);
	}
	let preferredTargetIndex = targetDepths.indexOf(preferredTarget);
	let leftNodes = [], preferredDepth = slice.openStart;
	for (let content = slice.content, i = 0;; i++) {
		let node = content.firstChild;
		leftNodes.push(node);
		if (i == slice.openStart) break;
		content = node.content;
	}
	for (let d = preferredDepth - 1; d >= 0; d--) {
		let leftNode = leftNodes[d], def = definesContent(leftNode.type);
		if (def && !leftNode.sameMarkup($from.node(Math.abs(preferredTarget) - 1))) preferredDepth = d;
		else if (def || !leftNode.type.isTextblock) break;
	}
	for (let j = slice.openStart; j >= 0; j--) {
		let openDepth = (j + preferredDepth + 1) % (slice.openStart + 1);
		let insert = leftNodes[openDepth];
		if (!insert) continue;
		for (let i = 0; i < targetDepths.length; i++) {
			let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true;
			if (targetDepth < 0) {
				expand = false;
				targetDepth = -targetDepth;
			}
			let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1);
			if (parent.canReplaceWith(index, index, insert.type, insert.marks)) return tr.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), openDepth, slice.openEnd));
		}
	}
	let startSteps = tr.steps.length;
	for (let i = targetDepths.length - 1; i >= 0; i--) {
		tr.replace(from, to, slice);
		if (tr.steps.length > startSteps) break;
		let depth = targetDepths[i];
		if (depth < 0) continue;
		from = $from.before(depth);
		to = $to.after(depth);
	}
}
function closeFragment(fragment, depth, oldOpen, newOpen, parent) {
	if (depth < oldOpen) {
		let first = fragment.firstChild;
		fragment = fragment.replaceChild(0, first.copy(closeFragment(first.content, depth + 1, oldOpen, newOpen, first)));
	}
	if (depth > newOpen) {
		let match = parent.contentMatchAt(0);
		let start = match.fillBefore(fragment).append(fragment);
		fragment = start.append(match.matchFragment(start).fillBefore(Fragment$8.empty, true));
	}
	return fragment;
}
function replaceRangeWith(tr, from, to, node) {
	if (!node.isInline && from == to && tr.doc.resolve(from).parent.content.size) {
		let point = insertPoint(tr.doc, from, node.type);
		if (point != null) from = to = point;
	}
	tr.replaceRange(from, to, new Slice(Fragment$8.from(node), 0, 0));
}
function deleteRange$1(tr, from, to) {
	let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
	if ($from.parent.isTextblock && $to.parent.isTextblock && $from.start() != $to.start() && $from.parentOffset == 0 && $to.parentOffset == 0) {
		let shared = $from.sharedDepth(to), isolated = false;
		for (let d = $from.depth; d > shared; d--) if ($from.node(d).type.spec.isolating) isolated = true;
		for (let d = $to.depth; d > shared; d--) if ($to.node(d).type.spec.isolating) isolated = true;
		if (!isolated) {
			for (let d = $from.depth; d > 0 && from == $from.start(d); d--) from = $from.before(d);
			for (let d = $to.depth; d > 0 && to == $to.start(d); d--) to = $to.before(d);
			$from = tr.doc.resolve(from);
			$to = tr.doc.resolve(to);
		}
	}
	let covered = coveredDepths($from, $to);
	for (let i = 0; i < covered.length; i++) {
		let depth = covered[i], last = i == covered.length - 1;
		if (last && depth == 0 || $from.node(depth).type.contentMatch.validEnd) return tr.delete($from.start(depth), $to.end(depth));
		if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) return tr.delete($from.before(depth), $to.after(depth));
	}
	for (let d = 1; d <= $from.depth && d <= $to.depth; d++) if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d && $from.start(d - 1) == $to.start(d - 1) && $from.node(d - 1).canReplace($from.index(d - 1), $to.index(d - 1))) return tr.delete($from.before(d), to);
	tr.delete(from, to);
}
function coveredDepths($from, $to) {
	let result = [], minDepth = Math.min($from.depth, $to.depth);
	for (let d = minDepth; d >= 0; d--) {
		let start = $from.start(d);
		if (start < $from.pos - ($from.depth - d) || $to.end(d) > $to.pos + ($to.depth - d) || $from.node(d).type.spec.isolating || $to.node(d).type.spec.isolating) break;
		if (start == $to.start(d) || d == $from.depth && d == $to.depth && $from.parent.inlineContent && $to.parent.inlineContent && d && $to.start(d - 1) == start - 1) result.push(d);
	}
	return result;
}
/**
Update an attribute in a specific node.
*/
var AttrStep = class AttrStep extends Step {
	/**
	Construct an attribute step.
	*/
	constructor(pos, attr, value) {
		super();
		this.pos = pos;
		this.attr = attr;
		this.value = value;
	}
	apply(doc) {
		let node = doc.nodeAt(this.pos);
		if (!node) return StepResult.fail("No node at attribute step's position");
		let attrs = Object.create(null);
		for (let name in node.attrs) attrs[name] = node.attrs[name];
		attrs[this.attr] = this.value;
		let updated = node.type.create(attrs, null, node.marks);
		return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment$8.from(updated), 0, node.isLeaf ? 0 : 1));
	}
	getMap() {
		return StepMap.empty;
	}
	invert(doc) {
		return new AttrStep(this.pos, this.attr, doc.nodeAt(this.pos).attrs[this.attr]);
	}
	map(mapping) {
		let pos = mapping.mapResult(this.pos, 1);
		return pos.deletedAfter ? null : new AttrStep(pos.pos, this.attr, this.value);
	}
	toJSON() {
		return {
			stepType: "attr",
			pos: this.pos,
			attr: this.attr,
			value: this.value
		};
	}
	static fromJSON(schema, json) {
		if (typeof json.pos != "number" || typeof json.attr != "string") throw new RangeError("Invalid input for AttrStep.fromJSON");
		return new AttrStep(json.pos, json.attr, json.value);
	}
};
Step.jsonID("attr", AttrStep);
/**
Update an attribute in the doc node.
*/
var DocAttrStep = class DocAttrStep extends Step {
	/**
	Construct an attribute step.
	*/
	constructor(attr, value) {
		super();
		this.attr = attr;
		this.value = value;
	}
	apply(doc) {
		let attrs = Object.create(null);
		for (let name in doc.attrs) attrs[name] = doc.attrs[name];
		attrs[this.attr] = this.value;
		let updated = doc.type.create(attrs, doc.content, doc.marks);
		return StepResult.ok(updated);
	}
	getMap() {
		return StepMap.empty;
	}
	invert(doc) {
		return new DocAttrStep(this.attr, doc.attrs[this.attr]);
	}
	map(mapping) {
		return this;
	}
	toJSON() {
		return {
			stepType: "docAttr",
			attr: this.attr,
			value: this.value
		};
	}
	static fromJSON(schema, json) {
		if (typeof json.attr != "string") throw new RangeError("Invalid input for DocAttrStep.fromJSON");
		return new DocAttrStep(json.attr, json.value);
	}
};
Step.jsonID("docAttr", DocAttrStep);
/**
@internal
*/
var TransformError = class extends Error {};
TransformError = function TransformError(message) {
	let err = Error.call(this, message);
	err.__proto__ = TransformError.prototype;
	return err;
};
TransformError.prototype = Object.create(Error.prototype);
TransformError.prototype.constructor = TransformError;
TransformError.prototype.name = "TransformError";
/**
Abstraction to build up and track an array of
[steps](https://prosemirror.net/docs/ref/#transform.Step) representing a document transformation.

Most transforming methods return the `Transform` object itself, so
that they can be chained.
*/
var Transform = class {
	/**
	Create a transform that starts with the given document.
	*/
	constructor(doc) {
		this.doc = doc;
		/**
		The steps in this transform.
		*/
		this.steps = [];
		/**
		The documents before each of the steps.
		*/
		this.docs = [];
		/**
		A mapping with the maps for each of the steps in this transform.
		*/
		this.mapping = new Mapping();
	}
	/**
	The starting document.
	*/
	get before() {
		return this.docs.length ? this.docs[0] : this.doc;
	}
	/**
	Apply a new step in this transform, saving the result. Throws an
	error when the step fails.
	*/
	step(step) {
		let result = this.maybeStep(step);
		if (result.failed) throw new TransformError(result.failed);
		return this;
	}
	/**
	Try to apply a step in this transformation, ignoring it if it
	fails. Returns the step result.
	*/
	maybeStep(step) {
		let result = step.apply(this.doc);
		if (!result.failed) this.addStep(step, result.doc);
		return result;
	}
	/**
	True when the document has been changed (when there are any
	steps).
	*/
	get docChanged() {
		return this.steps.length > 0;
	}
	/**
	Return a single range, in post-transform document positions,
	that covers all content changed by this transform. Returns null
	if no replacements are made. Note that this will ignore changes
	that add/remove marks without replacing the underlying content.
	*/
	changedRange() {
		let from = 1e9, to = -1e9;
		for (let i = 0; i < this.mapping.maps.length; i++) {
			let map = this.mapping.maps[i];
			if (i) {
				from = map.map(from, 1);
				to = map.map(to, -1);
			}
			map.forEach((_f, _t, fromB, toB) => {
				from = Math.min(from, fromB);
				to = Math.max(to, toB);
			});
		}
		return from == 1e9 ? null : {
			from,
			to
		};
	}
	/**
	@internal
	*/
	addStep(step, doc) {
		this.docs.push(this.doc);
		this.steps.push(step);
		this.mapping.appendMap(step.getMap());
		this.doc = doc;
	}
	/**
	Replace the part of the document between `from` and `to` with the
	given `slice`.
	*/
	replace(from, to = from, slice = Slice.empty) {
		let step = replaceStep(this.doc, from, to, slice);
		if (step) this.step(step);
		return this;
	}
	/**
	Replace the given range with the given content, which may be a
	fragment, node, or array of nodes.
	*/
	replaceWith(from, to, content) {
		return this.replace(from, to, new Slice(Fragment$8.from(content), 0, 0));
	}
	/**
	Delete the content between the given positions.
	*/
	delete(from, to) {
		return this.replace(from, to, Slice.empty);
	}
	/**
	Insert the given content at the given position.
	*/
	insert(pos, content) {
		return this.replaceWith(pos, pos, content);
	}
	/**
	Replace a range of the document with a given slice, using
	`from`, `to`, and the slice's
	[`openStart`](https://prosemirror.net/docs/ref/#model.Slice.openStart) property as hints, rather
	than fixed start and end points. This method may grow the
	replaced area or close open nodes in the slice in order to get a
	fit that is more in line with WYSIWYG expectations, by dropping
	fully covered parent nodes of the replaced region when they are
	marked [non-defining as
	context](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext), or including an
	open parent node from the slice that _is_ marked as [defining
	its content](https://prosemirror.net/docs/ref/#model.NodeSpec.definingForContent).
	
	This is the method, for example, to handle paste. The similar
	[`replace`](https://prosemirror.net/docs/ref/#transform.Transform.replace) method is a more
	primitive tool which will _not_ move the start and end of its given
	range, and is useful in situations where you need more precise
	control over what happens.
	*/
	replaceRange(from, to, slice) {
		replaceRange(this, from, to, slice);
		return this;
	}
	/**
	Replace the given range with a node, but use `from` and `to` as
	hints, rather than precise positions. When from and to are the same
	and are at the start or end of a parent node in which the given
	node doesn't fit, this method may _move_ them out towards a parent
	that does allow the given node to be placed. When the given range
	completely covers a parent node, this method may completely replace
	that parent node.
	*/
	replaceRangeWith(from, to, node) {
		replaceRangeWith(this, from, to, node);
		return this;
	}
	/**
	Delete the given range, expanding it to cover fully covered
	parent nodes until a valid replace is found.
	*/
	deleteRange(from, to) {
		deleteRange$1(this, from, to);
		return this;
	}
	/**
	Split the content in the given range off from its parent, if there
	is sibling content before or after it, and move it up the tree to
	the depth specified by `target`. You'll probably want to use
	[`liftTarget`](https://prosemirror.net/docs/ref/#transform.liftTarget) to compute `target`, to make
	sure the lift is valid.
	*/
	lift(range, target) {
		lift$2(this, range, target);
		return this;
	}
	/**
	Join the blocks around the given position. If depth is 2, their
	last and first siblings are also joined, and so on.
	*/
	join(pos, depth = 1) {
		join(this, pos, depth);
		return this;
	}
	/**
	Wrap the given [range](https://prosemirror.net/docs/ref/#model.NodeRange) in the given set of wrappers.
	The wrappers are assumed to be valid in this position, and should
	probably be computed with [`findWrapping`](https://prosemirror.net/docs/ref/#transform.findWrapping).
	*/
	wrap(range, wrappers) {
		wrap(this, range, wrappers);
		return this;
	}
	/**
	Set the type of all textblocks (partly) between `from` and `to` to
	the given node type with the given attributes.
	*/
	setBlockType(from, to = from, type, attrs = null) {
		setBlockType$1(this, from, to, type, attrs);
		return this;
	}
	/**
	Change the type, attributes, and/or marks of the node at `pos`.
	When `type` isn't given, the existing node type is preserved,
	*/
	setNodeMarkup(pos, type, attrs = null, marks) {
		setNodeMarkup(this, pos, type, attrs, marks);
		return this;
	}
	/**
	Set a single attribute on a given node to a new value.
	The `pos` addresses the document content. Use `setDocAttribute`
	to set attributes on the document itself.
	*/
	setNodeAttribute(pos, attr, value) {
		this.step(new AttrStep(pos, attr, value));
		return this;
	}
	/**
	Set a single attribute on the document to a new value.
	*/
	setDocAttribute(attr, value) {
		this.step(new DocAttrStep(attr, value));
		return this;
	}
	/**
	Add a mark to the node at position `pos`.
	*/
	addNodeMark(pos, mark) {
		this.step(new AddNodeMarkStep(pos, mark));
		return this;
	}
	/**
	Remove a mark (or all marks of the given type) from the node at
	position `pos`.
	*/
	removeNodeMark(pos, mark) {
		let node = this.doc.nodeAt(pos);
		if (!node) throw new RangeError("No node at position " + pos);
		if (mark instanceof Mark$1) {
			if (mark.isInSet(node.marks)) this.step(new RemoveNodeMarkStep(pos, mark));
		} else {
			let set = node.marks, found, steps = [];
			while (found = mark.isInSet(set)) {
				steps.push(new RemoveNodeMarkStep(pos, found));
				set = found.removeFromSet(set);
			}
			for (let i = steps.length - 1; i >= 0; i--) this.step(steps[i]);
		}
		return this;
	}
	/**
	Split the node at the given position, and optionally, if `depth` is
	greater than one, any number of nodes above that. By default, the
	parts split off will inherit the node type of the original node.
	This can be changed by passing an array of types and attributes to
	use after the split (with the outermost nodes coming first).
	*/
	split(pos, depth = 1, typesAfter) {
		split(this, pos, depth, typesAfter);
		return this;
	}
	/**
	Add the given mark to the inline content between `from` and `to`.
	*/
	addMark(from, to, mark) {
		addMark(this, from, to, mark);
		return this;
	}
	/**
	Remove marks from inline nodes between `from` and `to`. When
	`mark` is a single mark, remove precisely that mark. When it is
	a mark type, remove all marks of that type. When it is null,
	remove all marks of any type.
	*/
	removeMark(from, to, mark) {
		removeMark(this, from, to, mark);
		return this;
	}
	/**
	Removes all marks and nodes from the content of the node at
	`pos` that don't match the given new parent node type. Accepts
	an optional starting [content match](https://prosemirror.net/docs/ref/#model.ContentMatch) as
	third argument.
	*/
	clearIncompatible(pos, parentType, match) {
		clearIncompatible(this, pos, parentType, match);
		return this;
	}
};
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-state@1.4.4/node_modules/prosemirror-state/dist/index.js
var classesById = Object.create(null);
/**
Superclass for editor selections. Every selection type should
extend this. Should not be instantiated directly.
*/
var Selection$1 = class {
	/**
	Initialize a selection with the head and anchor and ranges. If no
	ranges are given, constructs a single range across `$anchor` and
	`$head`.
	*/
	constructor($anchor, $head, ranges) {
		this.$anchor = $anchor;
		this.$head = $head;
		this.ranges = ranges || [new SelectionRange($anchor.min($head), $anchor.max($head))];
	}
	/**
	The selection's anchor, as an unresolved position.
	*/
	get anchor() {
		return this.$anchor.pos;
	}
	/**
	The selection's head.
	*/
	get head() {
		return this.$head.pos;
	}
	/**
	The lower bound of the selection's main range.
	*/
	get from() {
		return this.$from.pos;
	}
	/**
	The upper bound of the selection's main range.
	*/
	get to() {
		return this.$to.pos;
	}
	/**
	The resolved lower  bound of the selection's main range.
	*/
	get $from() {
		return this.ranges[0].$from;
	}
	/**
	The resolved upper bound of the selection's main range.
	*/
	get $to() {
		return this.ranges[0].$to;
	}
	/**
	Indicates whether the selection contains any content.
	*/
	get empty() {
		let ranges = this.ranges;
		for (let i = 0; i < ranges.length; i++) if (ranges[i].$from.pos != ranges[i].$to.pos) return false;
		return true;
	}
	/**
	Get the content of this selection as a slice.
	*/
	content() {
		return this.$from.doc.slice(this.from, this.to, true);
	}
	/**
	Replace the selection with a slice or, if no slice is given,
	delete the selection. Will append to the given transaction.
	*/
	replace(tr, content = Slice.empty) {
		let lastNode = content.content.lastChild, lastParent = null;
		for (let i = 0; i < content.openEnd; i++) {
			lastParent = lastNode;
			lastNode = lastNode.lastChild;
		}
		let mapFrom = tr.steps.length, ranges = this.ranges;
		for (let i = 0; i < ranges.length; i++) {
			let { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
			tr.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
			if (i == 0) selectionToInsertionEnd$1(tr, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1);
		}
	}
	/**
	Replace the selection with the given node, appending the changes
	to the given transaction.
	*/
	replaceWith(tr, node) {
		let mapFrom = tr.steps.length, ranges = this.ranges;
		for (let i = 0; i < ranges.length; i++) {
			let { $from, $to } = ranges[i], mapping = tr.mapping.slice(mapFrom);
			let from = mapping.map($from.pos), to = mapping.map($to.pos);
			if (i) tr.deleteRange(from, to);
			else {
				tr.replaceRangeWith(from, to, node);
				selectionToInsertionEnd$1(tr, mapFrom, node.isInline ? -1 : 1);
			}
		}
	}
	/**
	Find a valid cursor or leaf node selection starting at the given
	position and searching back if `dir` is negative, and forward if
	positive. When `textOnly` is true, only consider cursor
	selections. Will return null when no valid selection position is
	found.
	*/
	static findFrom($pos, dir, textOnly = false) {
		let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly);
		if (inner) return inner;
		for (let depth = $pos.depth - 1; depth >= 0; depth--) {
			let found = dir < 0 ? findSelectionIn($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly);
			if (found) return found;
		}
		return null;
	}
	/**
	Find a valid cursor or leaf node selection near the given
	position. Searches forward first by default, but if `bias` is
	negative, it will search backwards first.
	*/
	static near($pos, bias = 1) {
		return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection($pos.node(0));
	}
	/**
	Find the cursor or leaf node selection closest to the start of
	the given document. Will return an
	[`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position
	exists.
	*/
	static atStart(doc) {
		return findSelectionIn(doc, doc, 0, 0, 1) || new AllSelection(doc);
	}
	/**
	Find the cursor or leaf node selection closest to the end of the
	given document.
	*/
	static atEnd(doc) {
		return findSelectionIn(doc, doc, doc.content.size, doc.childCount, -1) || new AllSelection(doc);
	}
	/**
	Deserialize the JSON representation of a selection. Must be
	implemented for custom classes (as a static class method).
	*/
	static fromJSON(doc, json) {
		if (!json || !json.type) throw new RangeError("Invalid input for Selection.fromJSON");
		let cls = classesById[json.type];
		if (!cls) throw new RangeError(`No selection type ${json.type} defined`);
		return cls.fromJSON(doc, json);
	}
	/**
	To be able to deserialize selections from JSON, custom selection
	classes must register themselves with an ID string, so that they
	can be disambiguated. Try to pick something that's unlikely to
	clash with classes from other modules.
	*/
	static jsonID(id, selectionClass) {
		if (id in classesById) throw new RangeError("Duplicate use of selection JSON ID " + id);
		classesById[id] = selectionClass;
		selectionClass.prototype.jsonID = id;
		return selectionClass;
	}
	/**
	Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection,
	which is a value that can be mapped without having access to a
	current document, and later resolved to a real selection for a
	given document again. (This is used mostly by the history to
	track and restore old selections.) The default implementation of
	this method just converts the selection to a text selection and
	returns the bookmark for that.
	*/
	getBookmark() {
		return TextSelection.between(this.$anchor, this.$head).getBookmark();
	}
};
Selection$1.prototype.visible = true;
/**
Represents a selected range in a document.
*/
var SelectionRange = class {
	/**
	Create a range.
	*/
	constructor($from, $to) {
		this.$from = $from;
		this.$to = $to;
	}
};
var warnedAboutTextSelection = false;
function checkTextSelection($pos) {
	if (!warnedAboutTextSelection && !$pos.parent.inlineContent) {
		warnedAboutTextSelection = true;
		console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
	}
}
/**
A text selection represents a classical editor selection, with a
head (the moving side) and anchor (immobile side), both of which
point into textblock nodes. It can be empty (a regular cursor
position).
*/
var TextSelection = class TextSelection extends Selection$1 {
	/**
	Construct a text selection between the given points.
	*/
	constructor($anchor, $head = $anchor) {
		checkTextSelection($anchor);
		checkTextSelection($head);
		super($anchor, $head);
	}
	/**
	Returns a resolved position if this is a cursor selection (an
	empty text selection), and null otherwise.
	*/
	get $cursor() {
		return this.$anchor.pos == this.$head.pos ? this.$head : null;
	}
	map(doc, mapping) {
		let $head = doc.resolve(mapping.map(this.head));
		if (!$head.parent.inlineContent) return Selection$1.near($head);
		let $anchor = doc.resolve(mapping.map(this.anchor));
		return new TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head);
	}
	replace(tr, content = Slice.empty) {
		super.replace(tr, content);
		if (content == Slice.empty) {
			let marks = this.$from.marksAcross(this.$to);
			if (marks) tr.ensureMarks(marks);
		}
	}
	eq(other) {
		return other instanceof TextSelection && other.anchor == this.anchor && other.head == this.head;
	}
	getBookmark() {
		return new TextBookmark(this.anchor, this.head);
	}
	toJSON() {
		return {
			type: "text",
			anchor: this.anchor,
			head: this.head
		};
	}
	/**
	@internal
	*/
	static fromJSON(doc, json) {
		if (typeof json.anchor != "number" || typeof json.head != "number") throw new RangeError("Invalid input for TextSelection.fromJSON");
		return new TextSelection(doc.resolve(json.anchor), doc.resolve(json.head));
	}
	/**
	Create a text selection from non-resolved positions.
	*/
	static create(doc, anchor, head = anchor) {
		let $anchor = doc.resolve(anchor);
		return new this($anchor, head == anchor ? $anchor : doc.resolve(head));
	}
	/**
	Return a text selection that spans the given positions or, if
	they aren't text positions, find a text selection near them.
	`bias` determines whether the method searches forward (default)
	or backwards (negative number) first. Will fall back to calling
	[`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document
	doesn't contain a valid text position.
	*/
	static between($anchor, $head, bias) {
		let dPos = $anchor.pos - $head.pos;
		if (!bias || dPos) bias = dPos >= 0 ? 1 : -1;
		if (!$head.parent.inlineContent) {
			let found = Selection$1.findFrom($head, bias, true) || Selection$1.findFrom($head, -bias, true);
			if (found) $head = found.$head;
			else return Selection$1.near($head, bias);
		}
		if (!$anchor.parent.inlineContent) {
			if (dPos == 0) $anchor = $head;
			else {
				$anchor = (Selection$1.findFrom($anchor, -bias, true) || Selection$1.findFrom($anchor, bias, true)).$anchor;
				if ($anchor.pos < $head.pos != dPos < 0) $anchor = $head;
			}
		}
		return new TextSelection($anchor, $head);
	}
};
Selection$1.jsonID("text", TextSelection);
var TextBookmark = class TextBookmark {
	constructor(anchor, head) {
		this.anchor = anchor;
		this.head = head;
	}
	map(mapping) {
		return new TextBookmark(mapping.map(this.anchor), mapping.map(this.head));
	}
	resolve(doc) {
		return TextSelection.between(doc.resolve(this.anchor), doc.resolve(this.head));
	}
};
/**
A node selection is a selection that points at a single node. All
nodes marked [selectable](https://prosemirror.net/docs/ref/#model.NodeSpec.selectable) can be the
target of a node selection. In such a selection, `from` and `to`
point directly before and after the selected node, `anchor` equals
`from`, and `head` equals `to`..
*/
var NodeSelection = class NodeSelection extends Selection$1 {
	/**
	Create a node selection. Does not verify the validity of its
	argument.
	*/
	constructor($pos) {
		let node = $pos.nodeAfter;
		let $end = $pos.node(0).resolve($pos.pos + node.nodeSize);
		super($pos, $end);
		this.node = node;
	}
	map(doc, mapping) {
		let { deleted, pos } = mapping.mapResult(this.anchor);
		let $pos = doc.resolve(pos);
		if (deleted) return Selection$1.near($pos);
		return new NodeSelection($pos);
	}
	content() {
		return new Slice(Fragment$8.from(this.node), 0, 0);
	}
	eq(other) {
		return other instanceof NodeSelection && other.anchor == this.anchor;
	}
	toJSON() {
		return {
			type: "node",
			anchor: this.anchor
		};
	}
	getBookmark() {
		return new NodeBookmark(this.anchor);
	}
	/**
	@internal
	*/
	static fromJSON(doc, json) {
		if (typeof json.anchor != "number") throw new RangeError("Invalid input for NodeSelection.fromJSON");
		return new NodeSelection(doc.resolve(json.anchor));
	}
	/**
	Create a node selection from non-resolved positions.
	*/
	static create(doc, from) {
		return new NodeSelection(doc.resolve(from));
	}
	/**
	Determines whether the given node may be selected as a node
	selection.
	*/
	static isSelectable(node) {
		return !node.isText && node.type.spec.selectable !== false;
	}
};
NodeSelection.prototype.visible = false;
Selection$1.jsonID("node", NodeSelection);
var NodeBookmark = class NodeBookmark {
	constructor(anchor) {
		this.anchor = anchor;
	}
	map(mapping) {
		let { deleted, pos } = mapping.mapResult(this.anchor);
		return deleted ? new TextBookmark(pos, pos) : new NodeBookmark(pos);
	}
	resolve(doc) {
		let $pos = doc.resolve(this.anchor), node = $pos.nodeAfter;
		if (node && NodeSelection.isSelectable(node)) return new NodeSelection($pos);
		return Selection$1.near($pos);
	}
};
/**
A selection type that represents selecting the whole document
(which can not necessarily be expressed with a text selection, when
there are for example leaf block nodes at the start or end of the
document).
*/
var AllSelection = class AllSelection extends Selection$1 {
	/**
	Create an all-selection over the given document.
	*/
	constructor(doc) {
		super(doc.resolve(0), doc.resolve(doc.content.size));
	}
	replace(tr, content = Slice.empty) {
		if (content == Slice.empty) {
			tr.delete(0, tr.doc.content.size);
			let sel = Selection$1.atStart(tr.doc);
			if (!sel.eq(tr.selection)) tr.setSelection(sel);
		} else super.replace(tr, content);
	}
	toJSON() {
		return { type: "all" };
	}
	/**
	@internal
	*/
	static fromJSON(doc) {
		return new AllSelection(doc);
	}
	map(doc) {
		return new AllSelection(doc);
	}
	eq(other) {
		return other instanceof AllSelection;
	}
	getBookmark() {
		return AllBookmark;
	}
};
Selection$1.jsonID("all", AllSelection);
var AllBookmark = {
	map() {
		return this;
	},
	resolve(doc) {
		return new AllSelection(doc);
	}
};
function findSelectionIn(doc, node, pos, index, dir, text = false) {
	if (node.inlineContent) return TextSelection.create(doc, pos);
	for (let i = index - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) {
		let child = node.child(i);
		if (!child.isAtom) {
			let inner = findSelectionIn(doc, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text);
			if (inner) return inner;
		} else if (!text && NodeSelection.isSelectable(child)) return NodeSelection.create(doc, pos - (dir < 0 ? child.nodeSize : 0));
		pos += child.nodeSize * dir;
	}
	return null;
}
function selectionToInsertionEnd$1(tr, startLen, bias) {
	let last = tr.steps.length - 1;
	if (last < startLen) return;
	let step = tr.steps[last];
	if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return;
	let map = tr.mapping.maps[last], end;
	map.forEach((_from, _to, _newFrom, newTo) => {
		if (end == null) end = newTo;
	});
	tr.setSelection(Selection$1.near(tr.doc.resolve(end), bias));
}
var UPDATED_SEL = 1;
var UPDATED_MARKS = 2;
var UPDATED_SCROLL = 4;
/**
An editor state transaction, which can be applied to a state to
create an updated state. Use
[`EditorState.tr`](https://prosemirror.net/docs/ref/#state.EditorState.tr) to create an instance.

Transactions track changes to the document (they are a subclass of
[`Transform`](https://prosemirror.net/docs/ref/#transform.Transform)), but also other state changes,
like selection updates and adjustments of the set of [stored
marks](https://prosemirror.net/docs/ref/#state.EditorState.storedMarks). In addition, you can store
metadata properties in a transaction, which are extra pieces of
information that client code or plugins can use to describe what a
transaction represents, so that they can update their [own
state](https://prosemirror.net/docs/ref/#state.StateField) accordingly.

The [editor view](https://prosemirror.net/docs/ref/#view.EditorView) uses a few metadata
properties: it will attach a property `"pointer"` with the value
`true` to selection transactions directly caused by mouse or touch
input, a `"composition"` property holding an ID identifying the
composition that caused it to transactions caused by composed DOM
input, and a `"uiEvent"` property of that may be `"paste"`,
`"cut"`, or `"drop"`.
*/
var Transaction = class extends Transform {
	/**
	@internal
	*/
	constructor(state) {
		super(state.doc);
		this.curSelectionFor = 0;
		this.updated = 0;
		this.meta = Object.create(null);
		this.time = Date.now();
		this.curSelection = state.selection;
		this.storedMarks = state.storedMarks;
	}
	/**
	The transaction's current selection. This defaults to the editor
	selection [mapped](https://prosemirror.net/docs/ref/#state.Selection.map) through the steps in the
	transaction, but can be overwritten with
	[`setSelection`](https://prosemirror.net/docs/ref/#state.Transaction.setSelection).
	*/
	get selection() {
		if (this.curSelectionFor < this.steps.length) {
			this.curSelection = this.curSelection.map(this.doc, this.mapping.slice(this.curSelectionFor));
			this.curSelectionFor = this.steps.length;
		}
		return this.curSelection;
	}
	/**
	Update the transaction's current selection. Will determine the
	selection that the editor gets when the transaction is applied.
	*/
	setSelection(selection) {
		if (selection.$from.doc != this.doc) throw new RangeError("Selection passed to setSelection must point at the current document");
		this.curSelection = selection;
		this.curSelectionFor = this.steps.length;
		this.updated = (this.updated | UPDATED_SEL) & -3;
		this.storedMarks = null;
		return this;
	}
	/**
	Whether the selection was explicitly updated by this transaction.
	*/
	get selectionSet() {
		return (this.updated & UPDATED_SEL) > 0;
	}
	/**
	Set the current stored marks.
	*/
	setStoredMarks(marks) {
		this.storedMarks = marks;
		this.updated |= UPDATED_MARKS;
		return this;
	}
	/**
	Make sure the current stored marks or, if that is null, the marks
	at the selection, match the given set of marks. Does nothing if
	this is already the case.
	*/
	ensureMarks(marks) {
		if (!Mark$1.sameSet(this.storedMarks || this.selection.$from.marks(), marks)) this.setStoredMarks(marks);
		return this;
	}
	/**
	Add a mark to the set of stored marks.
	*/
	addStoredMark(mark) {
		return this.ensureMarks(mark.addToSet(this.storedMarks || this.selection.$head.marks()));
	}
	/**
	Remove a mark or mark type from the set of stored marks.
	*/
	removeStoredMark(mark) {
		return this.ensureMarks(mark.removeFromSet(this.storedMarks || this.selection.$head.marks()));
	}
	/**
	Whether the stored marks were explicitly set for this transaction.
	*/
	get storedMarksSet() {
		return (this.updated & UPDATED_MARKS) > 0;
	}
	/**
	@internal
	*/
	addStep(step, doc) {
		super.addStep(step, doc);
		this.updated = this.updated & -3;
		this.storedMarks = null;
	}
	/**
	Update the timestamp for the transaction.
	*/
	setTime(time) {
		this.time = time;
		return this;
	}
	/**
	Replace the current selection with the given slice.
	*/
	replaceSelection(slice) {
		this.selection.replace(this, slice);
		return this;
	}
	/**
	Replace the selection with the given node. When `inheritMarks` is
	true and the content is inline, it inherits the marks from the
	place where it is inserted.
	*/
	replaceSelectionWith(node, inheritMarks = true) {
		let selection = this.selection;
		if (inheritMarks) node = node.mark(this.storedMarks || (selection.empty ? selection.$from.marks() : selection.$from.marksAcross(selection.$to) || Mark$1.none));
		selection.replaceWith(this, node);
		return this;
	}
	/**
	Delete the selection.
	*/
	deleteSelection() {
		this.selection.replace(this);
		return this;
	}
	/**
	Replace the given range, or the selection if no range is given,
	with a text node containing the given string.
	*/
	insertText(text, from, to) {
		let schema = this.doc.type.schema;
		if (from == null) {
			if (!text) return this.deleteSelection();
			return this.replaceSelectionWith(schema.text(text), true);
		} else {
			if (to == null) to = from;
			if (!text) return this.deleteRange(from, to);
			let marks = this.storedMarks;
			if (!marks) {
				let $from = this.doc.resolve(from);
				marks = to == from ? $from.marks() : $from.marksAcross(this.doc.resolve(to));
			}
			this.replaceRangeWith(from, to, schema.text(text, marks));
			if (!this.selection.empty && this.selection.to == from + text.length) this.setSelection(Selection$1.near(this.selection.$to));
			return this;
		}
	}
	/**
	Store a metadata property in this transaction, keyed either by
	name or by plugin.
	*/
	setMeta(key, value) {
		this.meta[typeof key == "string" ? key : key.key] = value;
		return this;
	}
	/**
	Retrieve a metadata property for a given name or plugin.
	*/
	getMeta(key) {
		return this.meta[typeof key == "string" ? key : key.key];
	}
	/**
	Returns true if this transaction doesn't contain any metadata,
	and can thus safely be extended.
	*/
	get isGeneric() {
		for (let _ in this.meta) return false;
		return true;
	}
	/**
	Indicate that the editor should scroll the selection into view
	when updated to the state produced by this transaction.
	*/
	scrollIntoView() {
		this.updated |= UPDATED_SCROLL;
		return this;
	}
	/**
	True when this transaction has had `scrollIntoView` called on it.
	*/
	get scrolledIntoView() {
		return (this.updated & UPDATED_SCROLL) > 0;
	}
};
function bind(f, self) {
	return !self || !f ? f : f.bind(self);
}
var FieldDesc = class {
	constructor(name, desc, self) {
		this.name = name;
		this.init = bind(desc.init, self);
		this.apply = bind(desc.apply, self);
	}
};
var baseFields = [
	new FieldDesc("doc", {
		init(config) {
			return config.doc || config.schema.topNodeType.createAndFill();
		},
		apply(tr) {
			return tr.doc;
		}
	}),
	new FieldDesc("selection", {
		init(config, instance) {
			return config.selection || Selection$1.atStart(instance.doc);
		},
		apply(tr) {
			return tr.selection;
		}
	}),
	new FieldDesc("storedMarks", {
		init(config) {
			return config.storedMarks || null;
		},
		apply(tr, _marks, _old, state) {
			return state.selection.$cursor ? tr.storedMarks : null;
		}
	}),
	new FieldDesc("scrollToSelection", {
		init() {
			return 0;
		},
		apply(tr, prev) {
			return tr.scrolledIntoView ? prev + 1 : prev;
		}
	})
];
var Configuration = class {
	constructor(schema, plugins) {
		this.schema = schema;
		this.plugins = [];
		this.pluginsByKey = Object.create(null);
		this.fields = baseFields.slice();
		if (plugins) plugins.forEach((plugin) => {
			if (this.pluginsByKey[plugin.key]) throw new RangeError("Adding different instances of a keyed plugin (" + plugin.key + ")");
			this.plugins.push(plugin);
			this.pluginsByKey[plugin.key] = plugin;
			if (plugin.spec.state) this.fields.push(new FieldDesc(plugin.key, plugin.spec.state, plugin));
		});
	}
};
/**
The state of a ProseMirror editor is represented by an object of
this type. A state is a persistent data structure—it isn't
updated, but rather a new state value is computed from an old one
using the [`apply`](https://prosemirror.net/docs/ref/#state.EditorState.apply) method.

A state holds a number of built-in fields, and plugins can
[define](https://prosemirror.net/docs/ref/#state.PluginSpec.state) additional fields.
*/
var EditorState = class EditorState {
	/**
	@internal
	*/
	constructor(config) {
		this.config = config;
	}
	/**
	The schema of the state's document.
	*/
	get schema() {
		return this.config.schema;
	}
	/**
	The plugins that are active in this state.
	*/
	get plugins() {
		return this.config.plugins;
	}
	/**
	Apply the given transaction to produce a new state.
	*/
	apply(tr) {
		return this.applyTransaction(tr).state;
	}
	/**
	@internal
	*/
	filterTransaction(tr, ignore = -1) {
		for (let i = 0; i < this.config.plugins.length; i++) if (i != ignore) {
			let plugin = this.config.plugins[i];
			if (plugin.spec.filterTransaction && !plugin.spec.filterTransaction.call(plugin, tr, this)) return false;
		}
		return true;
	}
	/**
	Verbose variant of [`apply`](https://prosemirror.net/docs/ref/#state.EditorState.apply) that
	returns the precise transactions that were applied (which might
	be influenced by the [transaction
	hooks](https://prosemirror.net/docs/ref/#state.PluginSpec.filterTransaction) of
	plugins) along with the new state.
	*/
	applyTransaction(rootTr) {
		if (!this.filterTransaction(rootTr)) return {
			state: this,
			transactions: []
		};
		let trs = [rootTr], newState = this.applyInner(rootTr), seen = null;
		for (;;) {
			let haveNew = false;
			for (let i = 0; i < this.config.plugins.length; i++) {
				let plugin = this.config.plugins[i];
				if (plugin.spec.appendTransaction) {
					let n = seen ? seen[i].n : 0, oldState = seen ? seen[i].state : this;
					let tr = n < trs.length && plugin.spec.appendTransaction.call(plugin, n ? trs.slice(n) : trs, oldState, newState);
					if (tr && newState.filterTransaction(tr, i)) {
						tr.setMeta("appendedTransaction", rootTr);
						if (!seen) {
							seen = [];
							for (let j = 0; j < this.config.plugins.length; j++) seen.push(j < i ? {
								state: newState,
								n: trs.length
							} : {
								state: this,
								n: 0
							});
						}
						trs.push(tr);
						newState = newState.applyInner(tr);
						haveNew = true;
					}
					if (seen) seen[i] = {
						state: newState,
						n: trs.length
					};
				}
			}
			if (!haveNew) return {
				state: newState,
				transactions: trs
			};
		}
	}
	/**
	@internal
	*/
	applyInner(tr) {
		if (!tr.before.eq(this.doc)) throw new RangeError("Applying a mismatched transaction");
		let newInstance = new EditorState(this.config), fields = this.config.fields;
		for (let i = 0; i < fields.length; i++) {
			let field = fields[i];
			newInstance[field.name] = field.apply(tr, this[field.name], this, newInstance);
		}
		return newInstance;
	}
	/**
	Accessor that constructs and returns a new [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
	*/
	get tr() {
		return new Transaction(this);
	}
	/**
	Create a new state.
	*/
	static create(config) {
		let $config = new Configuration(config.doc ? config.doc.type.schema : config.schema, config.plugins);
		let instance = new EditorState($config);
		for (let i = 0; i < $config.fields.length; i++) instance[$config.fields[i].name] = $config.fields[i].init(config, instance);
		return instance;
	}
	/**
	Create a new state based on this one, but with an adjusted set
	of active plugins. State fields that exist in both sets of
	plugins are kept unchanged. Those that no longer exist are
	dropped, and those that are new are initialized using their
	[`init`](https://prosemirror.net/docs/ref/#state.StateField.init) method, passing in the new
	configuration object..
	*/
	reconfigure(config) {
		let $config = new Configuration(this.schema, config.plugins);
		let fields = $config.fields, instance = new EditorState($config);
		for (let i = 0; i < fields.length; i++) {
			let name = fields[i].name;
			instance[name] = this.hasOwnProperty(name) ? this[name] : fields[i].init(config, instance);
		}
		return instance;
	}
	/**
	Serialize this state to JSON. If you want to serialize the state
	of plugins, pass an object mapping property names to use in the
	resulting JSON object to plugin objects. The argument may also be
	a string or number, in which case it is ignored, to support the
	way `JSON.stringify` calls `toString` methods.
	*/
	toJSON(pluginFields) {
		let result = {
			doc: this.doc.toJSON(),
			selection: this.selection.toJSON()
		};
		if (this.storedMarks) result.storedMarks = this.storedMarks.map((m) => m.toJSON());
		if (pluginFields && typeof pluginFields == "object") for (let prop in pluginFields) {
			if (prop == "doc" || prop == "selection") throw new RangeError("The JSON fields `doc` and `selection` are reserved");
			let plugin = pluginFields[prop], state = plugin.spec.state;
			if (state && state.toJSON) result[prop] = state.toJSON.call(plugin, this[plugin.key]);
		}
		return result;
	}
	/**
	Deserialize a JSON representation of a state. `config` should
	have at least a `schema` field, and should contain array of
	plugins to initialize the state with. `pluginFields` can be used
	to deserialize the state of plugins, by associating plugin
	instances with the property names they use in the JSON object.
	*/
	static fromJSON(config, json, pluginFields) {
		if (!json) throw new RangeError("Invalid input for EditorState.fromJSON");
		if (!config.schema) throw new RangeError("Required config field 'schema' missing");
		let $config = new Configuration(config.schema, config.plugins);
		let instance = new EditorState($config);
		$config.fields.forEach((field) => {
			if (field.name == "doc") instance.doc = Node$1.fromJSON(config.schema, json.doc);
			else if (field.name == "selection") instance.selection = Selection$1.fromJSON(instance.doc, json.selection);
			else if (field.name == "storedMarks") {
				if (json.storedMarks) instance.storedMarks = json.storedMarks.map(config.schema.markFromJSON);
			} else {
				if (pluginFields) for (let prop in pluginFields) {
					let plugin = pluginFields[prop], state = plugin.spec.state;
					if (plugin.key == field.name && state && state.fromJSON && Object.prototype.hasOwnProperty.call(json, prop)) {
						instance[field.name] = state.fromJSON.call(plugin, config, json[prop], instance);
						return;
					}
				}
				instance[field.name] = field.init(config, instance);
			}
		});
		return instance;
	}
};
function bindProps(obj, self, target) {
	for (let prop in obj) {
		let val = obj[prop];
		if (val instanceof Function) val = val.bind(self);
		else if (prop == "handleDOMEvents") val = bindProps(val, self, {});
		target[prop] = val;
	}
	return target;
}
/**
Plugins bundle functionality that can be added to an editor.
They are part of the [editor state](https://prosemirror.net/docs/ref/#state.EditorState) and
may influence that state and the view that contains it.
*/
var Plugin = class {
	/**
	Create a plugin.
	*/
	constructor(spec) {
		this.spec = spec;
		/**
		The [props](https://prosemirror.net/docs/ref/#view.EditorProps) exported by this plugin.
		*/
		this.props = {};
		if (spec.props) bindProps(spec.props, this, this.props);
		this.key = spec.key ? spec.key.key : createKey("plugin");
	}
	/**
	Extract the plugin's state field from an editor state.
	*/
	getState(state) {
		return state[this.key];
	}
};
var keys$1 = Object.create(null);
function createKey(name) {
	if (name in keys$1) return name + "$" + ++keys$1[name];
	keys$1[name] = 0;
	return name + "$";
}
/**
A key is used to [tag](https://prosemirror.net/docs/ref/#state.PluginSpec.key) plugins in a way
that makes it possible to find them, given an editor state.
Assigning a key does mean only one plugin of that type can be
active in a state.
*/
var PluginKey = class {
	/**
	Create a plugin key.
	*/
	constructor(name = "key") {
		this.key = createKey(name);
	}
	/**
	Get the active plugin with this key, if any, from an editor
	state.
	*/
	get(state) {
		return state.config.pluginsByKey[this.key];
	}
	/**
	Get the plugin's state from an editor state.
	*/
	getState(state) {
		return state[this.key];
	}
};
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-commands@1.7.1/node_modules/prosemirror-commands/dist/index.js
/**
Delete the selection, if there is one.
*/
var deleteSelection$1 = (state, dispatch) => {
	if (state.selection.empty) return false;
	if (dispatch) dispatch(state.tr.deleteSelection().scrollIntoView());
	return true;
};
function atBlockStart(state, view) {
	let { $cursor } = state.selection;
	if (!$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)) return null;
	return $cursor;
}
/**
If the selection is empty and at the start of a textblock, try to
reduce the distance between that block and the one before it—if
there's a block directly before it that can be joined, join them.
If not, try to move the selected block closer to the next one in
the document structure by lifting it out of its parent or moving it
into a parent of the previous block. Will use the view for accurate
(bidi-aware) start-of-textblock detection if given.
*/
var joinBackward$1 = (state, dispatch, view) => {
	let $cursor = atBlockStart(state, view);
	if (!$cursor) return false;
	let $cut = findCutBefore($cursor);
	if (!$cut) {
		let range = $cursor.blockRange(), target = range && liftTarget(range);
		if (target == null) return false;
		if (dispatch) dispatch(state.tr.lift(range, target).scrollIntoView());
		return true;
	}
	let before = $cut.nodeBefore;
	if (deleteBarrier(state, $cut, dispatch, -1)) return true;
	if ($cursor.parent.content.size == 0 && (textblockAt(before, "end") || NodeSelection.isSelectable(before))) for (let depth = $cursor.depth;; depth--) {
		let delStep = replaceStep(state.doc, $cursor.before(depth), $cursor.after(depth), Slice.empty);
		if (delStep && delStep.slice.size < delStep.to - delStep.from) {
			if (dispatch) {
				let tr = state.tr.step(delStep);
				tr.setSelection(textblockAt(before, "end") ? Selection$1.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos, -1)), -1) : NodeSelection.create(tr.doc, $cut.pos - before.nodeSize));
				dispatch(tr.scrollIntoView());
			}
			return true;
		}
		if (depth == 1 || $cursor.node(depth - 1).childCount > 1) break;
	}
	if (before.isAtom && $cut.depth == $cursor.depth - 1) {
		if (dispatch) dispatch(state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView());
		return true;
	}
	return false;
};
/**
A more limited form of [`joinBackward`](https://prosemirror.net/docs/ref/#commands.joinBackward)
that only tries to join the current textblock to the one before
it, if the cursor is at the start of a textblock.
*/
var joinTextblockBackward$1 = (state, dispatch, view) => {
	let $cursor = atBlockStart(state, view);
	if (!$cursor) return false;
	let $cut = findCutBefore($cursor);
	return $cut ? joinTextblocksAround(state, $cut, dispatch) : false;
};
/**
A more limited form of [`joinForward`](https://prosemirror.net/docs/ref/#commands.joinForward)
that only tries to join the current textblock to the one after
it, if the cursor is at the end of a textblock.
*/
var joinTextblockForward$1 = (state, dispatch, view) => {
	let $cursor = atBlockEnd(state, view);
	if (!$cursor) return false;
	let $cut = findCutAfter($cursor);
	return $cut ? joinTextblocksAround(state, $cut, dispatch) : false;
};
function joinTextblocksAround(state, $cut, dispatch) {
	let beforeText = $cut.nodeBefore, beforePos = $cut.pos - 1;
	for (; !beforeText.isTextblock; beforePos--) {
		if (beforeText.type.spec.isolating) return false;
		let child = beforeText.lastChild;
		if (!child) return false;
		beforeText = child;
	}
	let afterText = $cut.nodeAfter, afterPos = $cut.pos + 1;
	for (; !afterText.isTextblock; afterPos++) {
		if (afterText.type.spec.isolating) return false;
		let child = afterText.firstChild;
		if (!child) return false;
		afterText = child;
	}
	let step = replaceStep(state.doc, beforePos, afterPos, Slice.empty);
	if (!step || step.from != beforePos || step instanceof ReplaceStep && step.slice.size >= afterPos - beforePos) return false;
	if (dispatch) {
		let tr = state.tr.step(step);
		tr.setSelection(TextSelection.create(tr.doc, beforePos));
		dispatch(tr.scrollIntoView());
	}
	return true;
}
function textblockAt(node, side, only = false) {
	for (let scan = node; scan; scan = side == "start" ? scan.firstChild : scan.lastChild) {
		if (scan.isTextblock) return true;
		if (only && scan.childCount != 1) return false;
	}
	return false;
}
/**
When the selection is empty and at the start of a textblock, select
the node before that textblock, if possible. This is intended to be
bound to keys like backspace, after
[`joinBackward`](https://prosemirror.net/docs/ref/#commands.joinBackward) or other deleting
commands, as a fall-back behavior when the schema doesn't allow
deletion at the selected point.
*/
var selectNodeBackward$1 = (state, dispatch, view) => {
	let { $head, empty } = state.selection, $cut = $head;
	if (!empty) return false;
	if ($head.parent.isTextblock) {
		if (view ? !view.endOfTextblock("backward", state) : $head.parentOffset > 0) return false;
		$cut = findCutBefore($head);
	}
	let node = $cut && $cut.nodeBefore;
	if (!node || !NodeSelection.isSelectable(node)) return false;
	if (dispatch) dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos - node.nodeSize)).scrollIntoView());
	return true;
};
function findCutBefore($pos) {
	if (!$pos.parent.type.spec.isolating) for (let i = $pos.depth - 1; i >= 0; i--) {
		if ($pos.index(i) > 0) return $pos.doc.resolve($pos.before(i + 1));
		if ($pos.node(i).type.spec.isolating) break;
	}
	return null;
}
function atBlockEnd(state, view) {
	let { $cursor } = state.selection;
	if (!$cursor || (view ? !view.endOfTextblock("forward", state) : $cursor.parentOffset < $cursor.parent.content.size)) return null;
	return $cursor;
}
/**
If the selection is empty and the cursor is at the end of a
textblock, try to reduce or remove the boundary between that block
and the one after it, either by joining them or by moving the other
block closer to this one in the tree structure. Will use the view
for accurate start-of-textblock detection if given.
*/
var joinForward$1 = (state, dispatch, view) => {
	let $cursor = atBlockEnd(state, view);
	if (!$cursor) return false;
	let $cut = findCutAfter($cursor);
	if (!$cut) return false;
	let after = $cut.nodeAfter;
	if (deleteBarrier(state, $cut, dispatch, 1)) return true;
	if ($cursor.parent.content.size == 0 && (textblockAt(after, "start") || NodeSelection.isSelectable(after))) {
		let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty);
		if (delStep && delStep.slice.size < delStep.to - delStep.from) {
			if (dispatch) {
				let tr = state.tr.step(delStep);
				tr.setSelection(textblockAt(after, "start") ? Selection$1.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos)), 1) : NodeSelection.create(tr.doc, tr.mapping.map($cut.pos)));
				dispatch(tr.scrollIntoView());
			}
			return true;
		}
	}
	if (after.isAtom && $cut.depth == $cursor.depth - 1) {
		if (dispatch) dispatch(state.tr.delete($cut.pos, $cut.pos + after.nodeSize).scrollIntoView());
		return true;
	}
	return false;
};
/**
When the selection is empty and at the end of a textblock, select
the node coming after that textblock, if possible. This is intended
to be bound to keys like delete, after
[`joinForward`](https://prosemirror.net/docs/ref/#commands.joinForward) and similar deleting
commands, to provide a fall-back behavior when the schema doesn't
allow deletion at the selected point.
*/
var selectNodeForward$1 = (state, dispatch, view) => {
	let { $head, empty } = state.selection, $cut = $head;
	if (!empty) return false;
	if ($head.parent.isTextblock) {
		if (view ? !view.endOfTextblock("forward", state) : $head.parentOffset < $head.parent.content.size) return false;
		$cut = findCutAfter($head);
	}
	let node = $cut && $cut.nodeAfter;
	if (!node || !NodeSelection.isSelectable(node)) return false;
	if (dispatch) dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos)).scrollIntoView());
	return true;
};
function findCutAfter($pos) {
	if (!$pos.parent.type.spec.isolating) for (let i = $pos.depth - 1; i >= 0; i--) {
		let parent = $pos.node(i);
		if ($pos.index(i) + 1 < parent.childCount) return $pos.doc.resolve($pos.after(i + 1));
		if (parent.type.spec.isolating) break;
	}
	return null;
}
/**
Join the selected block or, if there is a text selection, the
closest ancestor block of the selection that can be joined, with
the sibling above it.
*/
var joinUp$1 = (state, dispatch) => {
	let sel = state.selection, nodeSel = sel instanceof NodeSelection, point;
	if (nodeSel) {
		if (sel.node.isTextblock || !canJoin(state.doc, sel.from)) return false;
		point = sel.from;
	} else {
		point = joinPoint(state.doc, sel.from, -1);
		if (point == null) return false;
	}
	if (dispatch) {
		let tr = state.tr.join(point);
		if (nodeSel) tr.setSelection(NodeSelection.create(tr.doc, point - state.doc.resolve(point).nodeBefore.nodeSize));
		dispatch(tr.scrollIntoView());
	}
	return true;
};
/**
Join the selected block, or the closest ancestor of the selection
that can be joined, with the sibling after it.
*/
var joinDown$1 = (state, dispatch) => {
	let sel = state.selection, point;
	if (sel instanceof NodeSelection) {
		if (sel.node.isTextblock || !canJoin(state.doc, sel.to)) return false;
		point = sel.to;
	} else {
		point = joinPoint(state.doc, sel.to, 1);
		if (point == null) return false;
	}
	if (dispatch) dispatch(state.tr.join(point).scrollIntoView());
	return true;
};
/**
Lift the selected block, or the closest ancestor block of the
selection that can be lifted, out of its parent node.
*/
var lift$1 = (state, dispatch) => {
	let { $from, $to } = state.selection;
	let range = $from.blockRange($to), target = range && liftTarget(range);
	if (target == null) return false;
	if (dispatch) dispatch(state.tr.lift(range, target).scrollIntoView());
	return true;
};
/**
If the selection is in a node whose type has a truthy
[`code`](https://prosemirror.net/docs/ref/#model.NodeSpec.code) property in its spec, replace the
selection with a newline character.
*/
var newlineInCode$1 = (state, dispatch) => {
	let { $head, $anchor } = state.selection;
	if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) return false;
	if (dispatch) dispatch(state.tr.insertText("\n").scrollIntoView());
	return true;
};
function defaultBlockAt$1(match) {
	for (let i = 0; i < match.edgeCount; i++) {
		let { type } = match.edge(i);
		if (type.isTextblock && !type.hasRequiredAttrs()) return type;
	}
	return null;
}
/**
When the selection is in a node with a truthy
[`code`](https://prosemirror.net/docs/ref/#model.NodeSpec.code) property in its spec, create a
default block after the code block, and move the cursor there.
*/
var exitCode$1 = (state, dispatch) => {
	let { $head, $anchor } = state.selection;
	if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) return false;
	let above = $head.node(-1), after = $head.indexAfter(-1), type = defaultBlockAt$1(above.contentMatchAt(after));
	if (!type || !above.canReplaceWith(after, after, type)) return false;
	if (dispatch) {
		let pos = $head.after(), tr = state.tr.replaceWith(pos, pos, type.createAndFill());
		tr.setSelection(Selection$1.near(tr.doc.resolve(pos), 1));
		dispatch(tr.scrollIntoView());
	}
	return true;
};
/**
If a block node is selected, create an empty paragraph before (if
it is its parent's first child) or after it.
*/
var createParagraphNear$1 = (state, dispatch) => {
	let sel = state.selection, { $from, $to } = sel;
	if (sel instanceof AllSelection || $from.parent.inlineContent || $to.parent.inlineContent) return false;
	let type = defaultBlockAt$1($to.parent.contentMatchAt($to.indexAfter()));
	if (!type || !type.isTextblock) return false;
	if (dispatch) {
		let side = (!$from.parentOffset && $to.index() < $to.parent.childCount ? $from : $to).pos;
		let tr = state.tr.insert(side, type.createAndFill());
		tr.setSelection(TextSelection.create(tr.doc, side + 1));
		dispatch(tr.scrollIntoView());
	}
	return true;
};
/**
If the cursor is in an empty textblock that can be lifted, lift the
block.
*/
var liftEmptyBlock$1 = (state, dispatch) => {
	let { $cursor } = state.selection;
	if (!$cursor || $cursor.parent.content.size) return false;
	if ($cursor.depth > 1 && $cursor.after() != $cursor.end(-1)) {
		let before = $cursor.before();
		if (canSplit(state.doc, before)) {
			if (dispatch) dispatch(state.tr.split(before).scrollIntoView());
			return true;
		}
	}
	let range = $cursor.blockRange(), target = range && liftTarget(range);
	if (target == null) return false;
	if (dispatch) dispatch(state.tr.lift(range, target).scrollIntoView());
	return true;
};
/**
Create a variant of [`splitBlock`](https://prosemirror.net/docs/ref/#commands.splitBlock) that uses
a custom function to determine the type of the newly split off block.
*/
function splitBlockAs(splitNode) {
	return (state, dispatch) => {
		let { $from, $to } = state.selection;
		if (state.selection instanceof NodeSelection && state.selection.node.isBlock) {
			if (!$from.parentOffset || !canSplit(state.doc, $from.pos)) return false;
			if (dispatch) dispatch(state.tr.split($from.pos).scrollIntoView());
			return true;
		}
		if (!$from.depth) return false;
		let types = [];
		let splitDepth, deflt, atEnd = false, atStart = false;
		for (let d = $from.depth;; d--) if ($from.node(d).isBlock) {
			atEnd = $from.end(d) == $from.pos + ($from.depth - d);
			atStart = $from.start(d) == $from.pos - ($from.depth - d);
			deflt = defaultBlockAt$1($from.node(d - 1).contentMatchAt($from.indexAfter(d - 1)));
			let splitType = splitNode && splitNode($to.parent, atEnd, $from);
			types.unshift(splitType || (atEnd && deflt ? { type: deflt } : null));
			splitDepth = d;
			break;
		} else {
			if (d == 1) return false;
			types.unshift(null);
		}
		let tr = state.tr;
		if (state.selection instanceof TextSelection || state.selection instanceof AllSelection) tr.deleteSelection();
		let splitPos = tr.mapping.map($from.pos);
		let can = canSplit(tr.doc, splitPos, types.length, types);
		if (!can) {
			types[0] = deflt ? { type: deflt } : null;
			can = canSplit(tr.doc, splitPos, types.length, types);
		}
		if (!can) return false;
		tr.split(splitPos, types.length, types);
		if (!atEnd && atStart && $from.node(splitDepth).type != deflt) {
			let first = tr.mapping.map($from.before(splitDepth)), $first = tr.doc.resolve(first);
			if (deflt && $from.node(splitDepth - 1).canReplaceWith($first.index(), $first.index() + 1, deflt)) tr.setNodeMarkup(tr.mapping.map($from.before(splitDepth)), deflt);
		}
		if (dispatch) dispatch(tr.scrollIntoView());
		return true;
	};
}
/**
Split the parent block of the selection. If the selection is a text
selection, also delete its content.
*/
var splitBlock$1 = splitBlockAs();
/**
Move the selection to the node wrapping the current selection, if
any. (Will not select the document node.)
*/
var selectParentNode$1 = (state, dispatch) => {
	let { $from, to } = state.selection, pos;
	let same = $from.sharedDepth(to);
	if (same == 0) return false;
	pos = $from.before(same);
	if (dispatch) dispatch(state.tr.setSelection(NodeSelection.create(state.doc, pos)));
	return true;
};
/**
Select the whole document.
*/
var selectAll$1 = (state, dispatch) => {
	if (dispatch) dispatch(state.tr.setSelection(new AllSelection(state.doc)));
	return true;
};
function joinMaybeClear(state, $pos, dispatch) {
	let before = $pos.nodeBefore, after = $pos.nodeAfter, index = $pos.index();
	if (!before || !after || !before.type.compatibleContent(after.type)) return false;
	if (!before.content.size && $pos.parent.canReplace(index - 1, index)) {
		if (dispatch) dispatch(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView());
		return true;
	}
	if (!$pos.parent.canReplace(index, index + 1) || !(after.isTextblock || canJoin(state.doc, $pos.pos))) return false;
	if (dispatch) dispatch(state.tr.join($pos.pos).scrollIntoView());
	return true;
}
function deleteBarrier(state, $cut, dispatch, dir) {
	let before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match;
	let isolated = before.type.spec.isolating || after.type.spec.isolating;
	if (!isolated && joinMaybeClear(state, $cut, dispatch)) return true;
	let canDelAfter = !isolated && $cut.parent.canReplace($cut.index(), $cut.index() + 1);
	if (canDelAfter && (conn = (match = before.contentMatchAt(before.childCount)).findWrapping(after.type)) && match.matchType(conn[0] || after.type).validEnd) {
		if (dispatch) {
			let end = $cut.pos + after.nodeSize, wrap = Fragment$8.empty;
			for (let i = conn.length - 1; i >= 0; i--) wrap = Fragment$8.from(conn[i].create(null, wrap));
			wrap = Fragment$8.from(before.copy(wrap));
			let tr = state.tr.step(new ReplaceAroundStep($cut.pos - 1, end, $cut.pos, end, new Slice(wrap, 1, 0), conn.length, true));
			let $joinAt = tr.doc.resolve(end + 2 * conn.length);
			if ($joinAt.nodeAfter && $joinAt.nodeAfter.type == before.type && canJoin(tr.doc, $joinAt.pos)) tr.join($joinAt.pos);
			dispatch(tr.scrollIntoView());
		}
		return true;
	}
	let selAfter = after.type.spec.isolating || dir > 0 && isolated ? null : Selection$1.findFrom($cut, 1);
	let range = selAfter && selAfter.$from.blockRange(selAfter.$to), target = range && liftTarget(range);
	if (target != null && target >= $cut.depth) {
		if (dispatch) dispatch(state.tr.lift(range, target).scrollIntoView());
		return true;
	}
	if (canDelAfter && textblockAt(after, "start", true) && textblockAt(before, "end")) {
		let at = before, wrap = [];
		for (;;) {
			wrap.push(at);
			if (at.isTextblock) break;
			at = at.lastChild;
		}
		let afterText = after, afterDepth = 1;
		for (; !afterText.isTextblock; afterText = afterText.firstChild) afterDepth++;
		if (at.canReplace(at.childCount, at.childCount, afterText.content)) {
			if (dispatch) {
				let end = Fragment$8.empty;
				for (let i = wrap.length - 1; i >= 0; i--) end = Fragment$8.from(wrap[i].copy(end));
				dispatch(state.tr.step(new ReplaceAroundStep($cut.pos - wrap.length, $cut.pos + after.nodeSize, $cut.pos + afterDepth, $cut.pos + after.nodeSize - afterDepth, new Slice(end, wrap.length, 0), 0, true)).scrollIntoView());
			}
			return true;
		}
	}
	return false;
}
function selectTextblockSide(side) {
	return function(state, dispatch) {
		let sel = state.selection, $pos = side < 0 ? sel.$from : sel.$to;
		let depth = $pos.depth;
		while ($pos.node(depth).isInline) {
			if (!depth) return false;
			depth--;
		}
		if (!$pos.node(depth).isTextblock) return false;
		if (dispatch) dispatch(state.tr.setSelection(TextSelection.create(state.doc, side < 0 ? $pos.start(depth) : $pos.end(depth))));
		return true;
	};
}
/**
Moves the cursor to the start of current text block.
*/
var selectTextblockStart$1 = selectTextblockSide(-1);
/**
Moves the cursor to the end of current text block.
*/
var selectTextblockEnd$1 = selectTextblockSide(1);
/**
Wrap the selection in a node of the given type with the given
attributes.
*/
function wrapIn$1(nodeType, attrs = null) {
	return function(state, dispatch) {
		let { $from, $to } = state.selection;
		let range = $from.blockRange($to), wrapping = range && findWrapping(range, nodeType, attrs);
		if (!wrapping) return false;
		if (dispatch) dispatch(state.tr.wrap(range, wrapping).scrollIntoView());
		return true;
	};
}
/**
Returns a command that tries to set the selected textblocks to the
given node type with the given attributes.
*/
function setBlockType(nodeType, attrs = null) {
	return function(state, dispatch) {
		let applicable = false;
		for (let i = 0; i < state.selection.ranges.length && !applicable; i++) {
			let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i];
			state.doc.nodesBetween(from, to, (node, pos) => {
				if (applicable) return false;
				if (!node.isTextblock || node.hasMarkup(nodeType, attrs)) return;
				if (node.type == nodeType) applicable = true;
				else {
					let $pos = state.doc.resolve(pos), index = $pos.index();
					applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType);
				}
			});
		}
		if (!applicable) return false;
		if (dispatch) {
			let tr = state.tr;
			for (let i = 0; i < state.selection.ranges.length; i++) {
				let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i];
				tr.setBlockType(from, to, nodeType, attrs);
			}
			dispatch(tr.scrollIntoView());
		}
		return true;
	};
}
/**
Combine a number of command functions into a single function (which
calls them one by one until one returns true).
*/
function chainCommands(...commands) {
	return function(state, dispatch, view) {
		for (let i = 0; i < commands.length; i++) if (commands[i](state, dispatch, view)) return true;
		return false;
	};
}
var backspace = chainCommands(deleteSelection$1, joinBackward$1, selectNodeBackward$1);
var del = chainCommands(deleteSelection$1, joinForward$1, selectNodeForward$1);
/**
A basic keymap containing bindings not specific to any schema.
Binds the following keys (when multiple commands are listed, they
are chained with [`chainCommands`](https://prosemirror.net/docs/ref/#commands.chainCommands)):

* **Enter** to `newlineInCode`, `createParagraphNear`, `liftEmptyBlock`, `splitBlock`
* **Mod-Enter** to `exitCode`
* **Backspace** and **Mod-Backspace** to `deleteSelection`, `joinBackward`, `selectNodeBackward`
* **Delete** and **Mod-Delete** to `deleteSelection`, `joinForward`, `selectNodeForward`
* **Mod-Delete** to `deleteSelection`, `joinForward`, `selectNodeForward`
* **Mod-a** to `selectAll`
*/
var pcBaseKeymap = {
	"Enter": chainCommands(newlineInCode$1, createParagraphNear$1, liftEmptyBlock$1, splitBlock$1),
	"Mod-Enter": exitCode$1,
	"Backspace": backspace,
	"Mod-Backspace": backspace,
	"Shift-Backspace": backspace,
	"Delete": del,
	"Mod-Delete": del,
	"Mod-a": selectAll$1
};
/**
A copy of `pcBaseKeymap` that also binds **Ctrl-h** like Backspace,
**Ctrl-d** like Delete, **Alt-Backspace** like Ctrl-Backspace, and
**Ctrl-Alt-Backspace**, **Alt-Delete**, and **Alt-d** like
Ctrl-Delete.
*/
var macBaseKeymap = {
	"Ctrl-h": pcBaseKeymap["Backspace"],
	"Alt-Backspace": pcBaseKeymap["Mod-Backspace"],
	"Ctrl-d": pcBaseKeymap["Delete"],
	"Ctrl-Alt-Backspace": pcBaseKeymap["Mod-Delete"],
	"Alt-Delete": pcBaseKeymap["Mod-Delete"],
	"Alt-d": pcBaseKeymap["Mod-Delete"],
	"Ctrl-a": selectTextblockStart$1,
	"Ctrl-e": selectTextblockEnd$1
};
for (let key in pcBaseKeymap) macBaseKeymap[key] = pcBaseKeymap[key];
typeof navigator != "undefined" ? /Mac|iP(hone|[oa]d)/.test(navigator.platform) : typeof os != "undefined" && os.platform && os.platform();
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-schema-list@1.5.1/node_modules/prosemirror-schema-list/dist/index.js
/**
Returns a command function that wraps the selection in a list with
the given type an attributes. If `dispatch` is null, only return a
value to indicate whether this is possible, but don't actually
perform the change.
*/
function wrapInList$1(listType, attrs = null) {
	return function(state, dispatch) {
		let { $from, $to } = state.selection;
		let range = $from.blockRange($to);
		if (!range) return false;
		let tr = dispatch ? state.tr : null;
		if (!wrapRangeInList(tr, range, listType, attrs)) return false;
		if (dispatch) dispatch(tr.scrollIntoView());
		return true;
	};
}
/**
Try to wrap the given node range in a list of the given type.
Return `true` when this is possible, `false` otherwise. When `tr`
is non-null, the wrapping is added to that transaction. When it is
`null`, the function only queries whether the wrapping is
possible.
*/
function wrapRangeInList(tr, range, listType, attrs = null) {
	let doJoin = false, outerRange = range, doc = range.$from.doc;
	if (range.depth >= 2 && range.$from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) {
		if (range.$from.index(range.depth - 1) == 0) return false;
		let $insert = doc.resolve(range.start - 2);
		outerRange = new NodeRange($insert, $insert, range.depth);
		if (range.endIndex < range.parent.childCount) range = new NodeRange(range.$from, doc.resolve(range.$to.end(range.depth)), range.depth);
		doJoin = true;
	}
	let wrap = findWrapping(outerRange, listType, attrs, range);
	if (!wrap) return false;
	if (tr) doWrapInList(tr, range, wrap, doJoin, listType);
	return true;
}
function doWrapInList(tr, range, wrappers, joinBefore, listType) {
	let content = Fragment$8.empty;
	for (let i = wrappers.length - 1; i >= 0; i--) content = Fragment$8.from(wrappers[i].type.create(wrappers[i].attrs, content));
	tr.step(new ReplaceAroundStep(range.start - (joinBefore ? 2 : 0), range.end, range.start, range.end, new Slice(content, 0, 0), wrappers.length, true));
	let found = 0;
	for (let i = 0; i < wrappers.length; i++) if (wrappers[i].type == listType) found = i + 1;
	let splitDepth = wrappers.length - found;
	let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0), parent = range.parent;
	for (let i = range.startIndex, e = range.endIndex, first = true; i < e; i++, first = false) {
		if (!first && canSplit(tr.doc, splitPos, splitDepth)) {
			tr.split(splitPos, splitDepth);
			splitPos += 2 * splitDepth;
		}
		splitPos += parent.child(i).nodeSize;
	}
	return tr;
}
/**
Create a command to lift the list item around the selection up into
a wrapping list.
*/
function liftListItem$1(itemType) {
	return function(state, dispatch) {
		let { $from, $to } = state.selection;
		let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType);
		if (!range) return false;
		if (!dispatch) return true;
		if ($from.node(range.depth - 1).type == itemType) return liftToOuterList(state, dispatch, itemType, range);
		else return liftOutOfList(state, dispatch, range);
	};
}
function liftToOuterList(state, dispatch, itemType, range) {
	let tr = state.tr, end = range.end, endOfList = range.$to.end(range.depth);
	if (end < endOfList) {
		tr.step(new ReplaceAroundStep(end - 1, endOfList, end, endOfList, new Slice(Fragment$8.from(itemType.create(null, range.parent.copy())), 1, 0), 1, true));
		range = new NodeRange(tr.doc.resolve(range.$from.pos), tr.doc.resolve(endOfList), range.depth);
	}
	const target = liftTarget(range);
	if (target == null) return false;
	tr.lift(range, target);
	let $after = tr.doc.resolve(tr.mapping.map(end, -1) - 1);
	if (canJoin(tr.doc, $after.pos) && $after.nodeBefore.type == $after.nodeAfter.type) tr.join($after.pos);
	dispatch(tr.scrollIntoView());
	return true;
}
function liftOutOfList(state, dispatch, range) {
	let tr = state.tr, list = range.parent;
	for (let pos = range.end, i = range.endIndex - 1, e = range.startIndex; i > e; i--) {
		pos -= list.child(i).nodeSize;
		tr.delete(pos - 1, pos + 1);
	}
	let $start = tr.doc.resolve(range.start), item = $start.nodeAfter;
	if (tr.mapping.map(range.end) != range.start + $start.nodeAfter.nodeSize) return false;
	let atStart = range.startIndex == 0, atEnd = range.endIndex == list.childCount;
	let parent = $start.node(-1), indexBefore = $start.index(-1);
	if (!parent.canReplace(indexBefore + (atStart ? 0 : 1), indexBefore + 1, item.content.append(atEnd ? Fragment$8.empty : Fragment$8.from(list)))) return false;
	let start = $start.pos, end = start + item.nodeSize;
	tr.step(new ReplaceAroundStep(start - (atStart ? 1 : 0), end + (atEnd ? 1 : 0), start + 1, end - 1, new Slice((atStart ? Fragment$8.empty : Fragment$8.from(list.copy(Fragment$8.empty))).append(atEnd ? Fragment$8.empty : Fragment$8.from(list.copy(Fragment$8.empty))), atStart ? 0 : 1, atEnd ? 0 : 1), atStart ? 0 : 1));
	dispatch(tr.scrollIntoView());
	return true;
}
/**
Create a command to sink the list item around the selection down
into an inner list.
*/
function sinkListItem$1(itemType) {
	return function(state, dispatch) {
		let { $from, $to } = state.selection;
		let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType);
		if (!range) return false;
		let startIndex = range.startIndex;
		if (startIndex == 0) return false;
		let parent = range.parent, nodeBefore = parent.child(startIndex - 1);
		if (nodeBefore.type != itemType) return false;
		if (dispatch) {
			let nestedBefore = nodeBefore.lastChild && nodeBefore.lastChild.type == parent.type;
			let inner = Fragment$8.from(nestedBefore ? itemType.create() : null);
			let slice = new Slice(Fragment$8.from(itemType.create(null, Fragment$8.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0);
			let before = range.start, after = range.end;
			dispatch(state.tr.step(new ReplaceAroundStep(before - (nestedBefore ? 3 : 1), after, before, after, slice, 1, true)).scrollIntoView());
		}
		return true;
	};
}
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-view@1.41.9/node_modules/prosemirror-view/dist/index.js
var domIndex = function(node) {
	for (var index = 0;; index++) {
		node = node.previousSibling;
		if (!node) return index;
	}
};
var parentNode = function(node) {
	let parent = node.assignedSlot || node.parentNode;
	return parent && parent.nodeType == 11 ? parent.host : parent;
};
var reusedRange = null;
var textRange = function(node, from, to) {
	let range = reusedRange || (reusedRange = document.createRange());
	range.setEnd(node, to == null ? node.nodeValue.length : to);
	range.setStart(node, from || 0);
	return range;
};
var clearReusedRange = function() {
	reusedRange = null;
};
var isEquivalentPosition = function(node, off, targetNode, targetOff) {
	return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1));
};
var atomElements = /^(img|br|input|textarea|hr)$/i;
function scanFor(node, off, targetNode, targetOff, dir) {
	var _a;
	for (;;) {
		if (node == targetNode && off == targetOff) return true;
		if (off == (dir < 0 ? 0 : nodeSize(node))) {
			let parent = node.parentNode;
			if (!parent || parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") return false;
			off = domIndex(node) + (dir < 0 ? 0 : 1);
			node = parent;
		} else if (node.nodeType == 1) {
			let child = node.childNodes[off + (dir < 0 ? -1 : 0)];
			if (child.nodeType == 1 && child.contentEditable == "false") {
				if ((_a = child.pmViewDesc) === null || _a === void 0 ? void 0 : _a.ignoreForSelection) off += dir;
				else return false;
			} else {
				node = child;
				off = dir < 0 ? nodeSize(node) : 0;
			}
		} else return false;
	}
}
function nodeSize(node) {
	return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
}
function textNodeBefore$1(node, offset) {
	for (;;) {
		if (node.nodeType == 3 && offset) return node;
		if (node.nodeType == 1 && offset > 0) {
			if (node.contentEditable == "false") return null;
			node = node.childNodes[offset - 1];
			offset = nodeSize(node);
		} else if (node.parentNode && !hasBlockDesc(node)) {
			offset = domIndex(node);
			node = node.parentNode;
		} else return null;
	}
}
function textNodeAfter$1(node, offset) {
	for (;;) {
		if (node.nodeType == 3 && offset < node.nodeValue.length) return node;
		if (node.nodeType == 1 && offset < node.childNodes.length) {
			if (node.contentEditable == "false") return null;
			node = node.childNodes[offset];
			offset = 0;
		} else if (node.parentNode && !hasBlockDesc(node)) {
			offset = domIndex(node) + 1;
			node = node.parentNode;
		} else return null;
	}
}
function isOnEdge(node, offset, parent) {
	for (let atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd;) {
		if (node == parent) return true;
		let index = domIndex(node);
		node = node.parentNode;
		if (!node) return false;
		atStart = atStart && index == 0;
		atEnd = atEnd && index == nodeSize(node);
	}
}
function hasBlockDesc(dom) {
	let desc;
	for (let cur = dom; cur; cur = cur.parentNode) if (desc = cur.pmViewDesc) break;
	return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom);
}
var selectionCollapsed = function(domSel) {
	return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset);
};
function keyEvent(keyCode, key) {
	let event = document.createEvent("Event");
	event.initEvent("keydown", true, true);
	event.keyCode = keyCode;
	event.key = event.code = key;
	return event;
}
function deepActiveElement(doc) {
	let elt = doc.activeElement;
	while (elt && elt.shadowRoot) elt = elt.shadowRoot.activeElement;
	return elt;
}
function caretFromPoint(doc, x, y) {
	if (doc.caretPositionFromPoint) try {
		let pos = doc.caretPositionFromPoint(x, y);
		if (pos) return {
			node: pos.offsetNode,
			offset: Math.min(nodeSize(pos.offsetNode), pos.offset)
		};
	} catch (_) {}
	if (doc.caretRangeFromPoint) {
		let range = doc.caretRangeFromPoint(x, y);
		if (range) return {
			node: range.startContainer,
			offset: Math.min(nodeSize(range.startContainer), range.startOffset)
		};
	}
}
var nav = typeof navigator != "undefined" ? navigator : null;
var doc = typeof document != "undefined" ? document : null;
var agent = nav && nav.userAgent || "";
var ie_edge = /Edge\/(\d+)/.exec(agent);
var ie_upto10 = /MSIE \d/.exec(agent);
var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent);
var ie$1 = !!(ie_upto10 || ie_11up || ie_edge);
var ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0;
var gecko = !ie$1 && /gecko\/(\d+)/i.test(agent);
gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1];
var _chrome = !ie$1 && /Chrome\/(\d+)/.exec(agent);
var chrome = !!_chrome;
var chrome_version = _chrome ? +_chrome[1] : 0;
var safari = !ie$1 && !!nav && /Apple Computer/.test(nav.vendor);
var ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2);
var mac$2 = ios || (nav ? /Mac/.test(nav.platform) : false);
var windows$1 = nav ? /Win/.test(nav.platform) : false;
var android = /Android \d/.test(agent);
var webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
var webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
function windowRect(doc) {
	let vp = doc.defaultView && doc.defaultView.visualViewport;
	if (vp) return {
		left: 0,
		right: vp.width,
		top: 0,
		bottom: vp.height
	};
	return {
		left: 0,
		right: doc.documentElement.clientWidth,
		top: 0,
		bottom: doc.documentElement.clientHeight
	};
}
function getSide(value, side) {
	return typeof value == "number" ? value : value[side];
}
function clientRect(node) {
	let rect = node.getBoundingClientRect();
	let scaleX = rect.width / node.offsetWidth || 1;
	let scaleY = rect.height / node.offsetHeight || 1;
	return {
		left: rect.left,
		right: rect.left + node.clientWidth * scaleX,
		top: rect.top,
		bottom: rect.top + node.clientHeight * scaleY
	};
}
function scrollRectIntoView(view, rect, startDOM) {
	let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5;
	let doc = view.dom.ownerDocument;
	for (let parent = startDOM || view.dom;;) {
		if (!parent) break;
		if (parent.nodeType != 1) {
			parent = parentNode(parent);
			continue;
		}
		let elt = parent;
		let atTop = elt == doc.body;
		let bounding = atTop ? windowRect(doc) : clientRect(elt);
		let moveX = 0, moveY = 0;
		if (rect.top < bounding.top + getSide(scrollThreshold, "top")) moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top"));
		else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) moveY = rect.bottom - rect.top > bounding.bottom - bounding.top ? rect.top + getSide(scrollMargin, "top") - bounding.top : rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom");
		if (rect.left < bounding.left + getSide(scrollThreshold, "left")) moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left"));
		else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) moveX = rect.right - bounding.right + getSide(scrollMargin, "right");
		if (moveX || moveY) {
			if (atTop) doc.defaultView.scrollBy(moveX, moveY);
			else {
				let startX = elt.scrollLeft, startY = elt.scrollTop;
				if (moveY) elt.scrollTop += moveY;
				if (moveX) elt.scrollLeft += moveX;
				let dX = elt.scrollLeft - startX, dY = elt.scrollTop - startY;
				rect = {
					left: rect.left - dX,
					top: rect.top - dY,
					right: rect.right - dX,
					bottom: rect.bottom - dY
				};
			}
		}
		let pos = atTop ? "fixed" : getComputedStyle(parent).position;
		if (/^(fixed|sticky)$/.test(pos)) break;
		parent = pos == "absolute" ? parent.offsetParent : parentNode(parent);
	}
}
function storeScrollPos(view) {
	let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top);
	let refDOM, refTop;
	for (let x = (rect.left + rect.right) / 2, y = startY + 1; y < Math.min(innerHeight, rect.bottom); y += 5) {
		let dom = view.root.elementFromPoint(x, y);
		if (!dom || dom == view.dom || !view.dom.contains(dom)) continue;
		let localRect = dom.getBoundingClientRect();
		if (localRect.top >= startY - 20) {
			refDOM = dom;
			refTop = localRect.top;
			break;
		}
	}
	return {
		refDOM,
		refTop,
		stack: scrollStack(view.dom)
	};
}
function scrollStack(dom) {
	let stack = [], doc = dom.ownerDocument;
	for (let cur = dom; cur; cur = parentNode(cur)) {
		stack.push({
			dom: cur,
			top: cur.scrollTop,
			left: cur.scrollLeft
		});
		if (dom == doc) break;
	}
	return stack;
}
function resetScrollPos({ refDOM, refTop, stack }) {
	let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0;
	restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop);
}
function restoreScrollStack(stack, dTop) {
	for (let i = 0; i < stack.length; i++) {
		let { dom, top, left } = stack[i];
		if (dom.scrollTop != top + dTop) dom.scrollTop = top + dTop;
		if (dom.scrollLeft != left) dom.scrollLeft = left;
	}
}
var preventScrollSupported = null;
function focusPreventScroll(dom) {
	if (dom.setActive) return dom.setActive();
	if (preventScrollSupported) return dom.focus(preventScrollSupported);
	let stored = scrollStack(dom);
	dom.focus(preventScrollSupported == null ? { get preventScroll() {
		preventScrollSupported = { preventScroll: true };
		return true;
	} } : void 0);
	if (!preventScrollSupported) {
		preventScrollSupported = false;
		restoreScrollStack(stored, 0);
	}
}
function findOffsetInNode(node, coords) {
	let closest, dxClosest = 2e8, coordsClosest, offset = 0;
	let rowBot = coords.top, rowTop = coords.top;
	let firstBelow, coordsBelow;
	for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
		let rects;
		if (child.nodeType == 1) rects = child.getClientRects();
		else if (child.nodeType == 3) rects = textRange(child).getClientRects();
		else continue;
		for (let i = 0; i < rects.length; i++) {
			let rect = rects[i];
			if (rect.top <= rowBot && rect.bottom >= rowTop) {
				rowBot = Math.max(rect.bottom, rowBot);
				rowTop = Math.min(rect.top, rowTop);
				let dx = rect.left > coords.left ? rect.left - coords.left : rect.right < coords.left ? coords.left - rect.right : 0;
				if (dx < dxClosest) {
					closest = child;
					dxClosest = dx;
					coordsClosest = dx && closest.nodeType == 3 ? {
						left: rect.right < coords.left ? rect.right : rect.left,
						top: coords.top
					} : coords;
					if (child.nodeType == 1 && dx) offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
					continue;
				}
			} else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) {
				firstBelow = child;
				coordsBelow = {
					left: Math.max(rect.left, Math.min(rect.right, coords.left)),
					top: rect.top
				};
			}
			if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) offset = childIndex + 1;
		}
	}
	if (!closest && firstBelow) {
		closest = firstBelow;
		coordsClosest = coordsBelow;
		dxClosest = 0;
	}
	if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest);
	if (!closest || dxClosest && closest.nodeType == 1) return {
		node,
		offset
	};
	return findOffsetInNode(closest, coordsClosest);
}
function findOffsetInText(node, coords) {
	let len = node.nodeValue.length;
	let range = document.createRange(), result;
	for (let i = 0; i < len; i++) {
		range.setEnd(node, i + 1);
		range.setStart(node, i);
		let rect = singleRect(range, 1);
		if (rect.top == rect.bottom) continue;
		if (inRect(coords, rect)) {
			result = {
				node,
				offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)
			};
			break;
		}
	}
	range.detach();
	return result || {
		node,
		offset: 0
	};
}
function inRect(coords, rect) {
	return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 && coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1;
}
function targetKludge(dom, coords) {
	let parent = dom.parentNode;
	if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) return parent;
	return dom;
}
function posFromElement(view, elt, coords) {
	let { node, offset } = findOffsetInNode(elt, coords), bias = -1;
	if (node.nodeType == 1 && !node.firstChild) {
		let rect = node.getBoundingClientRect();
		bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1;
	}
	return view.docView.posFromDOM(node, offset, bias);
}
function posFromCaret(view, node, offset, coords) {
	let outsideBlock = -1;
	for (let cur = node, sawBlock = false;;) {
		if (cur == view.dom) break;
		let desc = view.docView.nearestDesc(cur, true), rect;
		if (!desc) return null;
		if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) && ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
			if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) {
				if (!sawBlock && rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore;
				else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter;
				sawBlock = true;
			}
			if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) return (desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2) ? desc.posBefore : desc.posAfter;
		}
		cur = desc.dom.parentNode;
	}
	return outsideBlock > -1 ? outsideBlock : view.docView.posFromDOM(node, offset, -1);
}
function elementFromPoint(element, coords, box) {
	let len = element.childNodes.length;
	if (len && box.top < box.bottom) for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI;;) {
		let child = element.childNodes[i];
		if (child.nodeType == 1) {
			let rects = child.getClientRects();
			for (let j = 0; j < rects.length; j++) {
				let rect = rects[j];
				if (inRect(coords, rect)) return elementFromPoint(child, coords, rect);
			}
		}
		if ((i = (i + 1) % len) == startI) break;
	}
	return element;
}
function posAtCoords(view, coords) {
	let doc = view.dom.ownerDocument, node, offset = 0;
	let caret = caretFromPoint(doc, coords.left, coords.top);
	if (caret) ({node, offset} = caret);
	let elt = (view.root.elementFromPoint ? view.root : doc).elementFromPoint(coords.left, coords.top);
	let pos;
	if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {
		let box = view.dom.getBoundingClientRect();
		if (!inRect(coords, box)) return null;
		elt = elementFromPoint(view.dom, coords, box);
		if (!elt) return null;
	}
	if (safari) {
		for (let p = elt; node && p; p = parentNode(p)) if (p.draggable) node = void 0;
	}
	elt = targetKludge(elt, coords);
	if (node) {
		if (gecko && node.nodeType == 1) {
			offset = Math.min(offset, node.childNodes.length);
			if (offset < node.childNodes.length) {
				let next = node.childNodes[offset], box;
				if (next.nodeName == "IMG" && (box = next.getBoundingClientRect()).right <= coords.left && box.bottom > coords.top) offset++;
			}
		}
		let prev;
		if (webkit && offset && node.nodeType == 1 && (prev = node.childNodes[offset - 1]).nodeType == 1 && prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top) offset--;
		if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && coords.top > node.lastChild.getBoundingClientRect().bottom) pos = view.state.doc.content.size;
		else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") pos = posFromCaret(view, node, offset, coords);
	}
	if (pos == null) pos = posFromElement(view, elt, coords);
	let desc = view.docView.nearestDesc(elt, true);
	return {
		pos,
		inside: desc ? desc.posAtStart - desc.border : -1
	};
}
function nonZero(rect) {
	return rect.top < rect.bottom || rect.left < rect.right;
}
function singleRect(target, bias) {
	let rects = target.getClientRects();
	if (rects.length) {
		let first = rects[bias < 0 ? 0 : rects.length - 1];
		if (nonZero(first)) return first;
	}
	return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect();
}
var BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
function coordsAtPos(view, pos, side) {
	let { node, offset, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1);
	let supportEmptyRange = webkit || gecko;
	if (node.nodeType == 3) {
		if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) {
			let rect = singleRect(textRange(node, offset, offset), side);
			if (gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) {
				let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1);
				if (rectBefore.top == rect.top) {
					let rectAfter = singleRect(textRange(node, offset, offset + 1), -1);
					if (rectAfter.top != rect.top) return flattenV(rectAfter, rectAfter.left < rectBefore.left);
				}
			}
			return rect;
		} else {
			let from = offset, to = offset, takeSide = side < 0 ? 1 : -1;
			if (side < 0 && !offset) {
				to++;
				takeSide = -1;
			} else if (side >= 0 && offset == node.nodeValue.length) {
				from--;
				takeSide = 1;
			} else if (side < 0) from--;
			else to++;
			return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0);
		}
	}
	if (!view.state.doc.resolve(pos - (atom || 0)).parent.inlineContent) {
		if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
			let before = node.childNodes[offset - 1];
			if (before.nodeType == 1) return flattenH(before.getBoundingClientRect(), false);
		}
		if (atom == null && offset < nodeSize(node)) {
			let after = node.childNodes[offset];
			if (after.nodeType == 1) return flattenH(after.getBoundingClientRect(), true);
		}
		return flattenH(node.getBoundingClientRect(), side >= 0);
	}
	if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
		let before = node.childNodes[offset - 1];
		let target = before.nodeType == 3 ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1)) : before.nodeType == 1 && (before.nodeName != "BR" || !before.nextSibling) ? before : null;
		if (target) return flattenV(singleRect(target, 1), false);
	}
	if (atom == null && offset < nodeSize(node)) {
		let after = node.childNodes[offset];
		while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords) after = after.nextSibling;
		let target = !after ? null : after.nodeType == 3 ? textRange(after, 0, supportEmptyRange ? 0 : 1) : after.nodeType == 1 ? after : null;
		if (target) return flattenV(singleRect(target, -1), true);
	}
	return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, -side), side >= 0);
}
function flattenV(rect, left) {
	if (rect.width == 0) return rect;
	let x = left ? rect.left : rect.right;
	return {
		top: rect.top,
		bottom: rect.bottom,
		left: x,
		right: x
	};
}
function flattenH(rect, top) {
	if (rect.height == 0) return rect;
	let y = top ? rect.top : rect.bottom;
	return {
		top: y,
		bottom: y,
		left: rect.left,
		right: rect.right
	};
}
function withFlushedState(view, state, f) {
	let viewState = view.state, active = view.root.activeElement;
	if (viewState != state) view.updateState(state);
	if (active != view.dom) view.focus();
	try {
		return f();
	} finally {
		if (viewState != state) view.updateState(viewState);
		if (active != view.dom && active) active.focus();
	}
}
function endOfTextblockVertical(view, state, dir) {
	let sel = state.selection;
	let $pos = dir == "up" ? sel.$from : sel.$to;
	return withFlushedState(view, state, () => {
		let { node: dom } = view.docView.domFromPos($pos.pos, dir == "up" ? -1 : 1);
		for (;;) {
			let nearest = view.docView.nearestDesc(dom, true);
			if (!nearest) break;
			if (nearest.node.isBlock) {
				dom = nearest.contentDOM || nearest.dom;
				break;
			}
			dom = nearest.dom.parentNode;
		}
		let coords = coordsAtPos(view, $pos.pos, 1);
		for (let child = dom.firstChild; child; child = child.nextSibling) {
			let boxes;
			if (child.nodeType == 1) boxes = child.getClientRects();
			else if (child.nodeType == 3) boxes = textRange(child, 0, child.nodeValue.length).getClientRects();
			else continue;
			for (let i = 0; i < boxes.length; i++) {
				let box = boxes[i];
				if (box.bottom > box.top + 1 && (dir == "up" ? coords.top - box.top > (box.bottom - coords.top) * 2 : box.bottom - coords.bottom > (coords.bottom - box.top) * 2)) return false;
			}
		}
		return true;
	});
}
var maybeRTL = /[\u0590-\u08ac]/;
function endOfTextblockHorizontal(view, state, dir) {
	let { $head } = state.selection;
	if (!$head.parent.isTextblock) return false;
	let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size;
	let sel = view.domSelection();
	if (!sel) return $head.pos == $head.start() || $head.pos == $head.end();
	if (!maybeRTL.test($head.parent.textContent) || !sel.modify) return dir == "left" || dir == "backward" ? atStart : atEnd;
	return withFlushedState(view, state, () => {
		let { focusNode: oldNode, focusOffset: oldOff, anchorNode, anchorOffset } = view.domSelectionRange();
		let oldBidiLevel = sel.caretBidiLevel;
		sel.modify("move", dir, "character");
		let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom;
		let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange();
		let result = newNode && !parentDOM.contains(newNode.nodeType == 1 ? newNode : newNode.parentNode) || oldNode == newNode && oldOff == newOff;
		try {
			sel.collapse(anchorNode, anchorOffset);
			if (oldNode && (oldNode != anchorNode || oldOff != anchorOffset) && sel.extend) sel.extend(oldNode, oldOff);
		} catch (_) {}
		if (oldBidiLevel != null) sel.caretBidiLevel = oldBidiLevel;
		return result;
	});
}
var cachedState = null;
var cachedDir = null;
var cachedResult = false;
function endOfTextblock(view, state, dir) {
	if (cachedState == state && cachedDir == dir) return cachedResult;
	cachedState = state;
	cachedDir = dir;
	return cachedResult = dir == "up" || dir == "down" ? endOfTextblockVertical(view, state, dir) : endOfTextblockHorizontal(view, state, dir);
}
var NOT_DIRTY = 0;
var CHILD_DIRTY = 1;
var CONTENT_DIRTY = 2;
var NODE_DIRTY = 3;
var ViewDesc = class {
	constructor(parent, children, dom, contentDOM) {
		this.parent = parent;
		this.children = children;
		this.dom = dom;
		this.contentDOM = contentDOM;
		this.dirty = NOT_DIRTY;
		dom.pmViewDesc = this;
	}
	matchesWidget(widget) {
		return false;
	}
	matchesMark(mark) {
		return false;
	}
	matchesNode(node, outerDeco, innerDeco) {
		return false;
	}
	matchesHack(nodeName) {
		return false;
	}
	parseRule() {
		return null;
	}
	stopEvent(event) {
		return false;
	}
	get size() {
		let size = 0;
		for (let i = 0; i < this.children.length; i++) size += this.children[i].size;
		return size;
	}
	get border() {
		return 0;
	}
	destroy() {
		this.parent = void 0;
		if (this.dom.pmViewDesc == this) this.dom.pmViewDesc = void 0;
		for (let i = 0; i < this.children.length; i++) this.children[i].destroy();
	}
	posBeforeChild(child) {
		for (let i = 0, pos = this.posAtStart;; i++) {
			let cur = this.children[i];
			if (cur == child) return pos;
			pos += cur.size;
		}
	}
	get posBefore() {
		return this.parent.posBeforeChild(this);
	}
	get posAtStart() {
		return this.parent ? this.parent.posBeforeChild(this) + this.border : 0;
	}
	get posAfter() {
		return this.posBefore + this.size;
	}
	get posAtEnd() {
		return this.posAtStart + this.size - 2 * this.border;
	}
	localPosFromDOM(dom, offset, bias) {
		if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) {
			if (bias < 0) {
				let domBefore, desc;
				if (dom == this.contentDOM) domBefore = dom.childNodes[offset - 1];
				else {
					while (dom.parentNode != this.contentDOM) dom = dom.parentNode;
					domBefore = dom.previousSibling;
				}
				while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) domBefore = domBefore.previousSibling;
				return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart;
			} else {
				let domAfter, desc;
				if (dom == this.contentDOM) domAfter = dom.childNodes[offset];
				else {
					while (dom.parentNode != this.contentDOM) dom = dom.parentNode;
					domAfter = dom.nextSibling;
				}
				while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) domAfter = domAfter.nextSibling;
				return domAfter ? this.posBeforeChild(desc) : this.posAtEnd;
			}
		}
		let atEnd;
		if (dom == this.dom && this.contentDOM) atEnd = offset > domIndex(this.contentDOM);
		else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) atEnd = dom.compareDocumentPosition(this.contentDOM) & 2;
		else if (this.dom.firstChild) {
			if (offset == 0) for (let search = dom;; search = search.parentNode) {
				if (search == this.dom) {
					atEnd = false;
					break;
				}
				if (search.previousSibling) break;
			}
			if (atEnd == null && offset == dom.childNodes.length) for (let search = dom;; search = search.parentNode) {
				if (search == this.dom) {
					atEnd = true;
					break;
				}
				if (search.nextSibling) break;
			}
		}
		return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart;
	}
	nearestDesc(dom, onlyNodes = false) {
		for (let first = true, cur = dom; cur; cur = cur.parentNode) {
			let desc = this.getDesc(cur), nodeDOM;
			if (desc && (!onlyNodes || desc.node)) {
				if (first && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) first = false;
				else return desc;
			}
		}
	}
	getDesc(dom) {
		let desc = dom.pmViewDesc;
		for (let cur = desc; cur; cur = cur.parent) if (cur == this) return desc;
	}
	posFromDOM(dom, offset, bias) {
		for (let scan = dom; scan; scan = scan.parentNode) {
			let desc = this.getDesc(scan);
			if (desc) return desc.localPosFromDOM(dom, offset, bias);
		}
		return -1;
	}
	descAt(pos) {
		for (let i = 0, offset = 0; i < this.children.length; i++) {
			let child = this.children[i], end = offset + child.size;
			if (offset == pos && end != offset) {
				while (!child.border && child.children.length) for (let i = 0; i < child.children.length; i++) {
					let inner = child.children[i];
					if (inner.size) {
						child = inner;
						break;
					}
				}
				return child;
			}
			if (pos < end) return child.descAt(pos - offset - child.border);
			offset = end;
		}
	}
	domFromPos(pos, side) {
		if (!this.contentDOM) return {
			node: this.dom,
			offset: 0,
			atom: pos + 1
		};
		let i = 0, offset = 0;
		for (let curPos = 0; i < this.children.length; i++) {
			let child = this.children[i], end = curPos + child.size;
			if (end > pos || child instanceof TrailingHackViewDesc) {
				offset = pos - curPos;
				break;
			}
			curPos = end;
		}
		if (offset) return this.children[i].domFromPos(offset - this.children[i].border, side);
		for (let prev; i && !(prev = this.children[i - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i--);
		if (side <= 0) {
			let prev, enter = true;
			for (;; i--, enter = false) {
				prev = i ? this.children[i - 1] : null;
				if (!prev || prev.dom.parentNode == this.contentDOM) break;
			}
			if (prev && side && enter && !prev.border && !prev.domAtom) return prev.domFromPos(prev.size, side);
			return {
				node: this.contentDOM,
				offset: prev ? domIndex(prev.dom) + 1 : 0
			};
		} else {
			let next, enter = true;
			for (;; i++, enter = false) {
				next = i < this.children.length ? this.children[i] : null;
				if (!next || next.dom.parentNode == this.contentDOM) break;
			}
			if (next && enter && !next.border && !next.domAtom) return next.domFromPos(0, side);
			return {
				node: this.contentDOM,
				offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length
			};
		}
	}
	parseRange(from, to, base = 0) {
		if (this.children.length == 0) return {
			node: this.contentDOM,
			from,
			to,
			fromOffset: 0,
			toOffset: this.contentDOM.childNodes.length
		};
		let fromOffset = -1, toOffset = -1;
		for (let offset = base, i = 0;; i++) {
			let child = this.children[i], end = offset + child.size;
			if (fromOffset == -1 && from <= end) {
				let childBase = offset + child.border;
				if (from >= childBase && to <= end - child.border && child.node && child.contentDOM && this.contentDOM.contains(child.contentDOM)) return child.parseRange(from, to, childBase);
				from = offset;
				for (let j = i; j > 0; j--) {
					let prev = this.children[j - 1];
					if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) {
						fromOffset = domIndex(prev.dom) + 1;
						break;
					}
					from -= prev.size;
				}
				if (fromOffset == -1) fromOffset = 0;
			}
			if (fromOffset > -1 && (end > to || i == this.children.length - 1)) {
				to = end;
				for (let j = i + 1; j < this.children.length; j++) {
					let next = this.children[j];
					if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) {
						toOffset = domIndex(next.dom);
						break;
					}
					to += next.size;
				}
				if (toOffset == -1) toOffset = this.contentDOM.childNodes.length;
				break;
			}
			offset = end;
		}
		return {
			node: this.contentDOM,
			from,
			to,
			fromOffset,
			toOffset
		};
	}
	emptyChildAt(side) {
		if (this.border || !this.contentDOM || !this.children.length) return false;
		let child = this.children[side < 0 ? 0 : this.children.length - 1];
		return child.size == 0 || child.emptyChildAt(side);
	}
	domAfterPos(pos) {
		let { node, offset } = this.domFromPos(pos, 0);
		if (node.nodeType != 1 || offset == node.childNodes.length) throw new RangeError("No node after pos " + pos);
		return node.childNodes[offset];
	}
	setSelection(anchor, head, view, force = false) {
		let from = Math.min(anchor, head), to = Math.max(anchor, head);
		for (let i = 0, offset = 0; i < this.children.length; i++) {
			let child = this.children[i], end = offset + child.size;
			if (from > offset && to < end) return child.setSelection(anchor - offset - child.border, head - offset - child.border, view, force);
			offset = end;
		}
		let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1);
		let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1);
		let domSel = view.root.getSelection();
		let selRange = view.domSelectionRange();
		let brKludge = false;
		if ((gecko || safari) && anchor == head) {
			let { node, offset } = anchorDOM;
			if (node.nodeType == 3) {
				brKludge = !!(offset && node.nodeValue[offset - 1] == "\n");
				if (brKludge && offset == node.nodeValue.length) for (let scan = node, after; scan; scan = scan.parentNode) {
					if (after = scan.nextSibling) {
						if (after.nodeName == "BR") anchorDOM = headDOM = {
							node: after.parentNode,
							offset: domIndex(after) + 1
						};
						break;
					}
					let desc = scan.pmViewDesc;
					if (desc && desc.node && desc.node.isBlock) break;
				}
			} else {
				let prev = node.childNodes[offset - 1];
				brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false");
			}
		}
		if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && selRange.focusNode.nodeType == 1) {
			let after = selRange.focusNode.childNodes[selRange.focusOffset];
			if (after && after.contentEditable == "false") force = true;
		}
		if (!(force || brKludge && safari) && isEquivalentPosition(anchorDOM.node, anchorDOM.offset, selRange.anchorNode, selRange.anchorOffset) && isEquivalentPosition(headDOM.node, headDOM.offset, selRange.focusNode, selRange.focusOffset)) return;
		let domSelExtended = false;
		if ((domSel.extend || anchor == head) && !(brKludge && gecko)) {
			domSel.collapse(anchorDOM.node, anchorDOM.offset);
			try {
				if (anchor != head) domSel.extend(headDOM.node, headDOM.offset);
				domSelExtended = true;
			} catch (_) {}
		}
		if (!domSelExtended) {
			if (anchor > head) {
				let tmp = anchorDOM;
				anchorDOM = headDOM;
				headDOM = tmp;
			}
			let range = document.createRange();
			range.setEnd(headDOM.node, headDOM.offset);
			range.setStart(anchorDOM.node, anchorDOM.offset);
			domSel.removeAllRanges();
			domSel.addRange(range);
		}
	}
	ignoreMutation(mutation) {
		return !this.contentDOM && mutation.type != "selection";
	}
	get contentLost() {
		return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM);
	}
	markDirty(from, to) {
		for (let offset = 0, i = 0; i < this.children.length; i++) {
			let child = this.children[i], end = offset + child.size;
			if (offset == end ? from <= end && to >= offset : from < end && to > offset) {
				let startInside = offset + child.border, endInside = end - child.border;
				if (from >= startInside && to <= endInside) {
					this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY;
					if (from == startInside && to == endInside && (child.contentLost || child.dom.parentNode != this.contentDOM)) child.dirty = NODE_DIRTY;
					else child.markDirty(from - startInside, to - startInside);
					return;
				} else child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY;
			}
			offset = end;
		}
		this.dirty = CONTENT_DIRTY;
	}
	markParentsDirty() {
		let level = 1;
		for (let node = this.parent; node; node = node.parent, level++) {
			let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY;
			if (node.dirty < dirty) node.dirty = dirty;
		}
	}
	get domAtom() {
		return false;
	}
	get ignoreForCoords() {
		return false;
	}
	get ignoreForSelection() {
		return false;
	}
	isText(text) {
		return false;
	}
};
var WidgetViewDesc = class extends ViewDesc {
	constructor(parent, widget, view, pos) {
		let self, dom = widget.type.toDOM;
		if (typeof dom == "function") dom = dom(view, () => {
			if (!self) return pos;
			if (self.parent) return self.parent.posBeforeChild(self);
		});
		if (!widget.type.spec.raw) {
			if (dom.nodeType != 1) {
				let wrap = document.createElement("span");
				wrap.appendChild(dom);
				dom = wrap;
			}
			dom.contentEditable = "false";
			dom.classList.add("ProseMirror-widget");
		}
		super(parent, [], dom, null);
		this.widget = widget;
		this.widget = widget;
		self = this;
	}
	matchesWidget(widget) {
		return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type);
	}
	parseRule() {
		return { ignore: true };
	}
	stopEvent(event) {
		let stop = this.widget.spec.stopEvent;
		return stop ? stop(event) : false;
	}
	ignoreMutation(mutation) {
		return mutation.type != "selection" || this.widget.spec.ignoreSelection;
	}
	destroy() {
		this.widget.type.destroy(this.dom);
		super.destroy();
	}
	get domAtom() {
		return true;
	}
	get ignoreForSelection() {
		return !!this.widget.type.spec.relaxedSide;
	}
	get side() {
		return this.widget.type.side;
	}
};
var CompositionViewDesc = class extends ViewDesc {
	constructor(parent, dom, textDOM, text) {
		super(parent, [], dom, null);
		this.textDOM = textDOM;
		this.text = text;
	}
	get size() {
		return this.text.length;
	}
	localPosFromDOM(dom, offset) {
		if (dom != this.textDOM) return this.posAtStart + (offset ? this.size : 0);
		return this.posAtStart + offset;
	}
	domFromPos(pos) {
		return {
			node: this.textDOM,
			offset: pos
		};
	}
	ignoreMutation(mut) {
		return mut.type === "characterData" && mut.target.nodeValue == mut.oldValue;
	}
};
var MarkViewDesc = class MarkViewDesc extends ViewDesc {
	constructor(parent, mark, dom, contentDOM, spec) {
		super(parent, [], dom, contentDOM);
		this.mark = mark;
		this.spec = spec;
	}
	static create(parent, mark, inline, view) {
		let custom = view.nodeViews[mark.type.name];
		let spec = custom && custom(mark, view, inline);
		if (!spec || !spec.dom) spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs);
		return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom, spec);
	}
	parseRule() {
		if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) return null;
		return {
			mark: this.mark.type.name,
			attrs: this.mark.attrs,
			contentElement: this.contentDOM
		};
	}
	matchesMark(mark) {
		return this.dirty != NODE_DIRTY && this.mark.eq(mark);
	}
	markDirty(from, to) {
		super.markDirty(from, to);
		if (this.dirty != NOT_DIRTY) {
			let parent = this.parent;
			while (!parent.node) parent = parent.parent;
			if (parent.dirty < this.dirty) parent.dirty = this.dirty;
			this.dirty = NOT_DIRTY;
		}
	}
	slice(from, to, view) {
		let copy = MarkViewDesc.create(this.parent, this.mark, true, view);
		let nodes = this.children, size = this.size;
		if (to < size) nodes = replaceNodes(nodes, to, size, view);
		if (from > 0) nodes = replaceNodes(nodes, 0, from, view);
		for (let i = 0; i < nodes.length; i++) nodes[i].parent = copy;
		copy.children = nodes;
		return copy;
	}
	ignoreMutation(mutation) {
		return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation);
	}
	destroy() {
		if (this.spec.destroy) this.spec.destroy();
		super.destroy();
	}
};
var NodeViewDesc = class NodeViewDesc extends ViewDesc {
	constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) {
		super(parent, [], dom, contentDOM);
		this.node = node;
		this.outerDeco = outerDeco;
		this.innerDeco = innerDeco;
		this.nodeDOM = nodeDOM;
	}
	static create(parent, node, outerDeco, innerDeco, view, pos) {
		let custom = view.nodeViews[node.type.name], descObj;
		let spec = custom && custom(node, view, () => {
			if (!descObj) return pos;
			if (descObj.parent) return descObj.parent.posBeforeChild(descObj);
		}, outerDeco, innerDeco);
		let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM;
		if (node.isText) {
			if (!dom) dom = document.createTextNode(node.text);
			else if (dom.nodeType != 3) throw new RangeError("Text must be rendered as a DOM text node");
		} else if (!dom) {
			let spec = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node), null, node.attrs);
			({dom, contentDOM} = spec);
		}
		if (!contentDOM && !node.isText && dom.nodeName != "BR") {
			if (!dom.hasAttribute("contenteditable")) dom.contentEditable = "false";
			if (node.type.spec.draggable) dom.draggable = true;
		}
		let nodeDOM = dom;
		dom = applyOuterDeco(dom, outerDeco, node);
		if (spec) return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec, view, pos + 1);
		else if (node.isText) return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view);
		else return new NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, view, pos + 1);
	}
	parseRule() {
		if (this.node.type.spec.reparseInView) return null;
		let rule = {
			node: this.node.type.name,
			attrs: this.node.attrs
		};
		if (this.node.type.whitespace == "pre") rule.preserveWhitespace = "full";
		if (!this.contentDOM) rule.getContent = () => this.node.content;
		else if (!this.contentLost) rule.contentElement = this.contentDOM;
		else {
			for (let i = this.children.length - 1; i >= 0; i--) {
				let child = this.children[i];
				if (this.dom.contains(child.dom.parentNode)) {
					rule.contentElement = child.dom.parentNode;
					break;
				}
			}
			if (!rule.contentElement) rule.getContent = () => Fragment$8.empty;
		}
		return rule;
	}
	matchesNode(node, outerDeco, innerDeco) {
		return this.dirty == NOT_DIRTY && node.eq(this.node) && sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco);
	}
	get size() {
		return this.node.nodeSize;
	}
	get border() {
		return this.node.isLeaf ? 0 : 1;
	}
	updateChildren(view, pos) {
		let inline = this.node.inlineContent, off = pos;
		let composition = view.composing ? this.localCompositionInfo(view, pos) : null;
		let localComposition = composition && composition.pos > -1 ? composition : null;
		let compositionInChild = composition && composition.pos < 0;
		let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
		iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
			if (widget.spec.marks) updater.syncToMarks(widget.spec.marks, inline, view, i);
			else if (widget.type.side >= 0 && !insideNode) updater.syncToMarks(i == this.node.childCount ? Mark$1.none : this.node.child(i).marks, inline, view, i);
			updater.placeWidget(widget, view, off);
		}, (child, outerDeco, innerDeco, i) => {
			updater.syncToMarks(child.marks, inline, view, i);
			let compIndex;
			if (updater.findNodeMatch(child, outerDeco, innerDeco, i));
			else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view));
			else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i, off));
			else updater.addNode(child, outerDeco, innerDeco, view, off);
			off += child.nodeSize;
		});
		updater.syncToMarks([], inline, view, 0);
		if (this.node.isTextblock) updater.addTextblockHacks();
		updater.destroyRest();
		if (updater.changed || this.dirty == CONTENT_DIRTY) {
			if (localComposition) this.protectLocalComposition(view, localComposition);
			renderDescs(this.contentDOM, this.children, view);
			if (ios) iosHacks(this.dom);
		}
	}
	localCompositionInfo(view, pos) {
		let { from, to } = view.state.selection;
		if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) return null;
		let textNode = view.input.compositionNode;
		if (!textNode || !this.dom.contains(textNode.parentNode)) return null;
		if (this.node.inlineContent) {
			let text = textNode.nodeValue;
			let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos);
			return textPos < 0 ? null : {
				node: textNode,
				pos: textPos,
				text
			};
		} else return {
			node: textNode,
			pos: -1,
			text: ""
		};
	}
	protectLocalComposition(view, { node, pos, text }) {
		if (this.getDesc(node)) return;
		let topNode = node;
		for (;; topNode = topNode.parentNode) {
			if (topNode.parentNode == this.contentDOM) break;
			while (topNode.previousSibling) topNode.parentNode.removeChild(topNode.previousSibling);
			while (topNode.nextSibling) topNode.parentNode.removeChild(topNode.nextSibling);
			if (topNode.pmViewDesc) topNode.pmViewDesc = void 0;
		}
		let desc = new CompositionViewDesc(this, topNode, node, text);
		view.input.compositionNodes.push(desc);
		this.children = replaceNodes(this.children, pos, pos + text.length, view, desc);
	}
	update(node, outerDeco, innerDeco, view) {
		if (this.dirty == NODE_DIRTY || !node.sameMarkup(this.node)) return false;
		this.updateInner(node, outerDeco, innerDeco, view);
		return true;
	}
	updateInner(node, outerDeco, innerDeco, view) {
		this.updateOuterDeco(outerDeco);
		this.node = node;
		this.innerDeco = innerDeco;
		if (this.contentDOM) this.updateChildren(view, this.posAtStart);
		this.dirty = NOT_DIRTY;
	}
	updateOuterDeco(outerDeco) {
		if (sameOuterDeco(outerDeco, this.outerDeco)) return;
		let needsWrap = this.nodeDOM.nodeType != 1;
		let oldDOM = this.dom;
		this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap));
		if (this.dom != oldDOM) {
			oldDOM.pmViewDesc = void 0;
			this.dom.pmViewDesc = this;
		}
		this.outerDeco = outerDeco;
	}
	selectNode() {
		if (this.nodeDOM.nodeType == 1) {
			this.nodeDOM.classList.add("ProseMirror-selectednode");
			if (this.contentDOM || !this.node.type.spec.draggable) this.nodeDOM.draggable = true;
		}
	}
	deselectNode() {
		if (this.nodeDOM.nodeType == 1) {
			this.nodeDOM.classList.remove("ProseMirror-selectednode");
			if (this.contentDOM || !this.node.type.spec.draggable) this.nodeDOM.removeAttribute("draggable");
		}
	}
	get domAtom() {
		return this.node.isAtom;
	}
};
function docViewDesc(doc, outerDeco, innerDeco, dom, view) {
	applyOuterDeco(dom, outerDeco, doc);
	let docView = new NodeViewDesc(void 0, doc, outerDeco, innerDeco, dom, dom, dom, view, 0);
	if (docView.contentDOM) docView.updateChildren(view, 0);
	return docView;
}
var TextViewDesc = class TextViewDesc extends NodeViewDesc {
	constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) {
		super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view, 0);
	}
	parseRule() {
		let skip = this.nodeDOM.parentNode;
		while (skip && skip != this.dom && !skip.pmIsDeco) skip = skip.parentNode;
		return { skip: skip || true };
	}
	update(node, outerDeco, innerDeco, view) {
		if (this.dirty == NODE_DIRTY || this.dirty != NOT_DIRTY && !this.inParent() || !node.sameMarkup(this.node)) return false;
		this.updateOuterDeco(outerDeco);
		if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) {
			this.nodeDOM.nodeValue = node.text;
			if (view.trackWrites == this.nodeDOM) view.trackWrites = null;
		}
		this.node = node;
		this.dirty = NOT_DIRTY;
		return true;
	}
	inParent() {
		let parentDOM = this.parent.contentDOM;
		for (let n = this.nodeDOM; n; n = n.parentNode) if (n == parentDOM) return true;
		return false;
	}
	domFromPos(pos) {
		return {
			node: this.nodeDOM,
			offset: pos
		};
	}
	localPosFromDOM(dom, offset, bias) {
		if (dom == this.nodeDOM) return this.posAtStart + Math.min(offset, this.node.text.length);
		return super.localPosFromDOM(dom, offset, bias);
	}
	ignoreMutation(mutation) {
		return mutation.type != "characterData" && mutation.type != "selection";
	}
	slice(from, to, view) {
		let node = this.node.cut(from, to), dom = document.createTextNode(node.text);
		return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view);
	}
	markDirty(from, to) {
		super.markDirty(from, to);
		if (this.dom != this.nodeDOM && (from == 0 || to == this.nodeDOM.nodeValue.length)) this.dirty = NODE_DIRTY;
	}
	get domAtom() {
		return false;
	}
	isText(text) {
		return this.node.text == text;
	}
};
var TrailingHackViewDesc = class extends ViewDesc {
	parseRule() {
		return { ignore: true };
	}
	matchesHack(nodeName) {
		return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName;
	}
	get domAtom() {
		return true;
	}
	get ignoreForCoords() {
		return this.dom.nodeName == "IMG";
	}
};
var CustomNodeViewDesc = class extends NodeViewDesc {
	constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) {
		super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos);
		this.spec = spec;
	}
	update(node, outerDeco, innerDeco, view) {
		if (this.dirty == NODE_DIRTY) return false;
		if (this.spec.update && (this.node.type == node.type || this.spec.multiType)) {
			let result = this.spec.update(node, outerDeco, innerDeco);
			if (result) this.updateInner(node, outerDeco, innerDeco, view);
			return result;
		} else if (!this.contentDOM && !node.isLeaf) return false;
		else return super.update(node, outerDeco, innerDeco, view);
	}
	selectNode() {
		this.spec.selectNode ? this.spec.selectNode() : super.selectNode();
	}
	deselectNode() {
		this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode();
	}
	setSelection(anchor, head, view, force) {
		this.spec.setSelection ? this.spec.setSelection(anchor, head, view.root) : super.setSelection(anchor, head, view, force);
	}
	destroy() {
		if (this.spec.destroy) this.spec.destroy();
		super.destroy();
	}
	stopEvent(event) {
		return this.spec.stopEvent ? this.spec.stopEvent(event) : false;
	}
	ignoreMutation(mutation) {
		return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation);
	}
};
function renderDescs(parentDOM, descs, view) {
	let dom = parentDOM.firstChild, written = false;
	for (let i = 0; i < descs.length; i++) {
		let desc = descs[i], childDOM = desc.dom;
		if (childDOM.parentNode == parentDOM) {
			while (childDOM != dom) {
				dom = rm(dom);
				written = true;
			}
			dom = dom.nextSibling;
		} else {
			written = true;
			parentDOM.insertBefore(childDOM, dom);
		}
		if (desc instanceof MarkViewDesc) {
			let pos = dom ? dom.previousSibling : parentDOM.lastChild;
			renderDescs(desc.contentDOM, desc.children, view);
			dom = pos ? pos.nextSibling : parentDOM.firstChild;
		}
	}
	while (dom) {
		dom = rm(dom);
		written = true;
	}
	if (written && view.trackWrites == parentDOM) view.trackWrites = null;
}
var OuterDecoLevel = function(nodeName) {
	if (nodeName) this.nodeName = nodeName;
};
OuterDecoLevel.prototype = Object.create(null);
var noDeco = [new OuterDecoLevel()];
function computeOuterDeco(outerDeco, node, needsWrap) {
	if (outerDeco.length == 0) return noDeco;
	let top = needsWrap ? noDeco[0] : new OuterDecoLevel(), result = [top];
	for (let i = 0; i < outerDeco.length; i++) {
		let attrs = outerDeco[i].type.attrs;
		if (!attrs) continue;
		if (attrs.nodeName) result.push(top = new OuterDecoLevel(attrs.nodeName));
		for (let name in attrs) {
			let val = attrs[name];
			if (val == null) continue;
			if (needsWrap && result.length == 1) result.push(top = new OuterDecoLevel(node.isInline ? "span" : "div"));
			if (name == "class") top.class = (top.class ? top.class + " " : "") + val;
			else if (name == "style") top.style = (top.style ? top.style + ";" : "") + val;
			else if (name != "nodeName") top[name] = val;
		}
	}
	return result;
}
function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) {
	if (prevComputed == noDeco && curComputed == noDeco) return nodeDOM;
	let curDOM = nodeDOM;
	for (let i = 0; i < curComputed.length; i++) {
		let deco = curComputed[i], prev = prevComputed[i];
		if (i) {
			let parent;
			if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && (parent = curDOM.parentNode) && parent.nodeName.toLowerCase() == deco.nodeName) curDOM = parent;
			else {
				parent = document.createElement(deco.nodeName);
				parent.pmIsDeco = true;
				parent.appendChild(curDOM);
				prev = noDeco[0];
				curDOM = parent;
			}
		}
		patchAttributes(curDOM, prev || noDeco[0], deco);
	}
	return curDOM;
}
function patchAttributes(dom, prev, cur) {
	for (let name in prev) if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) dom.removeAttribute(name);
	for (let name in cur) if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) dom.setAttribute(name, cur[name]);
	if (prev.class != cur.class) {
		let prevList = prev.class ? prev.class.split(" ").filter(Boolean) : [];
		let curList = cur.class ? cur.class.split(" ").filter(Boolean) : [];
		for (let i = 0; i < prevList.length; i++) if (curList.indexOf(prevList[i]) == -1) dom.classList.remove(prevList[i]);
		for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1) dom.classList.add(curList[i]);
		if (dom.classList.length == 0) dom.removeAttribute("class");
	}
	if (prev.style != cur.style) {
		if (prev.style) {
			let prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m;
			while (m = prop.exec(prev.style)) dom.style.removeProperty(m[1]);
		}
		if (cur.style) dom.style.cssText += cur.style;
	}
}
function applyOuterDeco(dom, deco, node) {
	return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1));
}
function sameOuterDeco(a, b) {
	if (a.length != b.length) return false;
	for (let i = 0; i < a.length; i++) if (!a[i].type.eq(b[i].type)) return false;
	return true;
}
function rm(dom) {
	let next = dom.nextSibling;
	dom.parentNode.removeChild(dom);
	return next;
}
var ViewTreeUpdater = class {
	constructor(top, lock, view) {
		this.lock = lock;
		this.view = view;
		this.index = 0;
		this.stack = [];
		this.changed = false;
		this.top = top;
		this.preMatch = preMatch(top.node.content, top);
	}
	destroyBetween(start, end) {
		if (start == end) return;
		for (let i = start; i < end; i++) this.top.children[i].destroy();
		this.top.children.splice(start, end - start);
		this.changed = true;
	}
	destroyRest() {
		this.destroyBetween(this.index, this.top.children.length);
	}
	syncToMarks(marks, inline, view, parentIndex) {
		let keep = 0, depth = this.stack.length >> 1;
		let maxKeep = Math.min(depth, marks.length);
		while (keep < maxKeep && (keep == depth - 1 ? this.top : this.stack[keep + 1 << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) keep++;
		while (keep < depth) {
			this.destroyRest();
			this.top.dirty = NOT_DIRTY;
			this.index = this.stack.pop();
			this.top = this.stack.pop();
			depth--;
		}
		while (depth < marks.length) {
			this.stack.push(this.top, this.index + 1);
			let found = -1, scanTo = this.top.children.length;
			if (parentIndex < this.preMatch.index) scanTo = Math.min(this.index + 3, scanTo);
			for (let i = this.index; i < scanTo; i++) {
				let next = this.top.children[i];
				if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) {
					found = i;
					break;
				}
			}
			if (found > -1) {
				if (found > this.index) {
					this.changed = true;
					this.destroyBetween(this.index, found);
				}
				this.top = this.top.children[this.index];
			} else {
				let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view);
				this.top.children.splice(this.index, 0, markDesc);
				this.top = markDesc;
				this.changed = true;
			}
			this.index = 0;
			depth++;
		}
	}
	findNodeMatch(node, outerDeco, innerDeco, index) {
		let found = -1, targetDesc;
		if (index >= this.preMatch.index && (targetDesc = this.preMatch.matches[index - this.preMatch.index]).parent == this.top && targetDesc.matchesNode(node, outerDeco, innerDeco)) found = this.top.children.indexOf(targetDesc, this.index);
		else for (let i = this.index, e = Math.min(this.top.children.length, i + 5); i < e; i++) {
			let child = this.top.children[i];
			if (child.matchesNode(node, outerDeco, innerDeco) && !this.preMatch.matched.has(child)) {
				found = i;
				break;
			}
		}
		if (found < 0) return false;
		this.destroyBetween(this.index, found);
		this.index++;
		return true;
	}
	updateNodeAt(node, outerDeco, innerDeco, index, view) {
		let child = this.top.children[index];
		if (child.dirty == NODE_DIRTY && child.dom == child.contentDOM) child.dirty = CONTENT_DIRTY;
		if (!child.update(node, outerDeco, innerDeco, view)) return false;
		this.destroyBetween(this.index, index);
		this.index++;
		return true;
	}
	findIndexWithChild(domNode) {
		for (;;) {
			let parent = domNode.parentNode;
			if (!parent) return -1;
			if (parent == this.top.contentDOM) {
				let desc = domNode.pmViewDesc;
				if (desc) {
					for (let i = this.index; i < this.top.children.length; i++) if (this.top.children[i] == desc) return i;
				}
				return -1;
			}
			domNode = parent;
		}
	}
	updateNextNode(node, outerDeco, innerDeco, view, index, pos) {
		for (let i = this.index; i < this.top.children.length; i++) {
			let next = this.top.children[i];
			if (next instanceof NodeViewDesc) {
				let preMatch = this.preMatch.matched.get(next);
				if (preMatch != null && preMatch != index) return false;
				let nextDOM = next.dom, updated;
				let locked = this.isLocked(nextDOM) && !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco));
				if (!locked && next.update(node, outerDeco, innerDeco, view)) {
					this.destroyBetween(this.index, i);
					if (next.dom != nextDOM) this.changed = true;
					this.index++;
					return true;
				} else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
					this.destroyBetween(this.index, i);
					this.top.children[this.index] = updated;
					if (updated.contentDOM) {
						updated.dirty = CONTENT_DIRTY;
						updated.updateChildren(view, pos + 1);
						updated.dirty = NOT_DIRTY;
					}
					this.changed = true;
					this.index++;
					return true;
				}
				break;
			}
		}
		return false;
	}
	recreateWrapper(next, node, outerDeco, innerDeco, view, pos) {
		if (next.dirty || node.isAtom || !next.children.length || !next.node.content.eq(node.content) || !sameOuterDeco(outerDeco, next.outerDeco) || !innerDeco.eq(next.innerDeco)) return null;
		let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
		if (wrapper.contentDOM) {
			wrapper.children = next.children;
			next.children = [];
			for (let ch of wrapper.children) ch.parent = wrapper;
		}
		next.destroy();
		return wrapper;
	}
	addNode(node, outerDeco, innerDeco, view, pos) {
		let desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
		if (desc.contentDOM) desc.updateChildren(view, pos + 1);
		this.top.children.splice(this.index++, 0, desc);
		this.changed = true;
	}
	placeWidget(widget, view, pos) {
		let next = this.index < this.top.children.length ? this.top.children[this.index] : null;
		if (next && next.matchesWidget(widget) && (widget == next.widget || !next.widget.type.toDOM.parentNode)) this.index++;
		else {
			let desc = new WidgetViewDesc(this.top, widget, view, pos);
			this.top.children.splice(this.index++, 0, desc);
			this.changed = true;
		}
	}
	addTextblockHacks() {
		let lastChild = this.top.children[this.index - 1], parent = this.top;
		while (lastChild instanceof MarkViewDesc) {
			parent = lastChild;
			lastChild = parent.children[parent.children.length - 1];
		}
		if (!lastChild || !(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text) || this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text)) {
			if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") this.addHackNode("IMG", parent);
			this.addHackNode("BR", this.top);
		}
	}
	addHackNode(nodeName, parent) {
		if (parent == this.top && this.index < parent.children.length && parent.children[this.index].matchesHack(nodeName)) this.index++;
		else {
			let dom = document.createElement(nodeName);
			if (nodeName == "IMG") {
				dom.className = "ProseMirror-separator";
				dom.alt = "";
			}
			if (nodeName == "BR") dom.className = "ProseMirror-trailingBreak";
			let hack = new TrailingHackViewDesc(this.top, [], dom, null);
			if (parent != this.top) parent.children.push(hack);
			else parent.children.splice(this.index++, 0, hack);
			this.changed = true;
		}
	}
	isLocked(node) {
		return this.lock && (node == this.lock || node.nodeType == 1 && node.contains(this.lock.parentNode));
	}
};
function preMatch(frag, parentDesc) {
	let curDesc = parentDesc, descI = curDesc.children.length;
	let fI = frag.childCount, matched = /* @__PURE__ */ new Map(), matches = [];
	outer: while (fI > 0) {
		let desc;
		for (;;) if (descI) {
			let next = curDesc.children[descI - 1];
			if (next instanceof MarkViewDesc) {
				curDesc = next;
				descI = next.children.length;
			} else {
				desc = next;
				descI--;
				break;
			}
		} else if (curDesc == parentDesc) break outer;
		else {
			descI = curDesc.parent.children.indexOf(curDesc);
			curDesc = curDesc.parent;
		}
		let node = desc.node;
		if (!node) continue;
		if (node != frag.child(fI - 1)) break;
		--fI;
		matched.set(desc, fI);
		matches.push(desc);
	}
	return {
		index: fI,
		matched,
		matches: matches.reverse()
	};
}
function compareSide(a, b) {
	return a.type.side - b.type.side;
}
function iterDeco(parent, deco, onWidget, onNode) {
	let locals = deco.locals(parent), offset = 0;
	if (locals.length == 0) {
		for (let i = 0; i < parent.childCount; i++) {
			let child = parent.child(i);
			onNode(child, locals, deco.forChild(offset, child), i);
			offset += child.nodeSize;
		}
		return;
	}
	let decoIndex = 0, active = [], restNode = null;
	for (let parentIndex = 0;;) {
		let widget, widgets;
		while (decoIndex < locals.length && locals[decoIndex].to == offset) {
			let next = locals[decoIndex++];
			if (next.widget) {
				if (!widget) widget = next;
				else (widgets || (widgets = [widget])).push(next);
			}
		}
		if (widget) {
			if (widgets) {
				widgets.sort(compareSide);
				for (let i = 0; i < widgets.length; i++) onWidget(widgets[i], parentIndex, !!restNode);
			} else onWidget(widget, parentIndex, !!restNode);
		}
		let child, index;
		if (restNode) {
			index = -1;
			child = restNode;
			restNode = null;
		} else if (parentIndex < parent.childCount) {
			index = parentIndex;
			child = parent.child(parentIndex++);
		} else break;
		for (let i = 0; i < active.length; i++) if (active[i].to <= offset) active.splice(i--, 1);
		while (decoIndex < locals.length && locals[decoIndex].from <= offset && locals[decoIndex].to > offset) active.push(locals[decoIndex++]);
		let end = offset + child.nodeSize;
		if (child.isText) {
			let cutAt = end;
			if (decoIndex < locals.length && locals[decoIndex].from < cutAt) cutAt = locals[decoIndex].from;
			for (let i = 0; i < active.length; i++) if (active[i].to < cutAt) cutAt = active[i].to;
			if (cutAt < end) {
				restNode = child.cut(cutAt - offset);
				child = child.cut(0, cutAt - offset);
				end = cutAt;
				index = -1;
			}
		} else while (decoIndex < locals.length && locals[decoIndex].to < end) decoIndex++;
		let outerDeco = child.isInline && !child.isLeaf ? active.filter((d) => !d.inline) : active.slice();
		onNode(child, outerDeco, deco.forChild(offset, child), index);
		offset = end;
	}
}
function iosHacks(dom) {
	if (dom.nodeName == "UL" || dom.nodeName == "OL") {
		let oldCSS = dom.style.cssText;
		dom.style.cssText = oldCSS + "; list-style: square !important";
		window.getComputedStyle(dom).listStyle;
		dom.style.cssText = oldCSS;
	}
}
function findTextInFragment(frag, text, from, to) {
	for (let i = 0, pos = 0; i < frag.childCount && pos <= to;) {
		let child = frag.child(i++), childStart = pos;
		pos += child.nodeSize;
		if (!child.isText) continue;
		let str = child.text;
		while (i < frag.childCount) {
			let next = frag.child(i++);
			pos += next.nodeSize;
			if (!next.isText) break;
			str += next.text;
		}
		if (pos >= from) {
			if (pos >= to && str.slice(to - text.length - childStart, to - childStart) == text) return to - text.length;
			let found = childStart < to ? str.lastIndexOf(text, to - childStart - 1) : -1;
			if (found >= 0 && found + text.length + childStart >= from) return childStart + found;
			if (from == to && str.length >= to + text.length - childStart && str.slice(to - childStart, to - childStart + text.length) == text) return to;
		}
	}
	return -1;
}
function replaceNodes(nodes, from, to, view, replacement) {
	let result = [];
	for (let i = 0, off = 0; i < nodes.length; i++) {
		let child = nodes[i], start = off, end = off += child.size;
		if (start >= to || end <= from) result.push(child);
		else {
			if (start < from) result.push(child.slice(0, from - start, view));
			if (replacement) {
				result.push(replacement);
				replacement = void 0;
			}
			if (end > to) result.push(child.slice(to - start, child.size, view));
		}
	}
	return result;
}
function selectionFromDOM(view, origin = null) {
	let domSel = view.domSelectionRange(), doc = view.state.doc;
	if (!domSel.focusNode) return null;
	let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0;
	let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1);
	if (head < 0) return null;
	let $head = doc.resolve(head), anchor, selection;
	if (selectionCollapsed(domSel)) {
		anchor = head;
		while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent;
		let nearestDescNode = nearestDesc.node;
		if (nearestDesc && nearestDescNode.isAtom && NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) {
			let pos = nearestDesc.posBefore;
			selection = new NodeSelection(head == pos ? $head : doc.resolve(pos));
		}
	} else {
		if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) {
			let min = head, max = head;
			for (let i = 0; i < domSel.rangeCount; i++) {
				let range = domSel.getRangeAt(i);
				min = Math.min(min, view.docView.posFromDOM(range.startContainer, range.startOffset, 1));
				max = Math.max(max, view.docView.posFromDOM(range.endContainer, range.endOffset, -1));
			}
			if (min < 0) return null;
			[anchor, head] = max == view.state.selection.anchor ? [max, min] : [min, max];
			$head = doc.resolve(head);
		} else anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1);
		if (anchor < 0) return null;
	}
	let $anchor = doc.resolve(anchor);
	if (!selection) {
		let bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1;
		selection = selectionBetween(view, $anchor, $head, bias);
	}
	return selection;
}
function editorOwnsSelection(view) {
	return view.editable ? view.hasFocus() : hasSelection(view) && document.activeElement && document.activeElement.contains(view.dom);
}
function selectionToDOM(view, force = false) {
	let sel = view.state.selection;
	syncNodeSelection(view, sel);
	if (!editorOwnsSelection(view)) return;
	let mouseDown = view.input.mouseDown;
	if (!force && chrome && mouseDown) {
		let domSel = view.domSelectionRange(), curSel = view.domObserver.currentSelection;
		if (domSel.anchorNode && curSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset) && mouseDown.delaySelUpdate()) {
			view.domObserver.setCurSelection();
			return;
		}
	}
	view.domObserver.disconnectSelection();
	if (view.cursorWrapper) selectCursorWrapper(view);
	else {
		let { anchor, head } = sel, resetEditableFrom, resetEditableTo;
		if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {
			if (!sel.$from.parent.inlineContent) resetEditableFrom = temporarilyEditableNear(view, sel.from);
			if (!sel.empty && !sel.$from.parent.inlineContent) resetEditableTo = temporarilyEditableNear(view, sel.to);
		}
		view.docView.setSelection(anchor, head, view, force);
		if (brokenSelectBetweenUneditable) {
			if (resetEditableFrom) resetEditable(resetEditableFrom);
			if (resetEditableTo) resetEditable(resetEditableTo);
		}
		if (sel.visible) view.dom.classList.remove("ProseMirror-hideselection");
		else {
			view.dom.classList.add("ProseMirror-hideselection");
			if ("onselectionchange" in document) removeClassOnSelectionChange(view);
		}
	}
	view.domObserver.setCurSelection();
	view.domObserver.connectSelection();
}
var brokenSelectBetweenUneditable = safari || chrome && chrome_version < 63;
function temporarilyEditableNear(view, pos) {
	let { node, offset } = view.docView.domFromPos(pos, 0);
	let after = offset < node.childNodes.length ? node.childNodes[offset] : null;
	let before = offset ? node.childNodes[offset - 1] : null;
	if (safari && after && after.contentEditable == "false") return setEditable(after);
	if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) {
		if (after) return setEditable(after);
		else if (before) return setEditable(before);
	}
}
function setEditable(element) {
	element.contentEditable = "true";
	if (safari && element.draggable) {
		element.draggable = false;
		element.wasDraggable = true;
	}
	return element;
}
function resetEditable(element) {
	element.contentEditable = "false";
	if (element.wasDraggable) {
		element.draggable = true;
		element.wasDraggable = null;
	}
}
function removeClassOnSelectionChange(view) {
	let doc = view.dom.ownerDocument;
	doc.removeEventListener("selectionchange", view.input.hideSelectionGuard);
	let domSel = view.domSelectionRange();
	let node = domSel.anchorNode, offset = domSel.anchorOffset;
	doc.addEventListener("selectionchange", view.input.hideSelectionGuard = () => {
		if (domSel.anchorNode != node || domSel.anchorOffset != offset) {
			doc.removeEventListener("selectionchange", view.input.hideSelectionGuard);
			setTimeout(() => {
				if (!editorOwnsSelection(view) || view.state.selection.visible) view.dom.classList.remove("ProseMirror-hideselection");
			}, 20);
		}
	});
}
function selectCursorWrapper(view) {
	let domSel = view.domSelection();
	if (!domSel) return;
	let node = view.cursorWrapper.dom, img = node.nodeName == "IMG";
	if (img) domSel.collapse(node.parentNode, domIndex(node) + 1);
	else domSel.collapse(node, 0);
	if (!img && !view.state.selection.visible && ie$1 && ie_version <= 11) {
		node.disabled = true;
		node.disabled = false;
	}
}
function syncNodeSelection(view, sel) {
	if (sel instanceof NodeSelection) {
		let desc = view.docView.descAt(sel.from);
		if (desc != view.lastSelectedViewDesc) {
			clearNodeSelection(view);
			if (desc) desc.selectNode();
			view.lastSelectedViewDesc = desc;
		}
	} else clearNodeSelection(view);
}
function clearNodeSelection(view) {
	if (view.lastSelectedViewDesc) {
		if (view.lastSelectedViewDesc.parent) view.lastSelectedViewDesc.deselectNode();
		view.lastSelectedViewDesc = void 0;
	}
}
function selectionBetween(view, $anchor, $head, bias) {
	return view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias);
}
function hasFocusAndSelection(view) {
	if (view.editable && !view.hasFocus()) return false;
	return hasSelection(view);
}
function hasSelection(view) {
	let sel = view.domSelectionRange();
	if (!sel.anchorNode) return false;
	try {
		return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode));
	} catch (_) {
		return false;
	}
}
function anchorInRightPlace(view) {
	let anchorDOM = view.docView.domFromPos(view.state.selection.anchor, 0);
	let domSel = view.domSelectionRange();
	return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset);
}
function moveSelectionBlock(state, dir) {
	let { $anchor, $head } = state.selection;
	let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head);
	let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null;
	return $start && Selection$1.findFrom($start, dir);
}
function apply(view, sel) {
	view.dispatch(view.state.tr.setSelection(sel).scrollIntoView());
	return true;
}
function selectHorizontally(view, dir, mods) {
	let sel = view.state.selection;
	if (sel instanceof TextSelection) {
		if (mods.indexOf("s") > -1) {
			let { $head } = sel, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter;
			if (!node || node.isText || !node.isLeaf) return false;
			let $newHead = view.state.doc.resolve($head.pos + node.nodeSize * (dir < 0 ? -1 : 1));
			return apply(view, new TextSelection(sel.$anchor, $newHead));
		} else if (!sel.empty) return false;
		else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
			let next = moveSelectionBlock(view.state, dir);
			if (next && next instanceof NodeSelection) return apply(view, next);
			return false;
		} else if (!(mac$2 && mods.indexOf("m") > -1)) {
			let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc;
			if (!node || node.isText) return false;
			let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos;
			if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false;
			if (NodeSelection.isSelectable(node)) return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head));
			else if (webkit) return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)));
			else return false;
		}
	} else if (sel instanceof NodeSelection && sel.node.isInline) return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from));
	else {
		let next = moveSelectionBlock(view.state, dir);
		if (next) return apply(view, next);
		return false;
	}
}
function nodeLen(node) {
	return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
}
function isIgnorable(dom, dir) {
	let desc = dom.pmViewDesc;
	return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR");
}
function skipIgnoredNodes(view, dir) {
	return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view);
}
function skipIgnoredNodesBefore(view) {
	let sel = view.domSelectionRange();
	let node = sel.focusNode, offset = sel.focusOffset;
	if (!node) return;
	let moveNode, moveOffset, force = false;
	if (gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset], -1)) force = true;
	for (;;) if (offset > 0) {
		if (node.nodeType != 1) break;
		else {
			let before = node.childNodes[offset - 1];
			if (isIgnorable(before, -1)) {
				moveNode = node;
				moveOffset = --offset;
			} else if (before.nodeType == 3) {
				node = before;
				offset = node.nodeValue.length;
			} else break;
		}
	} else if (isBlockNode(node)) break;
	else {
		let prev = node.previousSibling;
		while (prev && isIgnorable(prev, -1)) {
			moveNode = node.parentNode;
			moveOffset = domIndex(prev);
			prev = prev.previousSibling;
		}
		if (!prev) {
			node = node.parentNode;
			if (node == view.dom) break;
			offset = 0;
		} else {
			node = prev;
			offset = nodeLen(node);
		}
	}
	if (force) setSelFocus(view, node, offset);
	else if (moveNode) setSelFocus(view, moveNode, moveOffset);
}
function skipIgnoredNodesAfter(view) {
	let sel = view.domSelectionRange();
	let node = sel.focusNode, offset = sel.focusOffset;
	if (!node) return;
	let len = nodeLen(node);
	let moveNode, moveOffset;
	for (;;) if (offset < len) {
		if (node.nodeType != 1) break;
		let after = node.childNodes[offset];
		if (isIgnorable(after, 1)) {
			moveNode = node;
			moveOffset = ++offset;
		} else break;
	} else if (isBlockNode(node)) break;
	else {
		let next = node.nextSibling;
		while (next && isIgnorable(next, 1)) {
			moveNode = next.parentNode;
			moveOffset = domIndex(next) + 1;
			next = next.nextSibling;
		}
		if (!next) {
			node = node.parentNode;
			if (node == view.dom) break;
			offset = len = 0;
		} else {
			node = next;
			offset = 0;
			len = nodeLen(node);
		}
	}
	if (moveNode) setSelFocus(view, moveNode, moveOffset);
}
function isBlockNode(dom) {
	let desc = dom.pmViewDesc;
	return desc && desc.node && desc.node.isBlock;
}
function textNodeAfter(node, offset) {
	while (node && offset == node.childNodes.length && !hasBlockDesc(node)) {
		offset = domIndex(node) + 1;
		node = node.parentNode;
	}
	while (node && offset < node.childNodes.length) {
		let next = node.childNodes[offset];
		if (next.nodeType == 3) return next;
		if (next.nodeType == 1 && next.contentEditable == "false") break;
		node = next;
		offset = 0;
	}
}
function textNodeBefore(node, offset) {
	while (node && !offset && !hasBlockDesc(node)) {
		offset = domIndex(node);
		node = node.parentNode;
	}
	while (node && offset) {
		let next = node.childNodes[offset - 1];
		if (next.nodeType == 3) return next;
		if (next.nodeType == 1 && next.contentEditable == "false") break;
		node = next;
		offset = node.childNodes.length;
	}
}
function setSelFocus(view, node, offset) {
	if (node.nodeType != 3) {
		let before, after;
		if (after = textNodeAfter(node, offset)) {
			node = after;
			offset = 0;
		} else if (before = textNodeBefore(node, offset)) {
			node = before;
			offset = before.nodeValue.length;
		}
	}
	let sel = view.domSelection();
	if (!sel) return;
	if (selectionCollapsed(sel)) {
		let range = document.createRange();
		range.setEnd(node, offset);
		range.setStart(node, offset);
		sel.removeAllRanges();
		sel.addRange(range);
	} else if (sel.extend) sel.extend(node, offset);
	view.domObserver.setCurSelection();
	let { state } = view;
	setTimeout(() => {
		if (view.state == state) selectionToDOM(view);
	}, 50);
}
function findDirection(view, pos) {
	let $pos = view.state.doc.resolve(pos);
	if (!(chrome || windows$1) && $pos.parent.inlineContent) {
		let coords = view.coordsAtPos(pos);
		if (pos > $pos.start()) {
			let before = view.coordsAtPos(pos - 1);
			let mid = (before.top + before.bottom) / 2;
			if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1) return before.left < coords.left ? "ltr" : "rtl";
		}
		if (pos < $pos.end()) {
			let after = view.coordsAtPos(pos + 1);
			let mid = (after.top + after.bottom) / 2;
			if (mid > coords.top && mid < coords.bottom && Math.abs(after.left - coords.left) > 1) return after.left > coords.left ? "ltr" : "rtl";
		}
	}
	return getComputedStyle(view.dom).direction == "rtl" ? "rtl" : "ltr";
}
function selectVertically(view, dir, mods) {
	let sel = view.state.selection;
	if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) return false;
	if (mac$2 && mods.indexOf("m") > -1) return false;
	let { $from, $to } = sel;
	if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) {
		let next = moveSelectionBlock(view.state, dir);
		if (next && next instanceof NodeSelection) return apply(view, next);
	}
	if (!$from.parent.inlineContent) {
		let side = dir < 0 ? $from : $to;
		let beyond = sel instanceof AllSelection ? Selection$1.near(side, dir) : Selection$1.findFrom(side, dir);
		return beyond ? apply(view, beyond) : false;
	}
	return false;
}
function stopNativeHorizontalDelete(view, dir) {
	if (!(view.state.selection instanceof TextSelection)) return true;
	let { $head, $anchor, empty } = view.state.selection;
	if (!$head.sameParent($anchor)) return true;
	if (!empty) return false;
	if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) return true;
	let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter);
	if (nextNode && !nextNode.isText) {
		let tr = view.state.tr;
		if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos);
		else tr.delete($head.pos, $head.pos + nextNode.nodeSize);
		view.dispatch(tr);
		return true;
	}
	return false;
}
function switchEditable(view, node, state) {
	view.domObserver.stop();
	node.contentEditable = state;
	view.domObserver.start();
}
function safariDownArrowBug(view) {
	if (!safari || view.state.selection.$head.parentOffset > 0) return false;
	let { focusNode, focusOffset } = view.domSelectionRange();
	if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && focusNode.firstChild && focusNode.firstChild.contentEditable == "false") {
		let child = focusNode.firstChild;
		switchEditable(view, child, "true");
		setTimeout(() => switchEditable(view, child, "false"), 20);
	}
	return false;
}
function getMods(event) {
	let result = "";
	if (event.ctrlKey) result += "c";
	if (event.metaKey) result += "m";
	if (event.altKey) result += "a";
	if (event.shiftKey) result += "s";
	return result;
}
function captureKeyDown(view, event) {
	let code = event.keyCode, mods = getMods(event);
	if (code == 8 || mac$2 && code == 72 && mods == "c") return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1);
	else if (code == 46 && !event.shiftKey || mac$2 && code == 68 && mods == "c") return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1);
	else if (code == 13 || code == 27) return true;
	else if (code == 37 || mac$2 && code == 66 && mods == "c") {
		let dir = code == 37 ? findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1 : -1;
		return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir);
	} else if (code == 39 || mac$2 && code == 70 && mods == "c") {
		let dir = code == 39 ? findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1 : 1;
		return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir);
	} else if (code == 38 || mac$2 && code == 80 && mods == "c") return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1);
	else if (code == 40 || mac$2 && code == 78 && mods == "c") return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodes(view, 1);
	else if (mods == (mac$2 ? "m" : "c") && (code == 66 || code == 73 || code == 89 || code == 90)) return true;
	return false;
}
function serializeForClipboard(view, slice) {
	view.someProp("transformCopied", (f) => {
		slice = f(slice, view);
	});
	let context = [], { content, openStart, openEnd } = slice;
	while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) {
		openStart--;
		openEnd--;
		let node = content.firstChild;
		context.push(node.type.name, node.attrs != node.type.defaultAttrs ? node.attrs : null);
		content = node.content;
	}
	let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema);
	let doc = detachedDoc(), wrap = doc.createElement("div");
	wrap.appendChild(serializer.serializeFragment(content, { document: doc }));
	let firstChild = wrap.firstChild, needsWrap, wrappers = 0;
	while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {
		for (let i = needsWrap.length - 1; i >= 0; i--) {
			let wrapper = doc.createElement(needsWrap[i]);
			while (wrap.firstChild) wrapper.appendChild(wrap.firstChild);
			wrap.appendChild(wrapper);
			wrappers++;
		}
		firstChild = wrap.firstChild;
	}
	if (firstChild && firstChild.nodeType == 1) firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`);
	return {
		dom: wrap,
		text: view.someProp("clipboardTextSerializer", (f) => f(slice, view)) || slice.content.textBetween(0, slice.content.size, "\n\n"),
		slice
	};
}
function parseFromClipboard(view, text, html, plainText, $context) {
	let inCode = $context.parent.type.spec.code;
	let dom, slice;
	if (!html && !text) return null;
	let asText = !!text && (plainText || inCode || !html);
	if (asText) {
		view.someProp("transformPastedText", (f) => {
			text = f(text, inCode || plainText, view);
		});
		if (inCode) {
			slice = new Slice(Fragment$8.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0);
			view.someProp("transformPasted", (f) => {
				slice = f(slice, view, true);
			});
			return slice;
		}
		let parsed = view.someProp("clipboardTextParser", (f) => f(text, $context, plainText, view));
		if (parsed) slice = parsed;
		else {
			let marks = $context.marks();
			let { schema } = view.state, serializer = DOMSerializer.fromSchema(schema);
			dom = document.createElement("div");
			text.split(/(?:\r\n?|\n)+/).forEach((block) => {
				let p = dom.appendChild(document.createElement("p"));
				if (block) p.appendChild(serializer.serializeNode(schema.text(block, marks)));
			});
		}
	} else {
		view.someProp("transformPastedHTML", (f) => {
			html = f(html, view);
		});
		dom = readHTML(html);
		if (webkit) restoreReplacedSpaces(dom);
	}
	let contextNode = dom && dom.querySelector("[data-pm-slice]");
	let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || "");
	if (sliceData && sliceData[3]) for (let i = +sliceData[3]; i > 0; i--) {
		let child = dom.firstChild;
		while (child && child.nodeType != 1) child = child.nextSibling;
		if (!child) break;
		dom = child;
	}
	if (!slice) slice = (view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser$1.fromSchema(view.state.schema)).parseSlice(dom, {
		preserveWhitespace: !!(asText || sliceData),
		context: $context,
		ruleFromNode(dom) {
			if (dom.nodeName == "BR" && !dom.nextSibling && dom.parentNode && !inlineParents.test(dom.parentNode.nodeName)) return { ignore: true };
			return null;
		}
	});
	if (sliceData) slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[4]);
	else {
		slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), true);
		if (slice.openStart || slice.openEnd) {
			let openStart = 0, openEnd = 0;
			for (let node = slice.content.firstChild; openStart < slice.openStart && !node.type.spec.isolating; openStart++, node = node.firstChild);
			for (let node = slice.content.lastChild; openEnd < slice.openEnd && !node.type.spec.isolating; openEnd++, node = node.lastChild);
			slice = closeSlice(slice, openStart, openEnd);
		}
	}
	view.someProp("transformPasted", (f) => {
		slice = f(slice, view, asText);
	});
	return slice;
}
var inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;
function normalizeSiblings(fragment, $context) {
	if (fragment.childCount < 2) return fragment;
	for (let d = $context.depth; d >= 0; d--) {
		let match = $context.node(d).contentMatchAt($context.index(d));
		let lastWrap, result = [];
		fragment.forEach((node) => {
			if (!result) return;
			let wrap = match.findWrapping(node.type), inLast;
			if (!wrap) return result = null;
			if (inLast = result.length && lastWrap.length && addToSibling(wrap, lastWrap, node, result[result.length - 1], 0)) result[result.length - 1] = inLast;
			else {
				if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length);
				let wrapped = withWrappers(node, wrap);
				result.push(wrapped);
				match = match.matchType(wrapped.type);
				lastWrap = wrap;
			}
		});
		if (result) return Fragment$8.from(result);
	}
	return fragment;
}
function withWrappers(node, wrap, from = 0) {
	for (let i = wrap.length - 1; i >= from; i--) node = wrap[i].create(null, Fragment$8.from(node));
	return node;
}
function addToSibling(wrap, lastWrap, node, sibling, depth) {
	if (depth < wrap.length && depth < lastWrap.length && wrap[depth] == lastWrap[depth]) {
		let inner = addToSibling(wrap, lastWrap, node, sibling.lastChild, depth + 1);
		if (inner) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner));
		if (sibling.contentMatchAt(sibling.childCount).matchType(depth == wrap.length - 1 ? node.type : wrap[depth + 1])) return sibling.copy(sibling.content.append(Fragment$8.from(withWrappers(node, wrap, depth + 1))));
	}
}
function closeRight(node, depth) {
	if (depth == 0) return node;
	let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1));
	let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment$8.empty, true);
	return node.copy(fragment.append(fill));
}
function closeRange(fragment, side, from, to, depth, openEnd) {
	let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content;
	if (fragment.childCount > 1) openEnd = 0;
	if (depth < to - 1) inner = closeRange(inner, side, from, to, depth + 1, openEnd);
	if (depth >= from) inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, openEnd <= depth).append(inner) : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment$8.empty, true));
	return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner));
}
function closeSlice(slice, openStart, openEnd) {
	if (openStart < slice.openStart) slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd);
	if (openEnd < slice.openEnd) slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd);
	return slice;
}
var wrapMap = {
	thead: ["table"],
	tbody: ["table"],
	tfoot: ["table"],
	caption: ["table"],
	colgroup: ["table"],
	col: ["table", "colgroup"],
	tr: ["table", "tbody"],
	td: [
		"table",
		"tbody",
		"tr"
	],
	th: [
		"table",
		"tbody",
		"tr"
	]
};
var _detachedDoc = null;
function detachedDoc() {
	return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title"));
}
var _policy = null;
function maybeWrapTrusted(html) {
	let trustedTypes = window.trustedTypes;
	if (!trustedTypes) return html;
	if (!_policy) _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
	return _policy.createHTML(html);
}
function readHTML(html) {
	let metas = /^(\s*<meta [^>]*>)*/.exec(html);
	if (metas) html = html.slice(metas[0].length);
	let elt = detachedDoc().createElement("div");
	let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap;
	if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()]) html = wrap.map((n) => "<" + n + ">").join("") + html + wrap.map((n) => "</" + n + ">").reverse().join("");
	elt.innerHTML = maybeWrapTrusted(html);
	if (wrap) for (let i = 0; i < wrap.length; i++) elt = elt.querySelector(wrap[i]) || elt;
	return elt;
}
function restoreReplacedSpaces(dom) {
	let nodes = dom.querySelectorAll(chrome ? "span:not([class]):not([style])" : "span.Apple-converted-space");
	for (let i = 0; i < nodes.length; i++) {
		let node = nodes[i];
		if (node.childNodes.length == 1 && node.textContent == "\xA0" && node.parentNode) node.parentNode.replaceChild(dom.ownerDocument.createTextNode(" "), node);
	}
}
function addContext(slice, context) {
	if (!slice.size) return slice;
	let schema = slice.content.firstChild.type.schema, array;
	try {
		array = JSON.parse(context);
	} catch (e) {
		return slice;
	}
	let { content, openStart, openEnd } = slice;
	for (let i = array.length - 2; i >= 0; i -= 2) {
		let type = schema.nodes[array[i]];
		if (!type || type.hasRequiredAttrs()) break;
		content = Fragment$8.from(type.create(array[i + 1], content));
		openStart++;
		openEnd++;
	}
	return new Slice(content, openStart, openEnd);
}
var handlers = {};
var editHandlers = {};
var passiveHandlers = {
	touchstart: true,
	touchmove: true
};
var InputState = class {
	constructor() {
		this.shiftKey = false;
		this.mouseDown = null;
		this.lastKeyCode = null;
		this.lastKeyCodeTime = 0;
		this.lastClick = {
			time: 0,
			x: 0,
			y: 0,
			type: "",
			button: 0
		};
		this.lastSelectionOrigin = null;
		this.lastSelectionTime = 0;
		this.lastIOSEnter = 0;
		this.lastIOSEnterFallbackTimeout = -1;
		this.lastFocus = 0;
		this.lastTouch = 0;
		this.lastChromeDelete = 0;
		this.composing = false;
		this.compositionNode = null;
		this.composingTimeout = -1;
		this.compositionNodes = [];
		this.compositionEndedAt = -2e8;
		this.compositionID = 1;
		this.badSafariComposition = false;
		this.compositionPendingChanges = 0;
		this.domChangeCount = 0;
		this.eventHandlers = Object.create(null);
		this.hideSelectionGuard = null;
	}
};
function initInput(view) {
	for (let event in handlers) {
		let handler = handlers[event];
		view.dom.addEventListener(event, view.input.eventHandlers[event] = (event) => {
			if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && (view.editable || !(event.type in editHandlers))) handler(view, event);
		}, passiveHandlers[event] ? { passive: true } : void 0);
	}
	if (safari) view.dom.addEventListener("input", () => null);
	ensureListeners(view);
}
function setSelectionOrigin(view, origin) {
	view.input.lastSelectionOrigin = origin;
	view.input.lastSelectionTime = Date.now();
}
function destroyInput(view) {
	if (view.input.mouseDown) view.input.mouseDown.done();
	view.domObserver.stop();
	for (let type in view.input.eventHandlers) view.dom.removeEventListener(type, view.input.eventHandlers[type]);
	clearTimeout(view.input.composingTimeout);
	clearTimeout(view.input.lastIOSEnterFallbackTimeout);
}
function ensureListeners(view) {
	view.someProp("handleDOMEvents", (currentHandlers) => {
		for (let type in currentHandlers) if (!view.input.eventHandlers[type]) view.dom.addEventListener(type, view.input.eventHandlers[type] = (event) => runCustomHandler(view, event));
	});
}
function runCustomHandler(view, event) {
	return view.someProp("handleDOMEvents", (handlers) => {
		let handler = handlers[event.type];
		return handler ? handler(view, event) || event.defaultPrevented : false;
	});
}
function eventBelongsToView(view, event) {
	if (!event.bubbles) return true;
	if (event.defaultPrevented) return false;
	for (let node = event.target; node != view.dom; node = node.parentNode) if (!node || node.nodeType == 11 || node.pmViewDesc && node.pmViewDesc.stopEvent(event)) return false;
	return true;
}
function dispatchEvent(view, event) {
	if (!runCustomHandler(view, event) && handlers[event.type] && (view.editable || !(event.type in editHandlers))) handlers[event.type](view, event);
}
editHandlers.keydown = (view, _event) => {
	let event = _event;
	view.input.shiftKey = event.keyCode == 16 || event.shiftKey;
	if (inOrNearComposition(view)) return;
	view.input.lastKeyCode = event.keyCode;
	view.input.lastKeyCodeTime = Date.now();
	if (android && chrome && event.keyCode == 13) return;
	if (event.keyCode != 229) view.domObserver.forceFlush();
	if (ios && event.keyCode == 13 && !event.ctrlKey && !event.altKey && !event.metaKey) {
		let now = Date.now();
		view.input.lastIOSEnter = now;
		view.input.lastIOSEnterFallbackTimeout = setTimeout(() => {
			if (view.input.lastIOSEnter == now) {
				view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")));
				view.input.lastIOSEnter = 0;
			}
		}, 200);
	} else if (view.someProp("handleKeyDown", (f) => f(view, event)) || captureKeyDown(view, event)) event.preventDefault();
	else setSelectionOrigin(view, "key");
};
editHandlers.keyup = (view, event) => {
	if (event.keyCode == 16) view.input.shiftKey = false;
};
editHandlers.keypress = (view, _event) => {
	let event = _event;
	if (inOrNearComposition(view) || !event.charCode || event.ctrlKey && !event.altKey || mac$2 && event.metaKey) return;
	if (view.someProp("handleKeyPress", (f) => f(view, event))) {
		event.preventDefault();
		return;
	}
	let sel = view.state.selection;
	if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) {
		let text = String.fromCharCode(event.charCode);
		let deflt = () => view.state.tr.insertText(text).scrollIntoView();
		if (!/[\r\n]/.test(text) && !view.someProp("handleTextInput", (f) => f(view, sel.$from.pos, sel.$to.pos, text, deflt))) view.dispatch(deflt());
		event.preventDefault();
	}
};
function eventCoords(event) {
	return {
		left: event.clientX,
		top: event.clientY
	};
}
function isNear(event, click) {
	let dx = click.x - event.clientX, dy = click.y - event.clientY;
	return dx * dx + dy * dy < 100;
}
function runHandlerOnContext(view, propName, pos, inside, event) {
	if (inside == -1) return false;
	let $pos = view.state.doc.resolve(inside);
	for (let i = $pos.depth + 1; i > 0; i--) if (view.someProp(propName, (f) => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) : f(view, pos, $pos.node(i), $pos.before(i), event, false))) return true;
	return false;
}
function updateSelection(view, selection, origin) {
	if (!view.focused) view.focus();
	if (view.state.selection.eq(selection)) return;
	let tr = view.state.tr.setSelection(selection);
	if (origin == "pointer") tr.setMeta("pointer", true);
	view.dispatch(tr);
}
function selectClickedLeaf(view, inside) {
	if (inside == -1) return false;
	let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter;
	if (node && node.isAtom && NodeSelection.isSelectable(node)) {
		updateSelection(view, new NodeSelection($pos), "pointer");
		return true;
	}
	return false;
}
function selectClickedNode(view, inside) {
	if (inside == -1) return false;
	let sel = view.state.selection, selectedNode, selectAt;
	if (sel instanceof NodeSelection) selectedNode = sel.node;
	let $pos = view.state.doc.resolve(inside);
	for (let i = $pos.depth + 1; i > 0; i--) {
		let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i);
		if (NodeSelection.isSelectable(node)) {
			if (selectedNode && sel.$from.depth > 0 && i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) selectAt = $pos.before(sel.$from.depth);
			else selectAt = $pos.before(i);
			break;
		}
	}
	if (selectAt != null) {
		updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer");
		return true;
	} else return false;
}
function handleSingleClick(view, pos, inside, event, selectNode) {
	return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || view.someProp("handleClick", (f) => f(view, pos, event)) || (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside));
}
function handleDoubleClick(view, pos, inside, event) {
	return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || view.someProp("handleDoubleClick", (f) => f(view, pos, event));
}
function handleTripleClick(view, pos, inside, event) {
	return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || view.someProp("handleTripleClick", (f) => f(view, pos, event)) || defaultTripleClick(view, inside, event);
}
function defaultTripleClick(view, inside, event) {
	if (event.button != 0) return false;
	let selection = selectionForTripleClick(view, inside, true), doc = view.state.doc;
	if (!selection) return false;
	updateSelection(view, selection, "pointer");
	if (selection instanceof TextSelection && doc.eq(view.state.doc)) view.input.mouseDown = new TripleClickDrag(view, selection);
	return true;
}
function selectionForTripleClick(view, inside, selectNodes) {
	let doc = view.state.doc;
	if (inside == -1) return doc.inlineContent ? TextSelection.create(doc, 0, doc.content.size) : null;
	let $pos = doc.resolve(inside);
	for (let i = $pos.depth + 1; i > 0; i--) {
		let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i);
		let nodePos = $pos.before(i);
		if (node.inlineContent) return TextSelection.create(doc, nodePos + 1, nodePos + 1 + node.content.size);
		else if (selectNodes && NodeSelection.isSelectable(node)) return NodeSelection.create(doc, nodePos);
	}
	return null;
}
function forceDOMFlush(view) {
	return endComposition(view);
}
var selectNodeModifier = mac$2 ? "metaKey" : "ctrlKey";
handlers.mousedown = (view, _event) => {
	let event = _event;
	view.input.shiftKey = event.shiftKey;
	let flushed = forceDOMFlush(view);
	let now = Date.now(), type = "singleClick";
	if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier] && view.input.lastClick.button == event.button) {
		if (view.input.lastClick.type == "singleClick") type = "doubleClick";
		else if (view.input.lastClick.type == "doubleClick") type = "tripleClick";
	}
	view.input.lastClick = {
		time: now,
		x: event.clientX,
		y: event.clientY,
		type,
		button: event.button
	};
	if (view.input.mouseDown) view.input.mouseDown.done();
	let pos = view.posAtCoords(eventCoords(event));
	if (!pos) return;
	if (type == "singleClick") view.input.mouseDown = new LeftMouseDown(view, pos, event, !!flushed);
	else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) event.preventDefault();
	else setSelectionOrigin(view, "pointer");
};
var MouseDown = class {
	constructor(view) {
		this.view = view;
		this.mightDrag = null;
		view.root.addEventListener("mouseup", this.up = this.up.bind(this));
		view.root.addEventListener("mousemove", this.move = this.move.bind(this));
	}
	up(event) {
		this.done();
	}
	move(event) {
		if (event.buttons == 0) this.done();
	}
	done() {
		this.view.root.removeEventListener("mouseup", this.up);
		this.view.root.removeEventListener("mousemove", this.move);
		if (this.view.input.mouseDown == this) this.view.input.mouseDown = null;
	}
	delaySelUpdate() {
		return false;
	}
};
var LeftMouseDown = class extends MouseDown {
	constructor(view, pos, event, flushed) {
		super(view);
		this.pos = pos;
		this.event = event;
		this.flushed = flushed;
		this.delayedSelectionSync = false;
		this.startDoc = view.state.doc;
		this.selectNode = !!event[selectNodeModifier];
		this.allowDefault = event.shiftKey;
		let targetNode, targetPos;
		if (pos.inside > -1) {
			targetNode = view.state.doc.nodeAt(pos.inside);
			targetPos = pos.inside;
		} else {
			let $pos = view.state.doc.resolve(pos.pos);
			targetNode = $pos.parent;
			targetPos = $pos.depth ? $pos.before() : 0;
		}
		const target = flushed ? null : event.target;
		const targetDesc = target ? view.docView.nearestDesc(target, true) : null;
		this.target = targetDesc && targetDesc.nodeDOM.nodeType == 1 ? targetDesc.nodeDOM : null;
		let { selection } = view.state;
		if (event.button == 0 && (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos)) this.mightDrag = {
			node: targetNode,
			pos: targetPos,
			addAttr: !!(this.target && !this.target.draggable),
			setUneditable: !!(this.target && gecko && !this.target.hasAttribute("contentEditable"))
		};
		if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) {
			this.view.domObserver.stop();
			if (this.mightDrag.addAttr) this.target.draggable = true;
			if (this.mightDrag.setUneditable) setTimeout(() => {
				if (this.view.input.mouseDown == this) this.target.setAttribute("contentEditable", "false");
			}, 20);
			this.view.domObserver.start();
		}
		setSelectionOrigin(view, "pointer");
	}
	done() {
		super.done();
		if (this.mightDrag && this.target) {
			this.view.domObserver.stop();
			if (this.mightDrag.addAttr) this.target.removeAttribute("draggable");
			if (this.mightDrag.setUneditable) this.target.removeAttribute("contentEditable");
			this.view.domObserver.start();
		}
		if (this.delayedSelectionSync) setTimeout(() => {
			if (!this.view.isDestroyed) selectionToDOM(this.view);
		});
	}
	up(event) {
		this.done();
		if (!this.view.dom.contains(event.target)) return;
		let pos = this.pos;
		if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event));
		this.updateAllowDefault(event);
		if (this.allowDefault || !pos) setSelectionOrigin(this.view, "pointer");
		else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) event.preventDefault();
		else if (event.button == 0 && (this.flushed || safari && this.mightDrag && !this.mightDrag.node.isAtom || chrome && !this.view.state.selection.visible && Math.min(Math.abs(pos.pos - this.view.state.selection.from), Math.abs(pos.pos - this.view.state.selection.to)) <= 2)) {
			updateSelection(this.view, Selection$1.near(this.view.state.doc.resolve(pos.pos)), "pointer");
			event.preventDefault();
		} else setSelectionOrigin(this.view, "pointer");
	}
	move(event) {
		this.updateAllowDefault(event);
		setSelectionOrigin(this.view, "pointer");
		super.move(event);
	}
	updateAllowDefault(event) {
		if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || Math.abs(this.event.y - event.clientY) > 4)) this.allowDefault = true;
	}
	delaySelUpdate() {
		if (!this.allowDefault) return false;
		this.delayedSelectionSync = true;
		return true;
	}
};
var TripleClickDrag = class extends MouseDown {
	constructor(view, startSelection) {
		super(view);
		this.startSelection = startSelection;
		this.startDoc = view.state.doc;
	}
	move(event) {
		if (event.buttons == 0 || this.view.isDestroyed || !this.view.state.doc.eq(this.startDoc)) {
			this.done();
			return;
		}
		event.preventDefault();
		setSelectionOrigin(this.view, "pointer");
		let pos = this.view.posAtCoords(eventCoords(event));
		let target = pos && selectionForTripleClick(this.view, pos.inside, false);
		if (!target) return;
		let { doc } = this.view.state, start = this.startSelection;
		let [anchor, head] = target.from < start.from ? [start.to, target.from] : [start.from, target.to];
		updateSelection(this.view, TextSelection.create(doc, anchor, head), "pointer");
	}
};
handlers.touchstart = (view) => {
	view.input.lastTouch = Date.now();
	forceDOMFlush(view);
	setSelectionOrigin(view, "pointer");
};
handlers.touchmove = (view) => {
	view.input.lastTouch = Date.now();
	setSelectionOrigin(view, "pointer");
};
handlers.contextmenu = (view) => forceDOMFlush(view);
function inOrNearComposition(view, event) {
	if (view.composing) return true;
	if (safari && Math.abs(Date.now() - view.input.compositionEndedAt) < 500) {
		view.input.compositionEndedAt = -2e8;
		return true;
	}
	return false;
}
var timeoutComposition = android ? 5e3 : -1;
editHandlers.compositionstart = editHandlers.compositionupdate = (view) => {
	if (!view.composing) {
		view.domObserver.flush();
		let { state } = view, $pos = state.selection.$to;
		if (state.selection instanceof TextSelection && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some((m) => m.type.spec.inclusive === false) || chrome && windows$1 && selectionBeforeUneditable(view))) {
			view.markCursor = view.state.storedMarks || $pos.marks();
			endComposition(view, true);
			view.markCursor = null;
		} else {
			endComposition(view, !state.selection.empty);
			if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {
				let sel = view.domSelectionRange();
				for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) {
					let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1];
					if (!before) break;
					if (before.nodeType == 3) {
						let sel = view.domSelection();
						if (sel) sel.collapse(before, before.nodeValue.length);
						break;
					} else {
						node = before;
						offset = -1;
					}
				}
			}
		}
		view.input.composing = true;
	}
	scheduleComposeEnd(view, timeoutComposition);
};
function selectionBeforeUneditable(view) {
	let { focusNode, focusOffset } = view.domSelectionRange();
	if (!focusNode || focusNode.nodeType != 1 || focusOffset >= focusNode.childNodes.length) return false;
	let next = focusNode.childNodes[focusOffset];
	return next.nodeType == 1 && next.contentEditable == "false";
}
editHandlers.compositionend = (view, event) => {
	if (view.composing) {
		view.input.composing = false;
		view.input.compositionEndedAt = Date.now();
		view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0;
		view.input.compositionNode = null;
		if (view.input.badSafariComposition) view.domObserver.forceFlush();
		else if (view.input.compositionPendingChanges) Promise.resolve().then(() => view.domObserver.flush());
		view.input.compositionID++;
		scheduleComposeEnd(view, 20);
	}
};
function scheduleComposeEnd(view, delay) {
	clearTimeout(view.input.composingTimeout);
	if (delay > -1) view.input.composingTimeout = setTimeout(() => endComposition(view), delay);
}
function clearComposition(view) {
	if (view.composing) {
		view.input.composing = false;
		view.input.compositionEndedAt = Date.now();
	}
	while (view.input.compositionNodes.length > 0) view.input.compositionNodes.pop().markParentsDirty();
}
function findCompositionNode(view) {
	let sel = view.domSelectionRange();
	if (!sel.focusNode) return null;
	let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
	let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
	if (textBefore && textAfter && textBefore != textAfter) {
		let descAfter = textAfter.pmViewDesc, lastChanged = view.domObserver.lastChangedTextNode;
		if (textBefore == lastChanged || textAfter == lastChanged) return lastChanged;
		if (!descAfter || !descAfter.isText(textAfter.nodeValue)) return textAfter;
		else if (view.input.compositionNode == textAfter) {
			let descBefore = textBefore.pmViewDesc;
			if (!(!descBefore || !descBefore.isText(textBefore.nodeValue))) return textAfter;
		}
	}
	return textBefore || textAfter;
}
/**
@internal
*/
function endComposition(view, restarting = false) {
	if (android && view.domObserver.flushingSoon >= 0) return;
	view.domObserver.forceFlush();
	clearComposition(view);
	if (restarting || view.docView && view.docView.dirty) {
		let sel = selectionFromDOM(view), cur = view.state.selection;
		if (sel && !sel.eq(cur)) view.dispatch(view.state.tr.setSelection(sel));
		else if ((view.markCursor || restarting) && !cur.$from.node(cur.$from.sharedDepth(cur.to)).inlineContent) view.dispatch(view.state.tr.deleteSelection());
		else view.updateState(view.state);
		return true;
	}
	return false;
}
function captureCopy(view, dom) {
	if (!view.dom.parentNode) return;
	let wrap = view.dom.parentNode.appendChild(document.createElement("div"));
	wrap.appendChild(dom);
	wrap.style.cssText = "position: fixed; left: -10000px; top: 10px";
	let sel = getSelection(), range = document.createRange();
	range.selectNodeContents(dom);
	view.dom.blur();
	sel.removeAllRanges();
	sel.addRange(range);
	setTimeout(() => {
		if (wrap.parentNode) wrap.parentNode.removeChild(wrap);
		view.focus();
	}, 50);
}
var brokenClipboardAPI = ie$1 && ie_version < 15 || ios && webkit_version < 604;
handlers.copy = editHandlers.cut = (view, _event) => {
	let event = _event;
	let sel = view.state.selection, cut = event.type == "cut";
	if (sel.empty) return;
	let data = brokenClipboardAPI ? null : event.clipboardData;
	let { dom, text } = serializeForClipboard(view, sel.content());
	if (data) {
		event.preventDefault();
		data.clearData();
		data.setData("text/html", dom.innerHTML);
		data.setData("text/plain", text);
	} else captureCopy(view, dom);
	if (cut) view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut"));
};
function sliceSingleNode(slice) {
	return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null;
}
function capturePaste(view, event) {
	if (!view.dom.parentNode) return;
	let plainText = view.input.shiftKey || view.state.selection.$from.parent.type.spec.code;
	let target = view.dom.parentNode.appendChild(document.createElement(plainText ? "textarea" : "div"));
	if (!plainText) target.contentEditable = "true";
	target.style.cssText = "position: fixed; left: -10000px; top: 10px";
	target.focus();
	let plain = view.input.shiftKey && view.input.lastKeyCode != 45;
	setTimeout(() => {
		view.focus();
		if (target.parentNode) target.parentNode.removeChild(target);
		if (plainText) doPaste(view, target.value, null, plain, event);
		else doPaste(view, target.textContent, target.innerHTML, plain, event);
	}, 50);
}
function doPaste(view, text, html, preferPlain, event) {
	let slice = parseFromClipboard(view, text, html, preferPlain, view.state.selection.$from);
	if (view.someProp("handlePaste", (f) => f(view, event, slice || Slice.empty))) return true;
	if (!slice) return false;
	let singleNode = sliceSingleNode(slice);
	let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, preferPlain) : view.state.tr.replaceSelection(slice);
	view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
	return true;
}
function getText$1(clipboardData) {
	let text = clipboardData.getData("text/plain") || clipboardData.getData("Text");
	if (text) return text;
	let uris = clipboardData.getData("text/uri-list");
	return uris ? uris.replace(/\r?\n/g, " ") : "";
}
editHandlers.paste = (view, _event) => {
	let event = _event;
	if (view.composing && !android) return;
	let data = brokenClipboardAPI ? null : event.clipboardData;
	let plain = view.input.shiftKey && view.input.lastKeyCode != 45;
	if (data && doPaste(view, getText$1(data), data.getData("text/html"), plain, event)) event.preventDefault();
	else capturePaste(view, event);
};
var Dragging = class {
	constructor(slice, move, node) {
		this.slice = slice;
		this.move = move;
		this.node = node;
	}
};
var dragCopyModifier = mac$2 ? "altKey" : "ctrlKey";
function dragMoves(view, event) {
	let copy;
	view.someProp("dragCopies", (test) => {
		copy = copy || test(event);
	});
	return copy != null ? !copy : !event[dragCopyModifier];
}
handlers.dragstart = (view, _event) => {
	let event = _event;
	let mouseDown = view.input.mouseDown;
	if (mouseDown) mouseDown.done();
	if (!event.dataTransfer) return;
	let sel = view.state.selection;
	let pos = sel.empty ? null : view.posAtCoords(eventCoords(event));
	let node;
	if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1 : sel.to));
	else if (mouseDown && mouseDown.mightDrag) node = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos);
	else if (event.target && event.target.nodeType == 1) {
		let desc = view.docView.nearestDesc(event.target, true);
		if (desc && desc.node.type.spec.draggable && desc != view.docView) node = NodeSelection.create(view.state.doc, desc.posBefore);
	}
	let { dom, text, slice } = serializeForClipboard(view, (node || view.state.selection).content());
	if (!event.dataTransfer.files.length || !chrome || chrome_version > 120) event.dataTransfer.clearData();
	event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML);
	event.dataTransfer.effectAllowed = "copyMove";
	if (!brokenClipboardAPI) event.dataTransfer.setData("text/plain", text);
	view.dragging = new Dragging(slice, dragMoves(view, event), node);
};
handlers.dragend = (view) => {
	let dragging = view.dragging;
	window.setTimeout(() => {
		if (view.dragging == dragging) view.dragging = null;
	}, 50);
};
editHandlers.dragover = editHandlers.dragenter = (_, e) => e.preventDefault();
editHandlers.drop = (view, event) => {
	try {
		handleDrop(view, event, view.dragging);
	} finally {
		view.dragging = null;
	}
};
function handleDrop(view, event, dragging) {
	if (!event.dataTransfer) return;
	let eventPos = view.posAtCoords(eventCoords(event));
	if (!eventPos) return;
	let $mouse = view.state.doc.resolve(eventPos.pos);
	let slice = dragging && dragging.slice;
	if (slice) view.someProp("transformPasted", (f) => {
		slice = f(slice, view, false);
	});
	else slice = parseFromClipboard(view, getText$1(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
	let move = !!(dragging && dragMoves(view, event));
	if (view.someProp("handleDrop", (f) => f(view, event, slice || Slice.empty, move))) {
		event.preventDefault();
		return;
	}
	if (!slice) return;
	event.preventDefault();
	let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos;
	if (insertPos == null) insertPos = $mouse.pos;
	let tr = view.state.tr;
	if (move) {
		let { node } = dragging;
		if (node) node.replace(tr);
		else tr.deleteSelection();
	}
	let pos = tr.mapping.map(insertPos);
	let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1;
	let beforeInsert = tr.doc;
	if (isNode) tr.replaceRangeWith(pos, pos, slice.content.firstChild);
	else tr.replaceRange(pos, pos, slice);
	if (tr.doc.eq(beforeInsert)) return;
	let $pos = tr.doc.resolve(pos);
	if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) tr.setSelection(new NodeSelection($pos));
	else {
		let end = tr.mapping.map(insertPos);
		tr.mapping.maps[tr.mapping.maps.length - 1].forEach((_from, _to, _newFrom, newTo) => end = newTo);
		tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(end)));
	}
	view.focus();
	view.dispatch(tr.setMeta("uiEvent", "drop"));
}
handlers.focus = (view) => {
	view.input.lastFocus = Date.now();
	if (!view.focused) {
		view.domObserver.stop();
		view.dom.classList.add("ProseMirror-focused");
		view.domObserver.start();
		view.focused = true;
		setTimeout(() => {
			if (view.docView && view.hasFocus() && !view.domObserver.currentSelection.eq(view.domSelectionRange())) selectionToDOM(view);
		}, 20);
	}
};
handlers.blur = (view, _event) => {
	let event = _event;
	if (view.focused) {
		view.domObserver.stop();
		view.dom.classList.remove("ProseMirror-focused");
		view.domObserver.start();
		if (event.relatedTarget && view.dom.contains(event.relatedTarget)) view.domObserver.currentSelection.clear();
		view.focused = false;
	}
};
handlers.beforeinput = (view, _event) => {
	if (chrome && android && _event.inputType == "deleteContentBackward") {
		view.domObserver.flushSoon();
		let { domChangeCount } = view.input;
		setTimeout(() => {
			if (view.input.domChangeCount != domChangeCount) return;
			view.dom.blur();
			view.focus();
			if (view.someProp("handleKeyDown", (f) => f(view, keyEvent(8, "Backspace")))) return;
			let { $cursor } = view.state.selection;
			if ($cursor && $cursor.pos > 0) view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView());
		}, 50);
	}
};
for (let prop in editHandlers) handlers[prop] = editHandlers[prop];
function compareObjs(a, b) {
	if (a == b) return true;
	for (let p in a) if (a[p] !== b[p]) return false;
	for (let p in b) if (!(p in a)) return false;
	return true;
}
var WidgetType = class WidgetType {
	constructor(toDOM, spec) {
		this.toDOM = toDOM;
		this.spec = spec || noSpec;
		this.side = this.spec.side || 0;
	}
	map(mapping, span, offset, oldOffset) {
		let { pos, deleted } = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1);
		return deleted ? null : new Decoration(pos - offset, pos - offset, this);
	}
	valid() {
		return true;
	}
	eq(other) {
		return this == other || other instanceof WidgetType && (this.spec.key && this.spec.key == other.spec.key || this.toDOM == other.toDOM && compareObjs(this.spec, other.spec));
	}
	destroy(node) {
		if (this.spec.destroy) this.spec.destroy(node);
	}
};
var InlineType = class InlineType {
	constructor(attrs, spec) {
		this.attrs = attrs;
		this.spec = spec || noSpec;
	}
	map(mapping, span, offset, oldOffset) {
		let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset;
		let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset;
		return from >= to ? null : new Decoration(from, to, this);
	}
	valid(_, span) {
		return span.from < span.to;
	}
	eq(other) {
		return this == other || other instanceof InlineType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec);
	}
	static is(span) {
		return span.type instanceof InlineType;
	}
	destroy() {}
};
var NodeType = class NodeType {
	constructor(attrs, spec) {
		this.attrs = attrs;
		this.spec = spec || noSpec;
	}
	map(mapping, span, offset, oldOffset) {
		let from = mapping.mapResult(span.from + oldOffset, 1);
		if (from.deleted) return null;
		let to = mapping.mapResult(span.to + oldOffset, -1);
		if (to.deleted || to.pos <= from.pos) return null;
		return new Decoration(from.pos - offset, to.pos - offset, this);
	}
	valid(node, span) {
		let { index, offset } = node.content.findIndex(span.from), child;
		return offset == span.from && !(child = node.child(index)).isText && offset + child.nodeSize == span.to;
	}
	eq(other) {
		return this == other || other instanceof NodeType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec);
	}
	destroy() {}
};
/**
Decoration objects can be provided to the view through the
[`decorations` prop](https://prosemirror.net/docs/ref/#view.EditorProps.decorations). They come in
several variants—see the static members of this class for details.
*/
var Decoration = class Decoration {
	/**
	@internal
	*/
	constructor(from, to, type) {
		this.from = from;
		this.to = to;
		this.type = type;
	}
	/**
	@internal
	*/
	copy(from, to) {
		return new Decoration(from, to, this.type);
	}
	/**
	@internal
	*/
	eq(other, offset = 0) {
		return this.type.eq(other.type) && this.from + offset == other.from && this.to + offset == other.to;
	}
	/**
	@internal
	*/
	map(mapping, offset, oldOffset) {
		return this.type.map(mapping, this, offset, oldOffset);
	}
	/**
	Creates a widget decoration, which is a DOM node that's shown in
	the document at the given position. It is recommended that you
	delay rendering the widget by passing a function that will be
	called when the widget is actually drawn in a view, but you can
	also directly pass a DOM node. `getPos` can be used to find the
	widget's current document position.
	*/
	static widget(pos, toDOM, spec) {
		return new Decoration(pos, pos, new WidgetType(toDOM, spec));
	}
	/**
	Creates an inline decoration, which adds the given attributes to
	each inline node between `from` and `to`.
	*/
	static inline(from, to, attrs, spec) {
		return new Decoration(from, to, new InlineType(attrs, spec));
	}
	/**
	Creates a node decoration. `from` and `to` should point precisely
	before and after a node in the document. That node, and only that
	node, will receive the given attributes.
	*/
	static node(from, to, attrs, spec) {
		return new Decoration(from, to, new NodeType(attrs, spec));
	}
	/**
	The spec provided when creating this decoration. Can be useful
	if you've stored extra information in that object.
	*/
	get spec() {
		return this.type.spec;
	}
	/**
	@internal
	*/
	get inline() {
		return this.type instanceof InlineType;
	}
	/**
	@internal
	*/
	get widget() {
		return this.type instanceof WidgetType;
	}
};
var none = [];
var noSpec = {};
/**
A collection of [decorations](https://prosemirror.net/docs/ref/#view.Decoration), organized in such
a way that the drawing algorithm can efficiently use and compare
them. This is a persistent data structure—it is not modified,
updates create a new value.
*/
var DecorationSet = class DecorationSet {
	/**
	@internal
	*/
	constructor(local, children) {
		this.local = local.length ? local : none;
		this.children = children.length ? children : none;
	}
	/**
	Create a set of decorations, using the structure of the given
	document. This will consume (modify) the `decorations` array, so
	you must make a copy if you want need to preserve that.
	*/
	static create(doc, decorations) {
		return decorations.length ? buildTree(decorations, doc, 0, noSpec) : empty;
	}
	/**
	Find all decorations in this set which touch the given range
	(including decorations that start or end directly at the
	boundaries) and match the given predicate on their spec. When
	`start` and `end` are omitted, all decorations in the set are
	considered. When `predicate` isn't given, all decorations are
	assumed to match.
	*/
	find(start, end, predicate) {
		let result = [];
		this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate);
		return result;
	}
	findInner(start, end, result, offset, predicate) {
		for (let i = 0; i < this.local.length; i++) {
			let span = this.local[i];
			if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) result.push(span.copy(span.from + offset, span.to + offset));
		}
		for (let i = 0; i < this.children.length; i += 3) if (this.children[i] < end && this.children[i + 1] > start) {
			let childOff = this.children[i] + 1;
			this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate);
		}
	}
	/**
	Map the set of decorations in response to a change in the
	document.
	*/
	map(mapping, doc, options) {
		if (this == empty || mapping.maps.length == 0) return this;
		return this.mapInner(mapping, doc, 0, 0, options || noSpec);
	}
	/**
	@internal
	*/
	mapInner(mapping, node, offset, oldOffset, options) {
		let newLocal;
		for (let i = 0; i < this.local.length; i++) {
			let mapped = this.local[i].map(mapping, offset, oldOffset);
			if (mapped && mapped.type.valid(node, mapped)) (newLocal || (newLocal = [])).push(mapped);
			else if (options.onRemove) options.onRemove(this.local[i].spec);
		}
		if (this.children.length) return mapChildren(this.children, newLocal || [], mapping, node, offset, oldOffset, options);
		else return newLocal ? new DecorationSet(newLocal.sort(byPos), none) : empty;
	}
	/**
	Add the given array of decorations to the ones in the set,
	producing a new set. Consumes the `decorations` array. Needs
	access to the current document to create the appropriate tree
	structure.
	*/
	add(doc, decorations) {
		if (!decorations.length) return this;
		if (this == empty) return DecorationSet.create(doc, decorations);
		return this.addInner(doc, decorations, 0);
	}
	addInner(doc, decorations, offset) {
		let children, childIndex = 0;
		doc.forEach((childNode, childOffset) => {
			let baseOffset = childOffset + offset, found;
			if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return;
			if (!children) children = this.children.slice();
			while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3;
			if (children[childIndex] == childOffset) children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1);
			else children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec));
			childIndex += 3;
		});
		let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset);
		for (let i = 0; i < local.length; i++) if (!local[i].type.valid(doc, local[i])) local.splice(i--, 1);
		return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children);
	}
	/**
	Create a new set that contains the decorations in this set, minus
	the ones in the given array.
	*/
	remove(decorations) {
		if (decorations.length == 0 || this == empty) return this;
		return this.removeInner(decorations, 0);
	}
	removeInner(decorations, offset) {
		let children = this.children, local = this.local;
		for (let i = 0; i < children.length; i += 3) {
			let found;
			let from = children[i] + offset, to = children[i + 1] + offset;
			for (let j = 0, span; j < decorations.length; j++) if (span = decorations[j]) {
				if (span.from > from && span.to < to) {
					decorations[j] = null;
					(found || (found = [])).push(span);
				}
			}
			if (!found) continue;
			if (children == this.children) children = this.children.slice();
			let removed = children[i + 2].removeInner(found, from + 1);
			if (removed != empty) children[i + 2] = removed;
			else {
				children.splice(i, 3);
				i -= 3;
			}
		}
		if (local.length) {
			for (let i = 0, span; i < decorations.length; i++) if (span = decorations[i]) {
				for (let j = 0; j < local.length; j++) if (local[j].eq(span, offset)) {
					if (local == this.local) local = this.local.slice();
					local.splice(j--, 1);
				}
			}
		}
		if (children == this.children && local == this.local) return this;
		return local.length || children.length ? new DecorationSet(local, children) : empty;
	}
	forChild(offset, node) {
		if (this == empty) return this;
		if (node.isLeaf) return DecorationSet.empty;
		let child, local;
		for (let i = 0; i < this.children.length; i += 3) if (this.children[i] >= offset) {
			if (this.children[i] == offset) child = this.children[i + 2];
			break;
		}
		let start = offset + 1, end = start + node.content.size;
		for (let i = 0; i < this.local.length; i++) {
			let dec = this.local[i];
			if (dec.from < end && dec.to > start && dec.type instanceof InlineType) {
				let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start;
				if (from < to) (local || (local = [])).push(dec.copy(from, to));
			}
		}
		if (local) {
			let localSet = new DecorationSet(local.sort(byPos), none);
			return child ? new DecorationGroup([localSet, child]) : localSet;
		}
		return child || empty;
	}
	/**
	@internal
	*/
	eq(other) {
		if (this == other) return true;
		if (!(other instanceof DecorationSet) || this.local.length != other.local.length || this.children.length != other.children.length) return false;
		for (let i = 0; i < this.local.length; i++) if (!this.local[i].eq(other.local[i])) return false;
		for (let i = 0; i < this.children.length; i += 3) if (this.children[i] != other.children[i] || this.children[i + 1] != other.children[i + 1] || !this.children[i + 2].eq(other.children[i + 2])) return false;
		return true;
	}
	/**
	@internal
	*/
	locals(node) {
		return removeOverlap(this.localsInner(node));
	}
	/**
	@internal
	*/
	localsInner(node) {
		if (this == empty) return none;
		if (node.inlineContent || !this.local.some(InlineType.is)) return this.local;
		let result = [];
		for (let i = 0; i < this.local.length; i++) if (!(this.local[i].type instanceof InlineType)) result.push(this.local[i]);
		return result;
	}
	forEachSet(f) {
		f(this);
	}
};
/**
The empty set of decorations.
*/
DecorationSet.empty = new DecorationSet([], []);
/**
@internal
*/
DecorationSet.removeOverlap = removeOverlap;
var empty = DecorationSet.empty;
var DecorationGroup = class DecorationGroup {
	constructor(members) {
		this.members = members;
	}
	map(mapping, doc) {
		const mappedDecos = this.members.map((member) => member.map(mapping, doc, noSpec));
		return DecorationGroup.from(mappedDecos);
	}
	forChild(offset, child) {
		if (child.isLeaf) return DecorationSet.empty;
		let found = [];
		for (let i = 0; i < this.members.length; i++) {
			let result = this.members[i].forChild(offset, child);
			if (result == empty) continue;
			if (result instanceof DecorationGroup) found = found.concat(result.members);
			else found.push(result);
		}
		return DecorationGroup.from(found);
	}
	eq(other) {
		if (!(other instanceof DecorationGroup) || other.members.length != this.members.length) return false;
		for (let i = 0; i < this.members.length; i++) if (!this.members[i].eq(other.members[i])) return false;
		return true;
	}
	locals(node) {
		let result, sorted = true;
		for (let i = 0; i < this.members.length; i++) {
			let locals = this.members[i].localsInner(node);
			if (!locals.length) continue;
			if (!result) result = locals;
			else {
				if (sorted) {
					result = result.slice();
					sorted = false;
				}
				for (let j = 0; j < locals.length; j++) result.push(locals[j]);
			}
		}
		return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none;
	}
	static from(members) {
		switch (members.length) {
			case 0: return empty;
			case 1: return members[0];
			default: return new DecorationGroup(members.every((m) => m instanceof DecorationSet) ? members : members.reduce((r, m) => r.concat(m instanceof DecorationSet ? m : m.members), []));
		}
	}
	forEachSet(f) {
		for (let i = 0; i < this.members.length; i++) this.members[i].forEachSet(f);
	}
};
function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {
	let children = oldChildren.slice();
	for (let i = 0, baseOffset = oldOffset; i < mapping.maps.length; i++) {
		let moved = 0;
		mapping.maps[i].forEach((oldStart, oldEnd, newStart, newEnd) => {
			let dSize = newEnd - newStart - (oldEnd - oldStart);
			for (let i = 0; i < children.length; i += 3) {
				let end = children[i + 1];
				if (end < 0 || oldStart > end + baseOffset - moved) continue;
				let start = children[i] + baseOffset - moved;
				if (oldEnd >= start) children[i + 1] = oldStart <= start ? -2 : -1;
				else if (oldStart >= baseOffset && dSize) {
					children[i] += dSize;
					children[i + 1] += dSize;
				}
			}
			moved += dSize;
		});
		baseOffset = mapping.maps[i].map(baseOffset, -1);
	}
	let mustRebuild = false;
	for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) {
		if (children[i + 1] == -2) {
			mustRebuild = true;
			children[i + 1] = -1;
			continue;
		}
		let from = mapping.map(oldChildren[i] + oldOffset), fromLocal = from - offset;
		if (fromLocal < 0 || fromLocal >= node.content.size) {
			mustRebuild = true;
			continue;
		}
		let toLocal = mapping.map(oldChildren[i + 1] + oldOffset, -1) - offset;
		let { index, offset: childOffset } = node.content.findIndex(fromLocal);
		let childNode = node.maybeChild(index);
		if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) {
			let mapped = children[i + 2].mapInner(mapping, childNode, from + 1, oldChildren[i] + oldOffset + 1, options);
			if (mapped != empty) {
				children[i] = fromLocal;
				children[i + 1] = toLocal;
				children[i + 2] = mapped;
			} else {
				children[i + 1] = -2;
				mustRebuild = true;
			}
		} else mustRebuild = true;
	}
	if (mustRebuild) {
		let built = buildTree(mapAndGatherRemainingDecorations(children, oldChildren, newLocal, mapping, offset, oldOffset, options), node, 0, options);
		newLocal = built.local;
		for (let i = 0; i < children.length; i += 3) if (children[i + 1] < 0) {
			children.splice(i, 3);
			i -= 3;
		}
		for (let i = 0, j = 0; i < built.children.length; i += 3) {
			let from = built.children[i];
			while (j < children.length && children[j] < from) j += 3;
			children.splice(j, 0, built.children[i], built.children[i + 1], built.children[i + 2]);
		}
	}
	return new DecorationSet(newLocal.sort(byPos), children);
}
function moveSpans(spans, offset) {
	if (!offset || !spans.length) return spans;
	let result = [];
	for (let i = 0; i < spans.length; i++) {
		let span = spans[i];
		result.push(new Decoration(span.from + offset, span.to + offset, span.type));
	}
	return result;
}
function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) {
	function gather(set, oldOffset) {
		for (let i = 0; i < set.local.length; i++) {
			let mapped = set.local[i].map(mapping, offset, oldOffset);
			if (mapped) decorations.push(mapped);
			else if (options.onRemove) options.onRemove(set.local[i].spec);
		}
		for (let i = 0; i < set.children.length; i += 3) gather(set.children[i + 2], set.children[i] + oldOffset + 1);
	}
	for (let i = 0; i < children.length; i += 3) if (children[i + 1] == -1) gather(children[i + 2], oldChildren[i] + oldOffset + 1);
	return decorations;
}
function takeSpansForNode(spans, node, offset) {
	if (node.isLeaf) return null;
	let end = offset + node.nodeSize, found = null;
	for (let i = 0, span; i < spans.length; i++) if ((span = spans[i]) && span.from > offset && span.to < end) {
		(found || (found = [])).push(span);
		spans[i] = null;
	}
	return found;
}
function withoutNulls(array) {
	let result = [];
	for (let i = 0; i < array.length; i++) if (array[i] != null) result.push(array[i]);
	return result;
}
function buildTree(spans, node, offset, options) {
	let children = [], hasNulls = false;
	node.forEach((childNode, localStart) => {
		let found = takeSpansForNode(spans, childNode, localStart + offset);
		if (found) {
			hasNulls = true;
			let subtree = buildTree(found, childNode, offset + localStart + 1, options);
			if (subtree != empty) children.push(localStart, localStart + childNode.nodeSize, subtree);
		}
	});
	let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos);
	for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i])) {
		if (options.onRemove) options.onRemove(locals[i].spec);
		locals.splice(i--, 1);
	}
	return locals.length || children.length ? new DecorationSet(locals, children) : empty;
}
function byPos(a, b) {
	return a.from - b.from || a.to - b.to;
}
function removeOverlap(spans) {
	let working = spans;
	for (let i = 0; i < working.length - 1; i++) {
		let span = working[i];
		if (span.from != span.to) for (let j = i + 1; j < working.length; j++) {
			let next = working[j];
			if (next.from == span.from) {
				if (next.to != span.to) {
					if (working == spans) working = spans.slice();
					working[j] = next.copy(next.from, span.to);
					insertAhead(working, j + 1, next.copy(span.to, next.to));
				}
				continue;
			} else {
				if (next.from < span.to) {
					if (working == spans) working = spans.slice();
					working[i] = span.copy(span.from, next.from);
					insertAhead(working, j, span.copy(next.from, span.to));
				}
				break;
			}
		}
	}
	return working;
}
function insertAhead(array, i, deco) {
	while (i < array.length && byPos(deco, array[i]) > 0) i++;
	array.splice(i, 0, deco);
}
function viewDecorations(view) {
	let found = [];
	view.someProp("decorations", (f) => {
		let result = f(view.state);
		if (result && result != empty) found.push(result);
	});
	if (view.cursorWrapper) found.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco]));
	return DecorationGroup.from(found);
}
var observeOptions = {
	childList: true,
	characterData: true,
	characterDataOldValue: true,
	attributes: true,
	attributeOldValue: true,
	subtree: true
};
var useCharData = ie$1 && ie_version <= 11;
var SelectionState$1 = class {
	constructor() {
		this.anchorNode = null;
		this.anchorOffset = 0;
		this.focusNode = null;
		this.focusOffset = 0;
	}
	set(sel) {
		this.anchorNode = sel.anchorNode;
		this.anchorOffset = sel.anchorOffset;
		this.focusNode = sel.focusNode;
		this.focusOffset = sel.focusOffset;
	}
	clear() {
		this.anchorNode = this.focusNode = null;
	}
	eq(sel) {
		return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset;
	}
};
var DOMObserver = class {
	constructor(view, handleDOMChange) {
		this.view = view;
		this.handleDOMChange = handleDOMChange;
		this.queue = [];
		this.flushingSoon = -1;
		this.observer = null;
		this.currentSelection = new SelectionState$1();
		this.onCharData = null;
		this.suppressingSelectionUpdates = false;
		this.lastChangedTextNode = null;
		this.observer = window.MutationObserver && new window.MutationObserver((mutations) => {
			for (let i = 0; i < mutations.length; i++) this.queue.push(mutations[i]);
			if (ie$1 && ie_version <= 11 && mutations.some((m) => m.type == "childList" && m.removedNodes.length || m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length)) this.flushSoon();
			else if (safari && view.composing && mutations.some((m) => m.type == "childList" && m.target.nodeName == "TR")) {
				view.input.badSafariComposition = true;
				this.flushSoon();
			} else this.flush();
		});
		if (useCharData) this.onCharData = (e) => {
			this.queue.push({
				target: e.target,
				type: "characterData",
				oldValue: e.prevValue
			});
			this.flushSoon();
		};
		this.onSelectionChange = this.onSelectionChange.bind(this);
	}
	flushSoon() {
		if (this.flushingSoon < 0) this.flushingSoon = window.setTimeout(() => {
			this.flushingSoon = -1;
			this.flush();
		}, 20);
	}
	forceFlush() {
		if (this.flushingSoon > -1) {
			window.clearTimeout(this.flushingSoon);
			this.flushingSoon = -1;
			this.flush();
		}
	}
	start() {
		if (this.observer) {
			this.observer.takeRecords();
			this.observer.observe(this.view.dom, observeOptions);
		}
		if (this.onCharData) this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData);
		this.connectSelection();
	}
	stop() {
		if (this.observer) {
			let take = this.observer.takeRecords();
			if (take.length) {
				for (let i = 0; i < take.length; i++) this.queue.push(take[i]);
				window.setTimeout(() => this.flush(), 20);
			}
			this.observer.disconnect();
		}
		if (this.onCharData) this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData);
		this.disconnectSelection();
	}
	connectSelection() {
		this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange);
	}
	disconnectSelection() {
		this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
	}
	suppressSelectionUpdates() {
		this.suppressingSelectionUpdates = true;
		setTimeout(() => this.suppressingSelectionUpdates = false, 50);
	}
	onSelectionChange() {
		if (!hasFocusAndSelection(this.view)) return;
		if (this.suppressingSelectionUpdates) return selectionToDOM(this.view);
		if (ie$1 && ie_version <= 11 && !this.view.state.selection.empty) {
			let sel = this.view.domSelectionRange();
			if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) return this.flushSoon();
		}
		this.flush();
	}
	setCurSelection() {
		this.currentSelection.set(this.view.domSelectionRange());
	}
	ignoreSelectionChange(sel) {
		if (!sel.focusNode) return true;
		let ancestors = /* @__PURE__ */ new Set(), container;
		for (let scan = sel.focusNode; scan; scan = parentNode(scan)) ancestors.add(scan);
		for (let scan = sel.anchorNode; scan; scan = parentNode(scan)) if (ancestors.has(scan)) {
			container = scan;
			break;
		}
		let desc = container && this.view.docView.nearestDesc(container);
		if (desc && desc.ignoreMutation({
			type: "selection",
			target: container.nodeType == 3 ? container.parentNode : container
		})) {
			this.setCurSelection();
			return true;
		}
	}
	pendingRecords() {
		if (this.observer) for (let mut of this.observer.takeRecords()) this.queue.push(mut);
		return this.queue;
	}
	flush() {
		let { view } = this;
		if (!view.docView || this.flushingSoon > -1) return;
		let mutations = this.pendingRecords();
		if (mutations.length) this.queue = [];
		let sel = view.domSelectionRange();
		let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
		let from = -1, to = -1, typeOver = false, added = [];
		if (view.editable) for (let i = 0; i < mutations.length; i++) {
			let result = this.registerMutation(mutations[i], added);
			if (result) {
				from = from < 0 ? result.from : Math.min(result.from, from);
				to = to < 0 ? result.to : Math.max(result.to, to);
				if (result.typeOver) typeOver = true;
			}
		}
		if (added.some((n) => n.nodeName == "BR") && (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46 || chrome && (view.composing || view.input.compositionEndedAt > Date.now() - 50) && mutations.some((m) => m.type == "childList" && m.removedNodes.length))) {
			for (let node of added) if (node.nodeName == "BR" && node.parentNode) {
				let after = node.nextSibling;
				while (after && after.nodeType == 1) {
					if (after.contentEditable == "false") {
						node.parentNode.removeChild(node);
						break;
					}
					after = after.firstChild;
				}
			}
		} else if (gecko && added.length) {
			let brs = added.filter((n) => n.nodeName == "BR");
			if (brs.length == 2) {
				let [a, b] = brs;
				if (a.parentNode && a.parentNode.parentNode == b.parentNode) b.remove();
				else a.remove();
			} else {
				let { focusNode } = this.currentSelection;
				for (let br of brs) {
					let parent = br.parentNode;
					if (parent && parent.nodeName == "LI" && (!focusNode || blockParent(view, focusNode) != parent)) br.remove();
				}
			}
		}
		let readSel = null;
		if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 && Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) && readSel.eq(Selection$1.near(view.state.doc.resolve(0), 1))) {
			view.input.lastFocus = 0;
			selectionToDOM(view);
			this.currentSelection.set(sel);
			view.scrollToSelection();
		} else if (from > -1 || newSel) {
			if (from > -1) {
				view.docView.markDirty(from, to);
				checkCSS(view);
			}
			if (view.input.badSafariComposition) {
				view.input.badSafariComposition = false;
				fixUpBadSafariComposition(view, added);
			}
			this.handleDOMChange(from, to, typeOver, added);
			if (view.docView && view.docView.dirty) view.updateState(view.state);
			else if (!this.currentSelection.eq(sel)) selectionToDOM(view);
			this.currentSelection.set(sel);
		}
	}
	registerMutation(mut, added) {
		if (added.indexOf(mut.target) > -1) return null;
		let desc = this.view.docView.nearestDesc(mut.target);
		if (mut.type == "attributes" && (desc == this.view.docView || mut.attributeName == "contenteditable" || mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style"))) return null;
		if (!desc || desc.ignoreMutation(mut)) return null;
		if (mut.type == "childList") {
			for (let i = 0; i < mut.addedNodes.length; i++) {
				let node = mut.addedNodes[i];
				added.push(node);
				if (node.nodeType == 3) this.lastChangedTextNode = node;
			}
			if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target)) return {
				from: desc.posBefore,
				to: desc.posAfter
			};
			let prev = mut.previousSibling, next = mut.nextSibling;
			if (ie$1 && ie_version <= 11 && mut.addedNodes.length) for (let i = 0; i < mut.addedNodes.length; i++) {
				let { previousSibling, nextSibling } = mut.addedNodes[i];
				if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling;
				if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) next = nextSibling;
			}
			let fromOffset = prev && prev.parentNode == mut.target ? domIndex(prev) + 1 : 0;
			let from = desc.localPosFromDOM(mut.target, fromOffset, -1);
			let toOffset = next && next.parentNode == mut.target ? domIndex(next) : mut.target.childNodes.length;
			return {
				from,
				to: desc.localPosFromDOM(mut.target, toOffset, 1)
			};
		} else if (mut.type == "attributes") return {
			from: desc.posAtStart - desc.border,
			to: desc.posAtEnd + desc.border
		};
		else {
			this.lastChangedTextNode = mut.target;
			return {
				from: desc.posAtStart,
				to: desc.posAtEnd,
				typeOver: mut.target.nodeValue == mut.oldValue
			};
		}
	}
};
var cssChecked = /* @__PURE__ */ new WeakMap();
var cssCheckWarned = false;
function checkCSS(view) {
	if (cssChecked.has(view)) return;
	cssChecked.set(view, null);
	if ([
		"normal",
		"nowrap",
		"pre-line"
	].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) {
		view.requiresGeckoHackNode = gecko;
		if (cssCheckWarned) return;
		console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.");
		cssCheckWarned = true;
	}
}
function rangeToSelectionRange(view, range) {
	let anchorNode = range.startContainer, anchorOffset = range.startOffset;
	let focusNode = range.endContainer, focusOffset = range.endOffset;
	let currentAnchor = view.domAtPos(view.state.selection.anchor);
	if (isEquivalentPosition(currentAnchor.node, currentAnchor.offset, focusNode, focusOffset)) [anchorNode, anchorOffset, focusNode, focusOffset] = [
		focusNode,
		focusOffset,
		anchorNode,
		anchorOffset
	];
	return {
		anchorNode,
		anchorOffset,
		focusNode,
		focusOffset
	};
}
function safariShadowSelectionRange(view, selection) {
	if (selection.getComposedRanges) {
		let range = selection.getComposedRanges(view.root)[0];
		if (range) return rangeToSelectionRange(view, range);
	}
	let found;
	function read(event) {
		event.preventDefault();
		event.stopImmediatePropagation();
		found = event.getTargetRanges()[0];
	}
	view.dom.addEventListener("beforeinput", read, true);
	document.execCommand("indent");
	view.dom.removeEventListener("beforeinput", read, true);
	return found ? rangeToSelectionRange(view, found) : null;
}
function blockParent(view, node) {
	for (let p = node.parentNode; p && p != view.dom; p = p.parentNode) {
		let desc = view.docView.nearestDesc(p, true);
		if (desc && desc.node.isBlock) return p;
	}
	return null;
}
function fixUpBadSafariComposition(view, addedNodes) {
	var _a;
	let { focusNode, focusOffset } = view.domSelectionRange();
	for (let node of addedNodes) if (((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.nodeName) == "TR") {
		let nextCell = node.nextSibling;
		while (nextCell && nextCell.nodeName != "TD" && nextCell.nodeName != "TH") nextCell = nextCell.nextSibling;
		if (nextCell) {
			let parent = nextCell;
			for (;;) {
				let first = parent.firstChild;
				if (!first || first.nodeType != 1 || first.contentEditable == "false" || /^(BR|IMG)$/.test(first.nodeName)) break;
				parent = first;
			}
			parent.insertBefore(node, parent.firstChild);
			if (focusNode == node) view.domSelection().collapse(node, focusOffset);
		} else node.parentNode.removeChild(node);
	}
}
function parseBetween(view, from_, to_) {
	let { node: parent, fromOffset, toOffset, from, to } = view.docView.parseRange(from_, to_);
	let domSel = view.domSelectionRange();
	let find;
	let anchor = domSel.anchorNode;
	if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) {
		find = [{
			node: anchor,
			offset: domSel.anchorOffset
		}];
		if (!selectionCollapsed(domSel)) find.push({
			node: domSel.focusNode,
			offset: domSel.focusOffset
		});
	}
	if (chrome && view.input.lastKeyCode === 8) for (let off = toOffset; off > fromOffset; off--) {
		let node = parent.childNodes[off - 1], desc = node.pmViewDesc;
		if (node.nodeName == "BR" && !desc) {
			toOffset = off;
			break;
		}
		if (!desc || desc.size) break;
	}
	let startDoc = view.state.doc;
	let parser = view.someProp("domParser") || DOMParser$1.fromSchema(view.state.schema);
	let $from = startDoc.resolve(from);
	let sel = null, doc = parser.parse(parent, {
		topNode: $from.parent,
		topMatch: $from.parent.contentMatchAt($from.index()),
		topOpen: true,
		from: fromOffset,
		to: toOffset,
		preserveWhitespace: $from.parent.type.whitespace == "pre" ? "full" : true,
		findPositions: find,
		ruleFromNode,
		context: $from
	});
	if (find && find[0].pos != null) {
		let anchor = find[0].pos, head = find[1] && find[1].pos;
		if (head == null) head = anchor;
		sel = {
			anchor: anchor + from,
			head: head + from
		};
	}
	return {
		doc,
		sel,
		from,
		to
	};
}
function ruleFromNode(dom) {
	let desc = dom.pmViewDesc;
	if (desc) return desc.parseRule();
	else if (dom.nodeName == "BR" && dom.parentNode) {
		if (safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) {
			let skip = document.createElement("div");
			skip.appendChild(document.createElement("li"));
			return { skip };
		} else if (dom.parentNode.lastChild == dom || safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) return { ignore: true };
	} else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) return { ignore: true };
	return null;
}
var isInline = /^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|img|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i;
function readDOMChange(view, from, to, typeOver, addedNodes) {
	let compositionID = view.input.compositionPendingChanges || (view.composing ? view.input.compositionID : 0);
	view.input.compositionPendingChanges = 0;
	if (from < 0) {
		let origin = view.input.lastSelectionTime > Date.now() - 50 ? view.input.lastSelectionOrigin : null;
		let newSel = selectionFromDOM(view, origin);
		if (newSel && !view.state.selection.eq(newSel)) {
			if (chrome && android && view.input.lastKeyCode === 13 && Date.now() - 100 < view.input.lastKeyCodeTime && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) return;
			let tr = view.state.tr.setSelection(newSel);
			if (origin == "pointer") tr.setMeta("pointer", true);
			else if (origin == "key") tr.scrollIntoView();
			if (compositionID) tr.setMeta("composition", compositionID);
			view.dispatch(tr);
		}
		return;
	}
	let $before = view.state.doc.resolve(from);
	let shared = $before.sharedDepth(to);
	from = $before.before(shared + 1);
	to = view.state.doc.resolve(to).after(shared + 1);
	let sel = view.state.selection;
	let parse = parseBetween(view, from, to);
	let doc = view.state.doc, compare = doc.slice(parse.from, parse.to);
	let preferredPos, preferredSide;
	if (view.input.lastKeyCode === 8 && Date.now() - 100 < view.input.lastKeyCodeTime) {
		preferredPos = view.state.selection.to;
		preferredSide = "end";
	} else {
		preferredPos = view.state.selection.from;
		preferredSide = "start";
	}
	view.input.lastKeyCode = null;
	let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide);
	if (change) view.input.domChangeCount++;
	if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) && addedNodes.some((n) => n.nodeType == 1 && !isInline.test(n.nodeName)) && (!change || change.endA >= change.endB) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) {
		view.input.lastIOSEnter = 0;
		return;
	}
	if (!change) {
		if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) change = {
			start: sel.from,
			endA: sel.to,
			endB: sel.to
		};
		else {
			if (parse.sel) {
				let sel = resolveSelection(view, view.state.doc, parse.sel);
				if (sel && !sel.eq(view.state.selection)) {
					let tr = view.state.tr.setSelection(sel);
					if (compositionID) tr.setMeta("composition", compositionID);
					view.dispatch(tr);
				}
			}
			return;
		}
	}
	if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof TextSelection) {
		if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2 && view.state.selection.from >= parse.from) change.start = view.state.selection.from;
		else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2 && view.state.selection.to <= parse.to) {
			change.endB += view.state.selection.to - change.endA;
			change.endA = view.state.selection.to;
		}
	}
	if (ie$1 && ie_version <= 11 && change.endB == change.start + 1 && change.endA == change.start && change.start > parse.from && parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \xA0") {
		change.start--;
		change.endA--;
		change.endB--;
	}
	let $from = parse.doc.resolveNoCache(change.start - parse.from);
	let $to = parse.doc.resolveNoCache(change.endB - parse.from);
	let $fromA = doc.resolve(change.start);
	let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA;
	if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some((n) => n.nodeName == "DIV" || n.nodeName == "P")) || !inlineChange && $from.pos < parse.doc.content.size && (!$from.sameParent($to) || !$from.parent.inlineContent) && $from.pos < $to.pos && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", ""))) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) {
		view.input.lastIOSEnter = 0;
		return;
	}
	if (view.state.selection.anchor > change.start && looksLikeBackspace(doc, change.start, change.endA, $from, $to) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(8, "Backspace")))) {
		if (android && chrome) view.domObserver.suppressSelectionUpdates();
		return;
	}
	if (chrome && change.endB == change.start) view.input.lastChromeDelete = Date.now();
	if (android && !inlineChange && $from.start() != $to.start() && $to.parentOffset == 0 && $from.depth == $to.depth && parse.sel && parse.sel.anchor == parse.sel.head && parse.sel.head == change.endA) {
		change.endB -= 2;
		$to = parse.doc.resolveNoCache(change.endB - parse.from);
		setTimeout(() => {
			view.someProp("handleKeyDown", function(f) {
				return f(view, keyEvent(13, "Enter"));
			});
		}, 20);
	}
	let chFrom = change.start, chTo = change.endA;
	let mkTr = (base) => {
		let tr = base || view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from));
		if (parse.sel) {
			let sel = resolveSelection(view, tr.doc, parse.sel);
			if (sel && !(chrome && view.composing && sel.empty && (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) && (sel.head == chFrom || sel.head == tr.mapping.map(chTo) - 1) || ie$1 && sel.empty && sel.head == chFrom)) tr.setSelection(sel);
		}
		if (compositionID) tr.setMeta("composition", compositionID);
		return tr.scrollIntoView();
	};
	let markChange;
	if (inlineChange) {
		if ($from.pos == $to.pos) {
			if (ie$1 && ie_version <= 11 && $from.parentOffset == 0) {
				view.domObserver.suppressSelectionUpdates();
				setTimeout(() => selectionToDOM(view), 20);
			}
			let tr = mkTr(view.state.tr.delete(chFrom, chTo));
			let marks = doc.resolve(change.start).marksAcross(doc.resolve(change.endA));
			if (marks) tr.ensureMarks(marks);
			view.dispatch(tr);
		} else if (change.endA == change.endB && (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), $fromA.parent.content.cut($fromA.parentOffset, change.endA - $fromA.start())))) {
			let tr = mkTr(view.state.tr);
			if (markChange.type == "add") tr.addMark(chFrom, chTo, markChange.mark);
			else tr.removeMark(chFrom, chTo, markChange.mark);
			view.dispatch(tr);
		} else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) {
			let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset);
			let deflt = () => mkTr(view.state.tr.insertText(text, chFrom, chTo));
			if (!view.someProp("handleTextInput", (f) => f(view, chFrom, chTo, text, deflt))) view.dispatch(deflt());
		} else view.dispatch(mkTr());
	} else view.dispatch(mkTr());
}
function resolveSelection(view, doc, parsedSel) {
	if (Math.max(parsedSel.anchor, parsedSel.head) > doc.content.size) return null;
	return selectionBetween(view, doc.resolve(parsedSel.anchor), doc.resolve(parsedSel.head));
}
function isMarkChange(cur, prev) {
	let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks;
	let added = curMarks, removed = prevMarks, type, mark, update;
	for (let i = 0; i < prevMarks.length; i++) added = prevMarks[i].removeFromSet(added);
	for (let i = 0; i < curMarks.length; i++) removed = curMarks[i].removeFromSet(removed);
	if (added.length == 1 && removed.length == 0) {
		mark = added[0];
		type = "add";
		update = (node) => node.mark(mark.addToSet(node.marks));
	} else if (added.length == 0 && removed.length == 1) {
		mark = removed[0];
		type = "remove";
		update = (node) => node.mark(mark.removeFromSet(node.marks));
	} else return null;
	let updated = [];
	for (let i = 0; i < prev.childCount; i++) updated.push(update(prev.child(i)));
	if (Fragment$8.from(updated).eq(cur)) return {
		mark,
		type
	};
}
function looksLikeBackspace(old, start, end, $newStart, $newEnd) {
	if (end - start <= $newEnd.pos - $newStart.pos || skipClosingAndOpening($newStart, true, false) < $newEnd.pos) return false;
	let $start = old.resolve(start);
	if (!$newStart.parent.isTextblock) {
		let after = $start.nodeAfter;
		return after != null && end == start + after.nodeSize;
	}
	if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) return false;
	let $next = old.resolve(skipClosingAndOpening($start, true, true));
	if (!$next.parent.isTextblock || $next.pos > end || skipClosingAndOpening($next, true, false) < end) return false;
	return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content);
}
function skipClosingAndOpening($pos, fromEnd, mayOpen) {
	let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos;
	while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) {
		depth--;
		end++;
		fromEnd = false;
	}
	if (mayOpen) {
		let next = $pos.node(depth).maybeChild($pos.indexAfter(depth));
		while (next && !next.isLeaf) {
			next = next.firstChild;
			end++;
		}
	}
	return end;
}
function findDiff(a, b, pos, preferredPos, preferredSide) {
	let start = a.findDiffStart(b, pos), lenA = pos + a.size, lenB = pos + b.size;
	if (start == null) return null;
	let { a: endA, b: endB } = a.findDiffEnd(b, lenA, lenB);
	if (preferredSide == "end") {
		let adjust = Math.max(0, start - Math.min(endA, endB));
		preferredPos -= endA + adjust - start;
	}
	if (endA < start && lenA < lenB) {
		let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0;
		start -= move;
		endB = start + (endB - endA);
		endA = start;
	} else if (endB < start) {
		let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0;
		start -= move;
		endA = start + (endA - endB);
		endB = start;
	}
	return {
		start,
		endA,
		endB
	};
}
/**
An editor view manages the DOM structure that represents an
editable document. Its state and behavior are determined by its
[props](https://prosemirror.net/docs/ref/#view.DirectEditorProps).
*/
var EditorView = class {
	/**
	Create a view. `place` may be a DOM node that the editor should
	be appended to, a function that will place it into the document,
	or an object whose `mount` property holds the node to use as the
	document container. If it is `null`, the editor will not be
	added to the document.
	*/
	constructor(place, props) {
		this._root = null;
		/**
		@internal
		*/
		this.focused = false;
		/**
		Kludge used to work around a Chrome bug @internal
		*/
		this.trackWrites = null;
		this.mounted = false;
		/**
		@internal
		*/
		this.markCursor = null;
		/**
		@internal
		*/
		this.cursorWrapper = null;
		/**
		@internal
		*/
		this.lastSelectedViewDesc = void 0;
		/**
		@internal
		*/
		this.input = new InputState();
		this.prevDirectPlugins = [];
		this.pluginViews = [];
		/**
		Holds `true` when a hack node is needed in Firefox to prevent the
		[space is eaten issue](https://code.haverbeke.berlin/prosemirror/prosemirror/issues/651)
		@internal
		*/
		this.requiresGeckoHackNode = false;
		/**
		When editor content is being dragged, this object contains
		information about the dragged slice and whether it is being
		copied or moved. At any other time, it is null.
		*/
		this.dragging = null;
		this._props = props;
		this.state = props.state;
		this.directPlugins = props.plugins || [];
		this.directPlugins.forEach(checkStateComponent);
		this.dispatch = this.dispatch.bind(this);
		this.dom = place && place.mount || document.createElement("div");
		if (place) {
			if (place.appendChild) place.appendChild(this.dom);
			else if (typeof place == "function") place(this.dom);
			else if (place.mount) this.mounted = true;
		}
		this.editable = getEditable(this);
		updateCursorWrapper(this);
		this.nodeViews = buildNodeViews(this);
		this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this);
		this.domObserver = new DOMObserver(this, (from, to, typeOver, added) => readDOMChange(this, from, to, typeOver, added));
		this.domObserver.start();
		initInput(this);
		this.updatePluginViews();
	}
	/**
	Holds `true` when a
	[composition](https://w3c.github.io/uievents/#events-compositionevents)
	is active.
	*/
	get composing() {
		return this.input.composing;
	}
	/**
	The view's current [props](https://prosemirror.net/docs/ref/#view.EditorProps).
	*/
	get props() {
		if (this._props.state != this.state) {
			let prev = this._props;
			this._props = {};
			for (let name in prev) this._props[name] = prev[name];
			this._props.state = this.state;
		}
		return this._props;
	}
	/**
	Update the view's props. Will immediately cause an update to
	the DOM.
	*/
	update(props) {
		if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this);
		let prevProps = this._props;
		this._props = props;
		if (props.plugins) {
			props.plugins.forEach(checkStateComponent);
			this.directPlugins = props.plugins;
		}
		this.updateStateInner(props.state, prevProps);
	}
	/**
	Update the view by updating existing props object with the object
	given as argument. Equivalent to `view.update(Object.assign({},
	view.props, props))`.
	*/
	setProps(props) {
		let updated = {};
		for (let name in this._props) updated[name] = this._props[name];
		updated.state = this.state;
		for (let name in props) updated[name] = props[name];
		this.update(updated);
	}
	/**
	Update the editor's `state` prop, without touching any of the
	other props.
	*/
	updateState(state) {
		this.updateStateInner(state, this._props);
	}
	updateStateInner(state, prevProps) {
		var _a;
		let prev = this.state, redraw = false, updateSel = false;
		if (state.storedMarks && this.composing) {
			clearComposition(this);
			updateSel = true;
		}
		this.state = state;
		let pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins;
		if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) {
			let nodeViews = buildNodeViews(this);
			if (changedNodeViews(nodeViews, this.nodeViews)) {
				this.nodeViews = nodeViews;
				redraw = true;
			}
		}
		if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this);
		this.editable = getEditable(this);
		updateCursorWrapper(this);
		let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this);
		let scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset" : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve";
		let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco);
		if (updateDoc || !state.selection.eq(prev.selection)) updateSel = true;
		let oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this);
		if (updateSel) {
			this.domObserver.stop();
			let forceSelUpdate = updateDoc && (ie$1 || chrome) && !this.composing && !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection);
			if (updateDoc) {
				let chromeKludge = chrome ? this.trackWrites = this.domSelectionRange().focusNode : null;
				if (this.composing) this.input.compositionNode = findCompositionNode(this);
				if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) {
					this.docView.updateOuterDeco(outerDeco);
					this.docView.destroy();
					this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this);
				}
				if (chromeKludge && (!this.trackWrites || !this.dom.contains(this.trackWrites))) forceSelUpdate = true;
			}
			let mouseDown = this.input.mouseDown;
			if (forceSelUpdate || !(mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) && anchorInRightPlace(this) && mouseDown.delaySelUpdate())) selectionToDOM(this, forceSelUpdate);
			else {
				syncNodeSelection(this, state.selection);
				this.domObserver.setCurSelection();
			}
			this.domObserver.start();
		}
		this.updatePluginViews(prev);
		if (((_a = this.dragging) === null || _a === void 0 ? void 0 : _a.node) && !prev.doc.eq(state.doc)) this.updateDraggedNode(this.dragging, prev);
		if (scroll == "reset") this.dom.scrollTop = 0;
		else if (scroll == "to selection") this.scrollToSelection();
		else if (oldScrollPos) resetScrollPos(oldScrollPos);
	}
	/**
	@internal
	*/
	scrollToSelection() {
		let startDOM = this.domSelectionRange().focusNode;
		if (!startDOM || !this.dom.contains(startDOM.nodeType == 1 ? startDOM : startDOM.parentNode));
		else if (this.someProp("handleScrollToSelection", (f) => f(this)));
		else if (this.state.selection instanceof NodeSelection) {
			let target = this.docView.domAfterPos(this.state.selection.from);
			if (target.nodeType == 1) scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
		} else scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1), startDOM);
	}
	destroyPluginViews() {
		let view;
		while (view = this.pluginViews.pop()) if (view.destroy) view.destroy();
	}
	updatePluginViews(prevState) {
		if (!prevState || prevState.plugins != this.state.plugins || this.directPlugins != this.prevDirectPlugins) {
			this.prevDirectPlugins = this.directPlugins;
			this.destroyPluginViews();
			for (let i = 0; i < this.directPlugins.length; i++) {
				let plugin = this.directPlugins[i];
				if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this));
			}
			for (let i = 0; i < this.state.plugins.length; i++) {
				let plugin = this.state.plugins[i];
				if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this));
			}
		} else for (let i = 0; i < this.pluginViews.length; i++) {
			let pluginView = this.pluginViews[i];
			if (pluginView.update) pluginView.update(this, prevState);
		}
	}
	updateDraggedNode(dragging, prev) {
		let sel = dragging.node, found = -1;
		if (sel.from < this.state.doc.content.size && this.state.doc.nodeAt(sel.from) == sel.node) found = sel.from;
		else {
			let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size);
			if ((movedPos > 0 && movedPos < this.state.doc.content.size && this.state.doc.nodeAt(movedPos)) == sel.node) found = movedPos;
		}
		this.dragging = new Dragging(dragging.slice, dragging.move, found < 0 ? void 0 : NodeSelection.create(this.state.doc, found));
	}
	someProp(propName, f) {
		let prop = this._props && this._props[propName], value;
		if (prop != null && (value = f ? f(prop) : prop)) return value;
		for (let i = 0; i < this.directPlugins.length; i++) {
			let prop = this.directPlugins[i].props[propName];
			if (prop != null && (value = f ? f(prop) : prop)) return value;
		}
		let plugins = this.state.plugins;
		if (plugins) for (let i = 0; i < plugins.length; i++) {
			let prop = plugins[i].props[propName];
			if (prop != null && (value = f ? f(prop) : prop)) return value;
		}
	}
	/**
	Query whether the view has focus.
	*/
	hasFocus() {
		if (ie$1) {
			let node = this.root.activeElement;
			if (node == this.dom) return true;
			if (!node || !this.dom.contains(node)) return false;
			while (node && this.dom != node && this.dom.contains(node)) {
				if (node.contentEditable == "false") return false;
				node = node.parentElement;
			}
			return true;
		}
		return this.root.activeElement == this.dom;
	}
	/**
	Focus the editor.
	*/
	focus() {
		this.domObserver.stop();
		if (this.editable) focusPreventScroll(this.dom);
		selectionToDOM(this);
		this.domObserver.start();
	}
	/**
	Get the document root in which the editor exists. This will
	usually be the top-level `document`, but might be a [shadow
	DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM)
	root if the editor is inside one.
	*/
	get root() {
		let cached = this._root;
		if (cached == null) {
			for (let search = this.dom.parentNode; search; search = search.parentNode) if (search.nodeType == 9 || search.nodeType == 11 && search.host) {
				if (!search.getSelection) Object.getPrototypeOf(search).getSelection = () => search.ownerDocument.getSelection();
				return this._root = search;
			}
		}
		return cached || document;
	}
	/**
	When an existing editor view is moved to a new document or
	shadow tree, call this to make it recompute its root.
	*/
	updateRoot() {
		this._root = null;
	}
	/**
	Given a pair of viewport coordinates, return the document
	position that corresponds to them. May return null if the given
	coordinates aren't inside of the editor. When an object is
	returned, its `pos` property is the position nearest to the
	coordinates, and its `inside` property holds the position of the
	inner node that the position falls inside of, or -1 if it is at
	the top level, not in any node.
	*/
	posAtCoords(coords) {
		return posAtCoords(this, coords);
	}
	/**
	Returns the viewport rectangle at a given document position.
	`left` and `right` will be the same number, as this returns a
	flat cursor-ish rectangle. If the position is between two things
	that aren't directly adjacent, `side` determines which element
	is used. When < 0, the element before the position is used,
	otherwise the element after.
	*/
	coordsAtPos(pos, side = 1) {
		return coordsAtPos(this, pos, side);
	}
	/**
	Find the DOM position that corresponds to the given document
	position. When `side` is negative, find the position as close as
	possible to the content before the position. When positive,
	prefer positions close to the content after the position. When
	zero, prefer as shallow a position as possible.
	
	Note that you should **not** mutate the editor's internal DOM,
	only inspect it (and even that is usually not necessary).
	*/
	domAtPos(pos, side = 0) {
		return this.docView.domFromPos(pos, side);
	}
	/**
	Find the DOM node that represents the document node after the
	given position. May return `null` when the position doesn't point
	in front of a node or if the node is inside an opaque node view.
	
	This is intended to be able to call things like
	`getBoundingClientRect` on that DOM node. Do **not** mutate the
	editor DOM directly, or add styling this way, since that will be
	immediately overriden by the editor as it redraws the node.
	*/
	nodeDOM(pos) {
		let desc = this.docView.descAt(pos);
		return desc ? desc.nodeDOM : null;
	}
	/**
	Find the document position that corresponds to a given DOM
	position. (Whenever possible, it is preferable to inspect the
	document structure directly, rather than poking around in the
	DOM, but sometimes—for example when interpreting an event
	target—you don't have a choice.)
	
	The `bias` parameter can be used to influence which side of a DOM
	node to use when the position is inside a leaf node.
	*/
	posAtDOM(node, offset, bias = -1) {
		let pos = this.docView.posFromDOM(node, offset, bias);
		if (pos == null) throw new RangeError("DOM position not inside the editor");
		return pos;
	}
	/**
	Find out whether the selection is at the end of a textblock when
	moving in a given direction. When, for example, given `"left"`,
	it will return true if moving left from the current cursor
	position would leave that position's parent textblock. Will apply
	to the view's current state by default, but it is possible to
	pass a different state.
	*/
	endOfTextblock(dir, state) {
		return endOfTextblock(this, state || this.state, dir);
	}
	/**
	Run the editor's paste logic with the given HTML string. The
	`event`, if given, will be passed to the
	[`handlePaste`](https://prosemirror.net/docs/ref/#view.EditorProps.handlePaste) hook.
	*/
	pasteHTML(html, event) {
		return doPaste(this, "", html, false, event || new ClipboardEvent("paste"));
	}
	/**
	Run the editor's paste logic with the given plain-text input.
	*/
	pasteText(text, event) {
		return doPaste(this, text, null, true, event || new ClipboardEvent("paste"));
	}
	/**
	Serialize the given slice as it would be if it was copied from
	this editor. Returns a DOM element that contains a
	representation of the slice as its children, a textual
	representation, and the transformed slice (which can be
	different from the given input due to hooks like
	[`transformCopied`](https://prosemirror.net/docs/ref/#view.EditorProps.transformCopied)).
	*/
	serializeForClipboard(slice) {
		return serializeForClipboard(this, slice);
	}
	/**
	Removes the editor from the DOM and destroys all [node
	views](https://prosemirror.net/docs/ref/#view.NodeView).
	*/
	destroy() {
		if (!this.docView) return;
		destroyInput(this);
		this.destroyPluginViews();
		if (this.mounted) {
			this.docView.update(this.state.doc, [], viewDecorations(this), this);
			this.dom.textContent = "";
		} else if (this.dom.parentNode) this.dom.parentNode.removeChild(this.dom);
		this.docView.destroy();
		this.docView = null;
		clearReusedRange();
	}
	/**
	This is true when the view has been
	[destroyed](https://prosemirror.net/docs/ref/#view.EditorView.destroy) (and thus should not be
	used anymore).
	*/
	get isDestroyed() {
		return this.docView == null;
	}
	/**
	Used for testing.
	*/
	dispatchEvent(event) {
		return dispatchEvent(this, event);
	}
	/**
	@internal
	*/
	domSelectionRange() {
		let sel = this.domSelection();
		if (!sel) return {
			focusNode: null,
			focusOffset: 0,
			anchorNode: null,
			anchorOffset: 0
		};
		return safari && this.root.nodeType === 11 && deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel;
	}
	/**
	@internal
	*/
	domSelection() {
		return this.root.getSelection();
	}
};
EditorView.prototype.dispatch = function(tr) {
	let dispatchTransaction = this._props.dispatchTransaction;
	if (dispatchTransaction) dispatchTransaction.call(this, tr);
	else this.updateState(this.state.apply(tr));
};
function computeDocDeco(view) {
	let attrs = Object.create(null);
	attrs.class = "ProseMirror";
	attrs.contenteditable = String(view.editable);
	view.someProp("attributes", (value) => {
		if (typeof value == "function") value = value(view.state);
		if (value) {
			for (let attr in value) if (attr == "class") attrs.class += " " + value[attr];
			else if (attr == "style") attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr];
			else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") attrs[attr] = String(value[attr]);
		}
	});
	if (!attrs.translate) attrs.translate = "no";
	return [Decoration.node(0, view.state.doc.content.size, attrs)];
}
function updateCursorWrapper(view) {
	if (view.markCursor) {
		let dom = document.createElement("img");
		dom.className = "ProseMirror-separator";
		dom.setAttribute("mark-placeholder", "true");
		dom.setAttribute("alt", "");
		view.cursorWrapper = {
			dom,
			deco: Decoration.widget(view.state.selection.from, dom, {
				raw: true,
				marks: view.markCursor
			})
		};
	} else view.cursorWrapper = null;
}
function getEditable(view) {
	return !view.someProp("editable", (value) => value(view.state) === false);
}
function selectionContextChanged(sel1, sel2) {
	let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head));
	return sel1.$anchor.start(depth) != sel2.$anchor.start(depth);
}
function buildNodeViews(view) {
	let result = Object.create(null);
	function add(obj) {
		for (let prop in obj) if (!Object.prototype.hasOwnProperty.call(result, prop)) result[prop] = obj[prop];
	}
	view.someProp("nodeViews", add);
	view.someProp("markViews", add);
	return result;
}
function changedNodeViews(a, b) {
	let nA = 0, nB = 0;
	for (let prop in a) {
		if (a[prop] != b[prop]) return true;
		nA++;
	}
	for (let _ in b) nB++;
	return nA != nB;
}
function checkStateComponent(plugin) {
	if (plugin.spec.state || plugin.spec.filterTransaction || plugin.spec.appendTransaction) throw new RangeError("Plugins passed directly to the view must not have a state component");
}
//#endregion
//#region ../../node_modules/.pnpm/w3c-keyname@2.2.8/node_modules/w3c-keyname/index.js
var base = {
	8: "Backspace",
	9: "Tab",
	10: "Enter",
	12: "NumLock",
	13: "Enter",
	16: "Shift",
	17: "Control",
	18: "Alt",
	20: "CapsLock",
	27: "Escape",
	32: " ",
	33: "PageUp",
	34: "PageDown",
	35: "End",
	36: "Home",
	37: "ArrowLeft",
	38: "ArrowUp",
	39: "ArrowRight",
	40: "ArrowDown",
	44: "PrintScreen",
	45: "Insert",
	46: "Delete",
	59: ";",
	61: "=",
	91: "Meta",
	92: "Meta",
	106: "*",
	107: "+",
	108: ",",
	109: "-",
	110: ".",
	111: "/",
	144: "NumLock",
	145: "ScrollLock",
	160: "Shift",
	161: "Shift",
	162: "Control",
	163: "Control",
	164: "Alt",
	165: "Alt",
	173: "-",
	186: ";",
	187: "=",
	188: ",",
	189: "-",
	190: ".",
	191: "/",
	192: "`",
	219: "[",
	220: "\\",
	221: "]",
	222: "'"
};
var shift = {
	48: ")",
	49: "!",
	50: "@",
	51: "#",
	52: "$",
	53: "%",
	54: "^",
	55: "&",
	56: "*",
	57: "(",
	59: ":",
	61: "+",
	173: "_",
	186: ":",
	187: "+",
	188: "<",
	189: "_",
	190: ">",
	191: "?",
	192: "~",
	219: "{",
	220: "|",
	221: "}",
	222: "\""
};
var mac$1 = typeof navigator != "undefined" && /Mac/.test(navigator.platform);
var ie = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
for (var i = 0; i < 10; i++) base[48 + i] = base[96 + i] = String(i);
for (var i = 1; i <= 24; i++) base[i + 111] = "F" + i;
for (var i = 65; i <= 90; i++) {
	base[i] = String.fromCharCode(i + 32);
	shift[i] = String.fromCharCode(i);
}
for (var code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code];
function keyName(event) {
	var name = !(mac$1 && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified") && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified";
	if (name == "Esc") name = "Escape";
	if (name == "Del") name = "Delete";
	if (name == "Left") name = "ArrowLeft";
	if (name == "Up") name = "ArrowUp";
	if (name == "Right") name = "ArrowRight";
	if (name == "Down") name = "ArrowDown";
	return name;
}
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-keymap@1.2.3/node_modules/prosemirror-keymap/dist/index.js
var mac = typeof navigator != "undefined" && /Mac|iP(hone|[oa]d)/.test(navigator.platform);
var windows = typeof navigator != "undefined" && /Win/.test(navigator.platform);
function normalizeKeyName$1(name) {
	let parts = name.split(/-(?!$)/), result = parts[parts.length - 1];
	if (result == "Space") result = " ";
	let alt, ctrl, shift, meta;
	for (let i = 0; i < parts.length - 1; i++) {
		let mod = parts[i];
		if (/^(cmd|meta|m)$/i.test(mod)) meta = true;
		else if (/^a(lt)?$/i.test(mod)) alt = true;
		else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
		else if (/^s(hift)?$/i.test(mod)) shift = true;
		else if (/^mod$/i.test(mod)) {
			if (mac) meta = true;
			else ctrl = true;
		} else throw new Error("Unrecognized modifier name: " + mod);
	}
	if (alt) result = "Alt-" + result;
	if (ctrl) result = "Ctrl-" + result;
	if (meta) result = "Meta-" + result;
	if (shift) result = "Shift-" + result;
	return result;
}
function normalize(map) {
	let copy = Object.create(null);
	for (let prop in map) copy[normalizeKeyName$1(prop)] = map[prop];
	return copy;
}
function modifiers(name, event, shift = true) {
	if (event.altKey) name = "Alt-" + name;
	if (event.ctrlKey) name = "Ctrl-" + name;
	if (event.metaKey) name = "Meta-" + name;
	if (shift && event.shiftKey) name = "Shift-" + name;
	return name;
}
/**
Create a keymap plugin for the given set of bindings.

Bindings should map key names to [command](https://prosemirror.net/docs/ref/#commands)-style
functions, which will be called with `(EditorState, dispatch,
EditorView)` arguments, and should return true when they've handled
the key. Note that the view argument isn't part of the command
protocol, but can be used as an escape hatch if a binding needs to
directly interact with the UI.

Key names may be strings like `"Shift-Ctrl-Enter"`—a key
identifier prefixed with zero or more modifiers. Key identifiers
are based on the strings that can appear in
[`KeyEvent.key`](https:developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key).
Use lowercase letters to refer to letter keys (or uppercase letters
if you want shift to be held). You may use `"Space"` as an alias
for the `" "` name.

Modifiers can be given in any order. `Shift-` (or `s-`), `Alt-` (or
`a-`), `Ctrl-` (or `c-` or `Control-`) and `Cmd-` (or `m-` or
`Meta-`) are recognized. For characters that are created by holding
shift, the `Shift-` prefix is implied, and should not be added
explicitly.

You can use `Mod-` as a shorthand for `Cmd-` on Mac and `Ctrl-` on
other platforms.

You can add multiple keymap plugins to an editor. The order in
which they appear determines their precedence (the ones early in
the array get to dispatch first).
*/
function keymap(bindings) {
	return new Plugin({ props: { handleKeyDown: keydownHandler(bindings) } });
}
/**
Given a set of bindings (using the same format as
[`keymap`](https://prosemirror.net/docs/ref/#keymap.keymap)), return a [keydown
handler](https://prosemirror.net/docs/ref/#view.EditorProps.handleKeyDown) that handles them.
*/
function keydownHandler(bindings) {
	let map = normalize(bindings);
	return function(view, event) {
		let name = keyName(event), baseName, direct = map[modifiers(name, event)];
		if (direct && direct(view.state, view.dispatch, view)) return true;
		if (name.length == 1 && name != " ") {
			if (event.shiftKey) {
				let noShift = map[modifiers(name, event, false)];
				if (noShift && noShift(view.state, view.dispatch, view)) return true;
			}
			if ((event.altKey || event.metaKey || event.ctrlKey) && !(windows && event.ctrlKey && event.altKey) && (baseName = base[event.keyCode]) && baseName != name) {
				let fromCode = map[modifiers(baseName, event)];
				if (fromCode && fromCode(view.state, view.dispatch, view)) return true;
			}
		}
		return false;
	};
}
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+core@3.30.2_@tiptap+pm@3.30.2/node_modules/@tiptap/core/dist/index.js
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
var import_react_dom = /* @__PURE__ */ __toESM(require_react_dom(), 1);
var import_shim = require_shim();
var import_jsx_runtime = require_jsx_runtime();
var __defProp$5 = Object.defineProperty;
var __export$1 = (target, all) => {
	for (var name in all) __defProp$5(target, name, {
		get: all[name],
		enumerable: true
	});
};
function createChainableState(config) {
	const { state, transaction } = config;
	let { selection } = transaction;
	let { doc } = transaction;
	let { storedMarks } = transaction;
	return {
		...state,
		apply: state.apply.bind(state),
		applyTransaction: state.applyTransaction.bind(state),
		plugins: state.plugins,
		schema: state.schema,
		reconfigure: state.reconfigure.bind(state),
		toJSON: state.toJSON.bind(state),
		get storedMarks() {
			return storedMarks;
		},
		get selection() {
			return selection;
		},
		get doc() {
			return doc;
		},
		get tr() {
			selection = transaction.selection;
			doc = transaction.doc;
			storedMarks = transaction.storedMarks;
			return transaction;
		}
	};
}
var CommandManager = class _CommandManager {
	constructor(props) {
		this.editor = props.editor;
		this.rawCommands = this.editor.extensionManager.commands;
		this.customState = props.state;
	}
	get hasCustomState() {
		return !!this.customState;
	}
	get state() {
		return this.customState || this.editor.state;
	}
	get commands() {
		const { rawCommands, editor, state } = this;
		const { view } = editor;
		const { tr } = state;
		const props = this.buildProps(tr);
		return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
			const method = (...args) => {
				const callback = command2(...args)(props);
				if (!tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
				return callback;
			};
			return [name, method];
		}));
	}
	get chain() {
		return () => this.createChain();
	}
	get can() {
		return () => this.createCan();
	}
	createChain(startTr, shouldDispatch = true) {
		const { rawCommands, editor, state } = this;
		const { view } = editor;
		const callbacks = [];
		const hasStartTransaction = !!startTr;
		const tr = startTr || state.tr;
		const run3 = () => {
			if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) view.dispatch(tr);
			return callbacks.every((callback) => callback === true);
		};
		const chain = {
			...Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
				const chainedCommand = (...args) => {
					const props = this.buildProps(tr, shouldDispatch);
					const callback = command2(...args)(props);
					callbacks.push(callback);
					return chain;
				};
				return [name, chainedCommand];
			})),
			run: run3
		};
		return chain;
	}
	/**
	* Creates a chain that safely returns `false` when run.
	* @returns A non-dispatching command chain.
	* @example
	* const chain = CommandManager.createFakeChain()
	* chain.focus().run() // false
	*/
	static createFakeChain() {
		const chain = new Proxy({}, { get: (_target, property) => {
			if (property === "then") return;
			if (property === "run") return () => false;
			return () => chain;
		} });
		return chain;
	}
	createCan(startTr) {
		const { rawCommands, state } = this;
		const dispatch = false;
		const tr = startTr || state.tr;
		const props = this.buildProps(tr, dispatch);
		return {
			...Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
				return [name, (...args) => command2(...args)({
					...props,
					dispatch: void 0
				})];
			})),
			chain: () => this.createChain(tr, dispatch)
		};
	}
	/**
	* Creates capability checks that safely return `false`.
	* @returns A non-dispatching capability checker.
	* @example
	* const can = CommandManager.createFallbackCan()
	* can.focus() // false
	*/
	static createFallbackCan() {
		const chain = _CommandManager.createFakeChain();
		return new Proxy({ chain: () => chain }, { get: (target, property) => {
			if (property === "then") return;
			if (property === "chain") return target.chain;
			return () => false;
		} });
	}
	buildProps(tr, shouldDispatch = true) {
		const { rawCommands, editor, state } = this;
		const { view } = editor;
		const props = {
			tr,
			editor,
			view,
			state: createChainableState({
				state,
				transaction: tr
			}),
			dispatch: shouldDispatch ? () => void 0 : void 0,
			chain: () => this.createChain(tr, shouldDispatch),
			can: () => this.createCan(tr),
			get commands() {
				return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => {
					return [name, (...args) => command2(...args)(props)];
				}));
			}
		};
		return props;
	}
};
var commands_exports = {};
__export$1(commands_exports, {
	blur: () => blur,
	clearContent: () => clearContent,
	clearNodes: () => clearNodes,
	command: () => command,
	createParagraphNear: () => createParagraphNear,
	cut: () => cut,
	deleteCurrentNode: () => deleteCurrentNode,
	deleteNode: () => deleteNode,
	deleteRange: () => deleteRange,
	deleteSelection: () => deleteSelection,
	enter: () => enter,
	exitCode: () => exitCode,
	extendMarkRange: () => extendMarkRange,
	first: () => first,
	focus: () => focus,
	forEach: () => forEach,
	insertContent: () => insertContent,
	insertContentAt: () => insertContentAt,
	insertDefaultBlock: () => insertDefaultBlock,
	joinBackward: () => joinBackward,
	joinDown: () => joinDown,
	joinForward: () => joinForward,
	joinItemBackward: () => joinItemBackward,
	joinItemForward: () => joinItemForward,
	joinTextblockBackward: () => joinTextblockBackward,
	joinTextblockForward: () => joinTextblockForward,
	joinUp: () => joinUp,
	keyboardShortcut: () => keyboardShortcut,
	lift: () => lift,
	liftEmptyBlock: () => liftEmptyBlock,
	liftListItem: () => liftListItem,
	newlineInCode: () => newlineInCode,
	resetAttributes: () => resetAttributes,
	scrollIntoView: () => scrollIntoView,
	selectAll: () => selectAll,
	selectNodeBackward: () => selectNodeBackward,
	selectNodeForward: () => selectNodeForward,
	selectParentNode: () => selectParentNode,
	selectTextblockEnd: () => selectTextblockEnd,
	selectTextblockStart: () => selectTextblockStart,
	setContent: () => setContent,
	setMark: () => setMark,
	setMeta: () => setMeta,
	setNode: () => setNode,
	setNodeSelection: () => setNodeSelection,
	setTextDirection: () => setTextDirection,
	setTextSelection: () => setTextSelection,
	sinkListItem: () => sinkListItem,
	splitBlock: () => splitBlock,
	splitListItem: () => splitListItem,
	toggleList: () => toggleList,
	toggleMark: () => toggleMark,
	toggleNode: () => toggleNode,
	toggleWrap: () => toggleWrap,
	undoInputRule: () => undoInputRule,
	unsetAllMarks: () => unsetAllMarks,
	unsetMark: () => unsetMark,
	unsetTextDirection: () => unsetTextDirection,
	updateAttributes: () => updateAttributes,
	updateDecorations: () => updateDecorations,
	wrapIn: () => wrapIn,
	wrapInList: () => wrapInList
});
var blur = () => ({ editor, view }) => {
	requestAnimationFrame(() => {
		var _a;
		if (!editor.isDestroyed) {
			view.dom.blur();
			(_a = window == null ? void 0 : window.getSelection()) == null || _a.removeAllRanges();
		}
	});
	return true;
};
var clearContent = (emitUpdate = true) => ({ commands }) => {
	return commands.setContent("", { emitUpdate });
};
var clearNodes = () => ({ state, tr, dispatch }) => {
	const { selection } = tr;
	const { ranges } = selection;
	if (!dispatch) return true;
	ranges.forEach(({ $from, $to }) => {
		state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
			if (node.type.isText) return;
			const { doc, mapping } = tr;
			const $mappedFrom = doc.resolve(mapping.map(pos));
			const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize));
			const nodeRange = $mappedFrom.blockRange($mappedTo);
			if (!nodeRange) return;
			const targetLiftDepth = liftTarget(nodeRange);
			if (node.type.isTextblock) {
				const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index());
				tr.setNodeMarkup(nodeRange.start, defaultType);
			}
			if (targetLiftDepth || targetLiftDepth === 0) tr.lift(nodeRange, targetLiftDepth);
		});
	});
	return true;
};
var command = (fn) => (props) => {
	return fn(props);
};
var createParagraphNear = () => ({ state, dispatch }) => {
	return createParagraphNear$1(state, dispatch);
};
var cut = (originRange, targetPos) => ({ editor, tr }) => {
	const { state } = editor;
	const contentSlice = state.doc.slice(originRange.from, originRange.to);
	tr.deleteRange(originRange.from, originRange.to);
	const newPos = tr.mapping.map(targetPos);
	tr.insert(newPos, contentSlice.content);
	tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
	return true;
};
var deleteCurrentNode = () => ({ tr, dispatch }) => {
	const { selection } = tr;
	const currentNode = selection.$anchor.node();
	if (currentNode.content.size > 0) return false;
	const $pos = tr.selection.$anchor;
	for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === currentNode.type) {
		if (dispatch) {
			const from = $pos.before(depth);
			const to = $pos.after(depth);
			tr.delete(from, to).scrollIntoView();
		}
		return true;
	}
	return false;
};
function getNodeType(nameOrType, schema) {
	if (typeof nameOrType === "string") {
		if (!schema.nodes[nameOrType]) throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`);
		return schema.nodes[nameOrType];
	}
	return nameOrType;
}
var deleteNode = (typeOrName) => ({ tr, state, dispatch }) => {
	const type = getNodeType(typeOrName, state.schema);
	const $pos = tr.selection.$anchor;
	for (let depth = $pos.depth; depth > 0; depth -= 1) if ($pos.node(depth).type === type) {
		if (dispatch) {
			const from = $pos.before(depth);
			const to = $pos.after(depth);
			tr.delete(from, to).scrollIntoView();
		}
		return true;
	}
	return false;
};
var deleteRange = (range) => ({ tr, dispatch }) => {
	const { from, to } = range;
	if (dispatch) tr.delete(from, to);
	return true;
};
var hasTextContent = (nodeSpec) => {
	if (!nodeSpec.content) return false;
	return /^text(\*|\+)/.test(nodeSpec.content);
};
var expandSelectionForSide = ($pos, schema, side) => {
	if (!$pos.parent.isInline) return $pos.pos;
	if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) return $pos.pos;
	const parentContent = schema.nodes[$pos.parent.type.name].spec;
	if (!hasTextContent(parentContent)) return $pos.pos;
	return side === "left" ? $pos.start() - 1 : $pos.end() + 1;
};
var expandSelectionForInlineText = ($from, $to, schema) => {
	return {
		from: expandSelectionForSide($from, schema, "left"),
		to: expandSelectionForSide($to, schema, "right")
	};
};
var deleteSelection = () => ({ state, dispatch }) => {
	if (state.selection.empty) return false;
	if (dispatch) {
		const tr = state.tr;
		const { ranges } = state.selection;
		const mapFrom = tr.steps.length;
		ranges.forEach((range) => {
			const mapping = tr.mapping.slice(mapFrom);
			const { from, to } = expandSelectionForInlineText(tr.doc.resolve(mapping.map(range.$from.pos)), tr.doc.resolve(mapping.map(range.$to.pos)), state.schema);
			tr.deleteRange(from, to);
		});
		if (!tr.selection.empty) tr.setSelection(TextSelection.near(tr.doc.resolve(tr.selection.from)));
		tr.scrollIntoView();
		dispatch(tr);
	}
	return true;
};
var enter = () => ({ commands }) => {
	return commands.keyboardShortcut("Enter");
};
var exitCode = () => ({ state, dispatch }) => {
	return exitCode$1(state, dispatch);
};
function isRegExp(value) {
	return Object.prototype.toString.call(value) === "[object RegExp]";
}
function objectIncludes(object1, object2, options = { strict: true }) {
	const keys = Object.keys(object2);
	if (!keys.length) return true;
	return keys.every((key) => {
		if (options.strict) return object2[key] === object1[key];
		if (isRegExp(object2[key])) return object2[key].test(object1[key]);
		return object2[key] === object1[key];
	});
}
function findMarkInSet(marks, type, attributes = {}) {
	return marks.find((item) => {
		return item.type === type && objectIncludes(Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])), attributes);
	});
}
function isMarkInSet(marks, type, attributes = {}) {
	return !!findMarkInSet(marks, type, attributes);
}
function getMarkRange($pos, type, attributes) {
	if (!$pos || !type) return;
	let start = $pos.parent.childAfter($pos.parentOffset);
	if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) start = $pos.parent.childBefore($pos.parentOffset);
	if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) return;
	if (!attributes) {
		const firstMark = start.node.marks.find((mark2) => mark2.type === type);
		if (firstMark) attributes = firstMark.attrs;
	}
	if (!findMarkInSet([...start.node.marks], type, attributes)) return;
	let startIndex = start.index;
	let startPos = $pos.start() + start.offset;
	let endIndex = startIndex + 1;
	let endPos = startPos + start.node.nodeSize;
	while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) {
		startIndex -= 1;
		startPos -= $pos.parent.child(startIndex).nodeSize;
	}
	while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) {
		endPos += $pos.parent.child(endIndex).nodeSize;
		endIndex += 1;
	}
	return {
		from: startPos,
		to: endPos
	};
}
function getMarkType(nameOrType, schema) {
	if (typeof nameOrType === "string") {
		if (!schema.marks[nameOrType]) throw Error(`There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`);
		return schema.marks[nameOrType];
	}
	return nameOrType;
}
var extendMarkRange = (typeOrName, attributes) => ({ tr, state, dispatch }) => {
	const type = getMarkType(typeOrName, state.schema);
	const { doc, selection } = tr;
	const { $from, from, to } = selection;
	if (dispatch) {
		const range = getMarkRange($from, type, attributes);
		if (range && range.from <= from && range.to >= to) {
			const newSelection = TextSelection.create(doc, range.from, range.to);
			tr.setSelection(newSelection);
		}
	}
	return true;
};
var first = (commands) => (props) => {
	const items = typeof commands === "function" ? commands(props) : commands;
	for (let i = 0; i < items.length; i += 1) if (items[i](props)) return true;
	return false;
};
function isTextSelection(value) {
	return value instanceof TextSelection;
}
function minMax(value = 0, min = 0, max = 0) {
	return Math.min(Math.max(value, min), max);
}
function resolveFocusPosition(doc, position = null) {
	if (!position) return null;
	const selectionAtStart = Selection$1.atStart(doc);
	const selectionAtEnd = Selection$1.atEnd(doc);
	if (position === "start" || position === true) return selectionAtStart;
	if (position === "end") return selectionAtEnd;
	const minPos = selectionAtStart.from;
	const maxPos = selectionAtEnd.to;
	if (position === "all") return TextSelection.create(doc, minMax(0, minPos, maxPos), minMax(doc.content.size, minPos, maxPos));
	return TextSelection.create(doc, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos));
}
function isAndroid() {
	return ["Android"].includes(navigator.platform) || /android/i.test(navigator.userAgent);
}
function isiOS() {
	return [
		"iPad Simulator",
		"iPhone Simulator",
		"iPod Simulator",
		"iPad",
		"iPhone",
		"iPod"
	].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document;
}
function isSafari() {
	return typeof navigator !== "undefined" ? /^((?!chrome|android).)*safari/i.test(navigator.userAgent) : false;
}
var focus = (position = null, options = {}) => ({ editor, view, tr, dispatch }) => {
	options = {
		scrollIntoView: true,
		...options
	};
	const delayedFocus = () => {
		if (isiOS() || isAndroid()) view.dom.focus();
		if (isSafari() && !isiOS() && !isAndroid()) view.dom.focus({ preventScroll: true });
		requestAnimationFrame(() => {
			if (!editor.isDestroyed) {
				view.focus();
				if (options == null ? void 0 : options.scrollIntoView) editor.commands.scrollIntoView();
			}
		});
	};
	try {
		if (view.hasFocus() && position === null || position === false) return true;
	} catch {
		return false;
	}
	if (dispatch && position === null && !isTextSelection(editor.state.selection)) {
		delayedFocus();
		return true;
	}
	const selection = resolveFocusPosition(tr.doc, position) || editor.state.selection;
	const isSameSelection = editor.state.selection.eq(selection);
	if (dispatch) {
		if (!isSameSelection) tr.setSelection(selection);
		if (isSameSelection && tr.storedMarks) tr.setStoredMarks(tr.storedMarks);
		delayedFocus();
	}
	return true;
};
var forEach = (items, fn) => (props) => {
	return items.every((item, index) => fn(item, {
		...props,
		index
	}));
};
var insertContent = (value, options) => ({ tr, commands }) => {
	return commands.insertContentAt({
		from: tr.selection.from,
		to: tr.selection.to
	}, value, options);
};
var removeWhitespaces = (node) => {
	const children = node.childNodes;
	for (let i = children.length - 1; i >= 0; i -= 1) {
		const child = children[i];
		if (child.nodeType === 3 && child.nodeValue && /^(\n\s\s|\n)$/.test(child.nodeValue)) node.removeChild(child);
		else if (child.nodeType === 1) removeWhitespaces(child);
	}
	return node;
};
function elementFromString(value) {
	if (typeof window === "undefined") throw new Error("[tiptap error]: there is no window object available, so this function cannot be used");
	const wrappedValue = `<body>${value}</body>`;
	const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body;
	return removeWhitespaces(html);
}
function isProseMirrorContent(value) {
	return typeof (value == null ? void 0 : value.nodesBetween) === "function";
}
function createNodeFromContent(content, schema, options) {
	if (isProseMirrorContent(content)) return content;
	const isJSONContent = typeof content === "object" && content !== null;
	options = {
		slice: true,
		parseOptions: {},
		...options
	};
	const isTextContent = typeof content === "string";
	if (isJSONContent) try {
		if (Array.isArray(content) && content.length > 0) return Fragment$8.fromArray(content.map((item) => schema.nodeFromJSON(item)));
		const node = schema.nodeFromJSON(content);
		if (options.errorOnInvalidContent) node.check();
		return node;
	} catch (error) {
		if (options.errorOnInvalidContent) throw new Error("[tiptap error]: Invalid JSON content", { cause: error });
		console.warn("[tiptap warn]: Invalid content.", "Passed value:", content, "Error:", error);
		return createNodeFromContent("", schema, options);
	}
	if (isTextContent) {
		if (options.errorOnInvalidContent) {
			let hasInvalidContent = false;
			let invalidContent = "";
			const contentCheckSchema = new Schema({
				topNode: schema.spec.topNode,
				marks: schema.spec.marks,
				nodes: schema.spec.nodes.append({ __tiptap__private__unknown__catch__all__node: {
					content: "inline*",
					group: "block",
					parseDOM: [{
						tag: "*",
						getAttrs: (e) => {
							hasInvalidContent = true;
							invalidContent = typeof e === "string" ? e : e.outerHTML;
							return null;
						}
					}]
				} })
			});
			if (options.slice) DOMParser$1.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions);
			else DOMParser$1.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions);
			if (options.errorOnInvalidContent && hasInvalidContent) throw new Error("[tiptap error]: Invalid HTML content", { cause: /* @__PURE__ */ new Error(`Invalid element found: ${invalidContent}`) });
		}
		const parser = DOMParser$1.fromSchema(schema);
		if (options.slice) return parser.parseSlice(elementFromString(content), options.parseOptions).content;
		return parser.parse(elementFromString(content), options.parseOptions);
	}
	return createNodeFromContent("", schema, options);
}
function isFragment(nodeOrFragment) {
	return !("type" in nodeOrFragment);
}
function selectionToInsertionEnd(tr, startLen, bias) {
	const last = tr.steps.length - 1;
	if (last < startLen) return;
	const step = tr.steps[last];
	if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return;
	const map = tr.mapping.maps[last];
	let end = 0;
	map.forEach((_from, _to, _newFrom, newTo) => {
		if (end === 0) end = newTo;
	});
	tr.setSelection(Selection$1.near(tr.doc.resolve(end), bias));
}
var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) => {
	var _a;
	if (dispatch) {
		options = {
			parseOptions: editor.options.parseOptions,
			updateSelection: true,
			applyInputRules: false,
			applyPasteRules: false,
			...options
		};
		let content;
		const emitContentError = (error) => {
			editor.emit("contentError", {
				editor,
				error,
				disableCollaboration: () => {
					if ("collaboration" in editor.storage && typeof editor.storage.collaboration === "object" && editor.storage.collaboration) editor.storage.collaboration.isDisabled = true;
				}
			});
		};
		const parseOptions = {
			preserveWhitespace: "full",
			...options.parseOptions
		};
		if (!options.errorOnInvalidContent && !editor.options.enableContentCheck && editor.options.emitContentError) try {
			createNodeFromContent(value, editor.schema, {
				parseOptions,
				errorOnInvalidContent: true
			});
		} catch (e) {
			emitContentError(e);
		}
		try {
			content = createNodeFromContent(value, editor.schema, {
				parseOptions,
				errorOnInvalidContent: (_a = options.errorOnInvalidContent) != null ? _a : editor.options.enableContentCheck
			});
		} catch (e) {
			emitContentError(e);
			return false;
		}
		let { from, to } = typeof position === "number" ? {
			from: position,
			to: position
		} : {
			from: position.from,
			to: position.to
		};
		let isOnlyTextContent = true;
		let isOnlyBlockContent = true;
		const nodes = isFragment(content) ? content.content : [content];
		nodes.forEach((node) => {
			node.check();
			isOnlyTextContent = isOnlyTextContent ? node.isText && node.marks.length === 0 : false;
			isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false;
		});
		if (from === to && isOnlyBlockContent) {
			const { parent } = tr.doc.resolve(from);
			if (parent.isTextblock && !parent.type.spec.code && !parent.childCount) {
				from -= 1;
				to += 1;
			}
		}
		let newContent;
		if (isOnlyTextContent) {
			if (Array.isArray(value)) newContent = value.map((item) => item.text || "").join("");
			else if (isProseMirrorContent(value)) newContent = nodes.map((node) => {
				var _a2;
				return (_a2 = node.text) != null ? _a2 : "";
			}).join("");
			else if (typeof value === "object" && !!value && !!value.text) newContent = value.text;
			else newContent = value;
			tr.insertText(newContent, from, to);
		} else {
			newContent = Fragment$8.from(nodes);
			const $from = tr.doc.resolve(from);
			const $fromNode = $from.node();
			const fromSelectionAtStart = $from.parentOffset === 0;
			const isTextSelection2 = $fromNode.isText || $fromNode.isTextblock;
			const hasContent = $fromNode.content.size > 0;
			if (fromSelectionAtStart && isTextSelection2 && hasContent && isOnlyBlockContent) from = Math.max(0, from - 1);
			tr.replaceWith(from, to, nodes);
		}
		if (options.updateSelection) selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
		if (options.applyInputRules) tr.setMeta("applyInputRules", {
			from,
			text: newContent
		});
		if (options.applyPasteRules) tr.setMeta("applyPasteRules", {
			from,
			text: newContent
		});
	}
	return true;
};
function defaultBlockAt(match) {
	for (let i = 0; i < match.edgeCount; i += 1) {
		const { type } = match.edge(i);
		if (type.isTextblock && !type.hasRequiredAttrs()) return type;
	}
	return null;
}
var insertDefaultBlock = (options = {}) => ({ tr, dispatch, editor }) => {
	const { pos, attrs, content, updateSelection = true } = options;
	let $pos;
	if (typeof pos === "number") $pos = tr.doc.resolve(pos);
	else if (pos) $pos = pos;
	else $pos = tr.selection.$from;
	const defaultType = defaultBlockAt($pos.parent.contentMatchAt($pos.index()));
	if (!defaultType) return false;
	const validAttrKeys = Object.keys(defaultType.spec.attrs || {});
	const filteredAttrs = attrs ? Object.fromEntries(Object.entries(attrs).filter(([key]) => validAttrKeys.includes(key))) : {};
	let node;
	if (content) {
		const parsed = createNodeFromContent(content, editor.schema);
		node = defaultType.createAndFill(filteredAttrs, parsed);
	} else node = defaultType.createAndFill(filteredAttrs);
	if (!node) return false;
	if (dispatch) {
		tr.insert($pos.pos, node);
		if (updateSelection) selectionToInsertionEnd(tr, tr.steps.length - 1, -1);
	}
	return true;
};
var joinUp = () => ({ state, dispatch }) => {
	return joinUp$1(state, dispatch);
};
var joinDown = () => ({ state, dispatch }) => {
	return joinDown$1(state, dispatch);
};
var joinBackward = () => ({ state, dispatch }) => {
	return joinBackward$1(state, dispatch);
};
var joinForward = () => ({ state, dispatch }) => {
	return joinForward$1(state, dispatch);
};
var joinItemBackward = () => ({ state, dispatch, tr }) => {
	try {
		const point = joinPoint(state.doc, state.selection.$from.pos, -1);
		if (point === null || point === void 0) return false;
		tr.join(point, 2);
		if (dispatch) dispatch(tr);
		return true;
	} catch {
		return false;
	}
};
var joinItemForward = () => ({ state, dispatch, tr }) => {
	try {
		const point = joinPoint(state.doc, state.selection.$from.pos, 1);
		if (point === null || point === void 0) return false;
		tr.join(point, 2);
		if (dispatch) dispatch(tr);
		return true;
	} catch {
		return false;
	}
};
var joinTextblockBackward = () => ({ state, dispatch }) => {
	return joinTextblockBackward$1(state, dispatch);
};
var joinTextblockForward = () => ({ state, dispatch }) => {
	return joinTextblockForward$1(state, dispatch);
};
function isMacOS() {
	return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
}
function normalizeKeyName(name) {
	const parts = name.split(/-(?!$)/);
	let result = parts[parts.length - 1];
	if (result === "Space") result = " ";
	let alt;
	let ctrl;
	let shift;
	let meta;
	for (let i = 0; i < parts.length - 1; i += 1) {
		const mod = parts[i];
		if (/^(cmd|meta|m)$/i.test(mod)) meta = true;
		else if (/^a(lt)?$/i.test(mod)) alt = true;
		else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
		else if (/^s(hift)?$/i.test(mod)) shift = true;
		else if (/^mod$/i.test(mod)) {
			if (isiOS() || isMacOS()) meta = true;
			else ctrl = true;
		} else throw new Error(`Unrecognized modifier name: ${mod}`);
	}
	if (alt) result = `Alt-${result}`;
	if (ctrl) result = `Ctrl-${result}`;
	if (meta) result = `Meta-${result}`;
	if (shift) result = `Shift-${result}`;
	return result;
}
var keyboardShortcut = (name) => ({ editor, view, tr, dispatch }) => {
	const keys = normalizeKeyName(name).split(/-(?!$)/);
	const key = keys.find((item) => ![
		"Alt",
		"Ctrl",
		"Meta",
		"Shift"
	].includes(item));
	const event = new KeyboardEvent("keydown", {
		key: key === "Space" ? " " : key,
		altKey: keys.includes("Alt"),
		ctrlKey: keys.includes("Ctrl"),
		metaKey: keys.includes("Meta"),
		shiftKey: keys.includes("Shift"),
		bubbles: true,
		cancelable: true
	});
	editor.captureTransaction(() => {
		view.someProp("handleKeyDown", (f) => f(view, event));
	})?.steps.forEach((step) => {
		const newStep = step.map(tr.mapping);
		if (newStep && dispatch) tr.maybeStep(newStep);
	});
	return true;
};
function isNodeActive(state, typeOrName, attributes = {}) {
	const { from, to, empty } = state.selection;
	const type = typeOrName ? getNodeType(typeOrName, state.schema) : null;
	const nodeRanges = [];
	state.doc.nodesBetween(from, to, (node, pos) => {
		if (node.isText) return;
		const relativeFrom = Math.max(from, pos);
		const relativeTo = Math.min(to, pos + node.nodeSize);
		nodeRanges.push({
			node,
			from: relativeFrom,
			to: relativeTo
		});
	});
	const selectionRange = to - from;
	const matchedNodeRanges = nodeRanges.filter((nodeRange) => {
		if (!type) return true;
		return type.name === nodeRange.node.type.name;
	}).filter((nodeRange) => objectIncludes(nodeRange.node.attrs, attributes, { strict: false }));
	if (empty) return !!matchedNodeRanges.length;
	return matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0) >= selectionRange;
}
var lift = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
	if (!isNodeActive(state, getNodeType(typeOrName, state.schema), attributes)) return false;
	return lift$1(state, dispatch);
};
var liftEmptyBlock = () => ({ state, dispatch }) => {
	return liftEmptyBlock$1(state, dispatch);
};
var liftListItem = (typeOrName) => ({ state, dispatch }) => {
	return liftListItem$1(getNodeType(typeOrName, state.schema))(state, dispatch);
};
var newlineInCode = () => ({ state, dispatch }) => {
	return newlineInCode$1(state, dispatch);
};
function getSchemaTypeNameByName(name, schema) {
	if (schema.nodes[name]) return "node";
	if (schema.marks[name]) return "mark";
	return null;
}
function deleteProps(obj, propOrProps) {
	const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps;
	return Object.keys(obj).reduce((newObj, prop) => {
		if (!props.includes(prop)) newObj[prop] = obj[prop];
		return newObj;
	}, {});
}
var resetAttributes = (typeOrName, attributes) => ({ tr, state, dispatch }) => {
	let nodeType = null;
	let markType = null;
	const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema);
	if (!schemaType) return false;
	if (schemaType === "node") nodeType = getNodeType(typeOrName, state.schema);
	if (schemaType === "mark") markType = getMarkType(typeOrName, state.schema);
	let canReset = false;
	tr.selection.ranges.forEach((range) => {
		state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => {
			if (nodeType && nodeType === node.type) {
				canReset = true;
				if (dispatch) tr.setNodeMarkup(pos, void 0, deleteProps(node.attrs, attributes));
			}
			if (markType && node.marks.length) node.marks.forEach((mark) => {
				if (markType === mark.type) {
					canReset = true;
					if (dispatch) tr.addMark(pos, pos + node.nodeSize, markType.create(deleteProps(mark.attrs, attributes)));
				}
			});
		});
	});
	return canReset;
};
var scrollIntoView = () => ({ tr, dispatch }) => {
	if (dispatch) tr.scrollIntoView();
	return true;
};
var selectAll = () => ({ tr, dispatch }) => {
	if (dispatch) {
		const selection = new AllSelection(tr.doc);
		tr.setSelection(selection);
	}
	return true;
};
var selectNodeBackward = () => ({ state, dispatch }) => {
	return selectNodeBackward$1(state, dispatch);
};
var selectNodeForward = () => ({ state, dispatch }) => {
	return selectNodeForward$1(state, dispatch);
};
var selectParentNode = () => ({ state, dispatch }) => {
	return selectParentNode$1(state, dispatch);
};
var selectTextblockEnd = () => ({ state, dispatch }) => {
	return selectTextblockEnd$1(state, dispatch);
};
var selectTextblockStart = () => ({ state, dispatch }) => {
	return selectTextblockStart$1(state, dispatch);
};
function createDocument(content, schema, parseOptions = {}, options = {}) {
	return createNodeFromContent(content, schema, {
		slice: false,
		parseOptions,
		errorOnInvalidContent: options.errorOnInvalidContent
	});
}
var setContent = (content, { errorOnInvalidContent, emitUpdate = true, parseOptions = {} } = {}) => ({ editor, tr, dispatch, commands }) => {
	const { doc } = tr;
	if (parseOptions.preserveWhitespace !== "full") {
		const document2 = createDocument(content, editor.schema, parseOptions, { errorOnInvalidContent: errorOnInvalidContent != null ? errorOnInvalidContent : editor.options.enableContentCheck });
		if (dispatch) {
			const nodes = isFragment(document2) ? document2.content : [document2];
			tr.replaceWith(0, doc.content.size, nodes).setMeta("preventUpdate", !emitUpdate);
		}
		return true;
	}
	if (dispatch) tr.setMeta("preventUpdate", !emitUpdate);
	return commands.insertContentAt({
		from: 0,
		to: doc.content.size
	}, content, {
		parseOptions,
		errorOnInvalidContent: errorOnInvalidContent != null ? errorOnInvalidContent : editor.options.enableContentCheck
	});
};
function getMarkAttributes(state, typeOrName) {
	const type = getMarkType(typeOrName, state.schema);
	const { from, to, empty } = state.selection;
	const marks = [];
	if (empty) {
		if (state.storedMarks) marks.push(...state.storedMarks);
		marks.push(...state.selection.$head.marks());
	} else state.doc.nodesBetween(from, to, (node) => {
		marks.push(...node.marks);
	});
	const mark = marks.find((markItem) => markItem.type.name === type.name);
	if (!mark) return {};
	return { ...mark.attrs };
}
function combineTransactionSteps(oldDoc, transactions) {
	const transform = new Transform(oldDoc);
	transactions.forEach((transaction) => {
		transaction.steps.forEach((step) => {
			transform.step(step);
		});
	});
	return transform;
}
function findChildrenInRange(node, range, predicate) {
	const nodesWithPos = [];
	node.nodesBetween(range.from, range.to, (child, pos) => {
		if (predicate(child)) nodesWithPos.push({
			node: child,
			pos
		});
	});
	return nodesWithPos;
}
function findParentNodeClosestToPos($pos, predicate) {
	for (let i = $pos.depth; i > 0; i -= 1) {
		const node = $pos.node(i);
		if (predicate(node)) return {
			pos: i > 0 ? $pos.before(i) : 0,
			start: $pos.start(i),
			depth: i,
			node
		};
	}
}
function findParentNode(predicate) {
	return (selection) => findParentNodeClosestToPos(selection.$from, predicate);
}
function getExtensionField(extension, field, context) {
	if (extension.config[field] === void 0 && extension.parent) return getExtensionField(extension.parent, field, context);
	if (typeof extension.config[field] === "function") return extension.config[field].bind({
		...context,
		parent: extension.parent ? getExtensionField(extension.parent, field, context) : null
	});
	return extension.config[field];
}
function flattenExtensions(extensions) {
	return extensions.map((extension) => {
		const addExtensions = getExtensionField(extension, "addExtensions", {
			name: extension.name,
			options: extension.options,
			storage: extension.storage
		});
		if (addExtensions) return [extension, ...flattenExtensions(addExtensions())];
		return extension;
	}).flat(10);
}
function getHTMLFromFragment(fragment, schema) {
	const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment);
	const container = document.implementation.createHTMLDocument().createElement("div");
	container.appendChild(documentFragment);
	return container.innerHTML;
}
function isFunction$3(value) {
	return typeof value === "function";
}
function callOrReturn(value, context = void 0, ...props) {
	if (isFunction$3(value)) {
		if (context) return value.bind(context)(...props);
		return value(...props);
	}
	return value;
}
function isEmptyObject(value = {}) {
	return Object.keys(value).length === 0 && value.constructor === Object;
}
function splitExtensions(extensions) {
	return {
		baseExtensions: extensions.filter((extension) => extension.type === "extension"),
		nodeExtensions: extensions.filter((extension) => extension.type === "node"),
		markExtensions: extensions.filter((extension) => extension.type === "mark")
	};
}
function getAttributesFromExtensions(extensions) {
	const extensionAttributes = [];
	const { nodeExtensions, markExtensions } = splitExtensions(extensions);
	const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions];
	const defaultAttribute = {
		default: null,
		validate: void 0,
		rendered: true,
		renderHTML: null,
		parseHTML: null,
		keepOnSplit: true,
		isRequired: false
	};
	const nodeExtensionTypes = nodeExtensions.filter((ext) => ext.name !== "text").map((ext) => ext.name);
	const markExtensionTypes = markExtensions.map((ext) => ext.name);
	const allExtensionTypes = [...nodeExtensionTypes, ...markExtensionTypes];
	extensions.forEach((extension) => {
		const addGlobalAttributes = getExtensionField(extension, "addGlobalAttributes", {
			name: extension.name,
			options: extension.options,
			storage: extension.storage,
			extensions: nodeAndMarkExtensions
		});
		if (!addGlobalAttributes) return;
		addGlobalAttributes().forEach((globalAttribute) => {
			let resolvedTypes;
			if (Array.isArray(globalAttribute.types)) resolvedTypes = globalAttribute.types;
			else if (globalAttribute.types === "*") resolvedTypes = allExtensionTypes;
			else if (globalAttribute.types === "nodes") resolvedTypes = nodeExtensionTypes;
			else if (globalAttribute.types === "marks") resolvedTypes = markExtensionTypes;
			else resolvedTypes = [];
			resolvedTypes.forEach((type) => {
				Object.entries(globalAttribute.attributes).forEach(([name, attribute]) => {
					extensionAttributes.push({
						type,
						name,
						attribute: {
							...defaultAttribute,
							...attribute
						}
					});
				});
			});
		});
	});
	nodeAndMarkExtensions.forEach((extension) => {
		const addAttributes = getExtensionField(extension, "addAttributes", {
			name: extension.name,
			options: extension.options,
			storage: extension.storage
		});
		if (!addAttributes) return;
		const attributes = addAttributes();
		Object.entries(attributes).forEach(([name, attribute]) => {
			const mergedAttr = {
				...defaultAttribute,
				...attribute
			};
			if (typeof (mergedAttr == null ? void 0 : mergedAttr.default) === "function") mergedAttr.default = mergedAttr.default();
			if ((mergedAttr == null ? void 0 : mergedAttr.isRequired) && (mergedAttr == null ? void 0 : mergedAttr.default) === void 0) delete mergedAttr.default;
			extensionAttributes.push({
				type: extension.name,
				name,
				attribute: mergedAttr
			});
		});
	});
	return extensionAttributes;
}
function splitStyleDeclarations(styles) {
	const result = [];
	let current = "";
	let inSingleQuote = false;
	let inDoubleQuote = false;
	let parenDepth = 0;
	const length = styles.length;
	for (let i = 0; i < length; i += 1) {
		const char = styles[i];
		if (char === "'" && !inDoubleQuote) {
			inSingleQuote = !inSingleQuote;
			current += char;
			continue;
		}
		if (char === "\"" && !inSingleQuote) {
			inDoubleQuote = !inDoubleQuote;
			current += char;
			continue;
		}
		if (!inSingleQuote && !inDoubleQuote) {
			if (char === "(") {
				parenDepth += 1;
				current += char;
				continue;
			}
			if (char === ")" && parenDepth > 0) {
				parenDepth -= 1;
				current += char;
				continue;
			}
			if (char === ";" && parenDepth === 0) {
				result.push(current);
				current = "";
				continue;
			}
		}
		current += char;
	}
	if (current) result.push(current);
	return result;
}
function parseStyleEntries(styles) {
	const pairs = [];
	const declarations = splitStyleDeclarations(styles || "");
	const numDeclarations = declarations.length;
	for (let i = 0; i < numDeclarations; i += 1) {
		const declaration = declarations[i];
		const firstColonIndex = declaration.indexOf(":");
		if (firstColonIndex === -1) continue;
		const property = declaration.slice(0, firstColonIndex).trim();
		const value = declaration.slice(firstColonIndex + 1).trim();
		if (property && value) pairs.push([property, value]);
	}
	return pairs;
}
function mergeAttributes(...objects) {
	return objects.filter((item) => !!item).reduce((items, item) => {
		const mergedAttributes = { ...items };
		Object.entries(item).forEach(([key, value]) => {
			if (!mergedAttributes[key]) {
				mergedAttributes[key] = value;
				return;
			}
			if (key === "class") {
				const valueClasses = value ? String(value).split(" ") : [];
				const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : [];
				const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass));
				mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" ");
			} else if (key === "style") {
				const styleMap = new Map([...parseStyleEntries(mergedAttributes[key]), ...parseStyleEntries(value)]);
				mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; ");
			} else mergedAttributes[key] = value;
		});
		return mergedAttributes;
	}, {});
}
function getRenderedAttributes(nodeOrMark, extensionAttributes) {
	return extensionAttributes.filter((attribute) => attribute.type === nodeOrMark.type.name).filter((item) => item.attribute.rendered).map((item) => {
		if (!item.attribute.renderHTML) return { [item.name]: nodeOrMark.attrs[item.name] };
		return item.attribute.renderHTML(nodeOrMark.attrs) || {};
	}).reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {});
}
function fromString(value) {
	if (typeof value !== "string") return value;
	if (value.match(/^[+-]?(?:\d*\.)?\d+$/)) return Number(value);
	if (value === "true") return true;
	if (value === "false") return false;
	return value;
}
function injectExtensionAttributesToParseRule(parseRule, extensionAttributes) {
	if ("style" in parseRule) return parseRule;
	return {
		...parseRule,
		getAttrs: (node) => {
			const oldAttributes = parseRule.getAttrs ? parseRule.getAttrs(node) : parseRule.attrs;
			if (oldAttributes === false) return false;
			const newAttributes = extensionAttributes.reduce((items, item) => {
				const value = item.attribute.parseHTML ? item.attribute.parseHTML(node) : fromString(node.getAttribute(item.name));
				if (value === null || value === void 0) return items;
				return {
					...items,
					[item.name]: value
				};
			}, {});
			return {
				...oldAttributes,
				...newAttributes
			};
		}
	};
}
function cleanUpSchemaItem(data) {
	return Object.fromEntries(Object.entries(data).filter(([key, value]) => {
		if (key === "attrs" && isEmptyObject(value)) return false;
		return value !== null && value !== void 0;
	}));
}
function buildAttributeSpec(extensionAttribute) {
	var _a, _b;
	const spec = {};
	if (!((_a = extensionAttribute == null ? void 0 : extensionAttribute.attribute) == null ? void 0 : _a.isRequired) && "default" in ((extensionAttribute == null ? void 0 : extensionAttribute.attribute) || {})) spec.default = extensionAttribute.attribute.default;
	if (((_b = extensionAttribute == null ? void 0 : extensionAttribute.attribute) == null ? void 0 : _b.validate) !== void 0) spec.validate = extensionAttribute.attribute.validate;
	return [extensionAttribute.name, spec];
}
function getSchemaByResolvedExtensions(extensions, editor) {
	var _a;
	const allAttributes = getAttributesFromExtensions(extensions);
	const { nodeExtensions, markExtensions } = splitExtensions(extensions);
	return new Schema({
		topNode: (_a = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) == null ? void 0 : _a.name,
		nodes: Object.fromEntries(nodeExtensions.map((extension) => {
			const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
			const context = {
				name: extension.name,
				options: extension.options,
				storage: extension.storage,
				editor
			};
			const schema = cleanUpSchemaItem({
				...extensions.reduce((fields, e) => {
					const extendNodeSchema = getExtensionField(e, "extendNodeSchema", context);
					return {
						...fields,
						...extendNodeSchema ? extendNodeSchema(extension) : {}
					};
				}, {}),
				content: callOrReturn(getExtensionField(extension, "content", context)),
				marks: callOrReturn(getExtensionField(extension, "marks", context)),
				group: callOrReturn(getExtensionField(extension, "group", context)),
				inline: callOrReturn(getExtensionField(extension, "inline", context)),
				atom: callOrReturn(getExtensionField(extension, "atom", context)),
				selectable: callOrReturn(getExtensionField(extension, "selectable", context)),
				draggable: callOrReturn(getExtensionField(extension, "draggable", context)),
				code: callOrReturn(getExtensionField(extension, "code", context)),
				whitespace: callOrReturn(getExtensionField(extension, "whitespace", context)),
				linebreakReplacement: callOrReturn(getExtensionField(extension, "linebreakReplacement", context)),
				defining: callOrReturn(getExtensionField(extension, "defining", context)),
				isolating: callOrReturn(getExtensionField(extension, "isolating", context)),
				attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
			});
			const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
			if (parseHTML) schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
			const renderHTML = getExtensionField(extension, "renderHTML", context);
			if (renderHTML) schema.toDOM = (node) => renderHTML({
				node,
				HTMLAttributes: getRenderedAttributes(node, extensionAttributes)
			});
			const renderText = getExtensionField(extension, "renderText", context);
			if (renderText) schema.toText = renderText;
			return [extension.name, schema];
		})),
		marks: Object.fromEntries(markExtensions.map((extension) => {
			const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name);
			const context = {
				name: extension.name,
				options: extension.options,
				storage: extension.storage,
				editor
			};
			const schema = cleanUpSchemaItem({
				...extensions.reduce((fields, e) => {
					const extendMarkSchema = getExtensionField(e, "extendMarkSchema", context);
					return {
						...fields,
						...extendMarkSchema ? extendMarkSchema(extension) : {}
					};
				}, {}),
				inclusive: callOrReturn(getExtensionField(extension, "inclusive", context)),
				excludes: callOrReturn(getExtensionField(extension, "excludes", context)),
				group: callOrReturn(getExtensionField(extension, "group", context)),
				spanning: callOrReturn(getExtensionField(extension, "spanning", context)),
				code: callOrReturn(getExtensionField(extension, "code", context)),
				attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec))
			});
			const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context));
			if (parseHTML) schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes));
			const renderHTML = getExtensionField(extension, "renderHTML", context);
			if (renderHTML) schema.toDOM = (mark) => renderHTML({
				mark,
				HTMLAttributes: getRenderedAttributes(mark, extensionAttributes)
			});
			return [extension.name, schema];
		}))
	});
}
function findDuplicates(items) {
	const filtered = items.filter((el, index) => items.indexOf(el) !== index);
	return Array.from(new Set(filtered));
}
function sortExtensions(extensions) {
	const defaultPriority = 100;
	return extensions.sort((a, b) => {
		const priorityA = getExtensionField(a, "priority") || defaultPriority;
		const priorityB = getExtensionField(b, "priority") || defaultPriority;
		if (priorityA > priorityB) return -1;
		if (priorityA < priorityB) return 1;
		return 0;
	});
}
function resolveExtensions(extensions) {
	const resolvedExtensions = sortExtensions(flattenExtensions(extensions));
	const duplicatedNames = findDuplicates(resolvedExtensions.map((extension) => extension.name));
	if (duplicatedNames.length) console.warn(`[tiptap warn]: Duplicate extension names found: [${duplicatedNames.map((item) => `'${item}'`).join(", ")}]. This can lead to issues.`);
	return resolvedExtensions;
}
function getTextBetween(startNode, range, options) {
	const { from, to } = range;
	const { blockSeparator = "\n\n", textSerializers = {} } = options || {};
	let text = "";
	startNode.nodesBetween(from, to, (node, pos, parent, index) => {
		var _a;
		if (node.isBlock && pos > from) text += blockSeparator;
		const textSerializer = textSerializers == null ? void 0 : textSerializers[node.type.name];
		if (textSerializer) {
			if (parent) text += textSerializer({
				node,
				pos,
				parent,
				index,
				range
			});
			return false;
		}
		if (node.isText) text += (_a = node == null ? void 0 : node.text) == null ? void 0 : _a.slice(Math.max(from, pos) - pos, to - pos);
	});
	return text;
}
function getText(node, options) {
	return getTextBetween(node, {
		from: 0,
		to: node.content.size
	}, options);
}
function getTextSerializersFromSchema(schema) {
	return Object.fromEntries(Object.entries(schema.nodes).filter(([, node]) => node.spec.toText).map(([name, node]) => [name, node.spec.toText]));
}
function getNodeAttributes(state, typeOrName) {
	const type = getNodeType(typeOrName, state.schema);
	const { from, to } = state.selection;
	const nodes = [];
	state.doc.nodesBetween(from, to, (node2) => {
		nodes.push(node2);
	});
	const node = nodes.reverse().find((nodeItem) => nodeItem.type.name === type.name);
	if (!node) return {};
	return { ...node.attrs };
}
function getAttributes(state, typeOrName) {
	const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema);
	if (schemaType === "node") return getNodeAttributes(state, typeOrName);
	if (schemaType === "mark") return getMarkAttributes(state, typeOrName);
	return {};
}
function removeDuplicates(array, by = JSON.stringify) {
	const seen = {};
	return array.filter((item) => {
		const key = by(item);
		return Object.prototype.hasOwnProperty.call(seen, key) ? false : seen[key] = true;
	});
}
function simplifyChangedRanges(changes) {
	const uniqueChanges = removeDuplicates(changes);
	return uniqueChanges.length === 1 ? uniqueChanges : uniqueChanges.filter((change, index) => {
		return !uniqueChanges.filter((_, i) => i !== index).some((otherChange) => {
			return change.oldRange.from >= otherChange.oldRange.from && change.oldRange.to <= otherChange.oldRange.to && change.newRange.from >= otherChange.newRange.from && change.newRange.to <= otherChange.newRange.to;
		});
	});
}
function getChangedRanges(transform) {
	const { mapping, steps } = transform;
	const changes = [];
	mapping.maps.forEach((stepMap, index) => {
		const ranges = [];
		if (!stepMap.ranges.length) {
			const { from, to } = steps[index];
			if (from === void 0 || to === void 0) return;
			ranges.push({
				from,
				to
			});
		} else stepMap.forEach((from, to) => {
			ranges.push({
				from,
				to
			});
		});
		ranges.forEach(({ from, to }) => {
			const newStart = mapping.slice(index).map(from, -1);
			const newEnd = mapping.slice(index).map(to);
			const oldStart = mapping.invert().map(newStart, -1);
			const oldEnd = mapping.invert().map(newEnd);
			changes.push({
				oldRange: {
					from: oldStart,
					to: oldEnd
				},
				newRange: {
					from: newStart,
					to: newEnd
				}
			});
		});
	});
	return simplifyChangedRanges(changes);
}
function getMarksBetween(from, to, doc) {
	const marks = [];
	if (from === to) doc.resolve(from).marks().forEach((mark) => {
		const range = getMarkRange(doc.resolve(from), mark.type);
		if (!range) return;
		marks.push({
			mark,
			...range
		});
	});
	else doc.nodesBetween(from, to, (node, pos) => {
		if (!node || (node == null ? void 0 : node.nodeSize) === void 0) return;
		marks.push(...node.marks.map((mark) => ({
			from: pos,
			to: pos + node.nodeSize,
			mark
		})));
	});
	return marks;
}
var getNodeAtPosition = (state, typeOrName, pos, maxDepth = 20) => {
	const $pos = state.doc.resolve(pos);
	let currentDepth = maxDepth;
	let node = null;
	while (currentDepth > 0 && node === null) {
		const currentNode = $pos.node(currentDepth);
		if ((currentNode == null ? void 0 : currentNode.type.name) === typeOrName) node = currentNode;
		else currentDepth -= 1;
	}
	return [node, currentDepth];
};
var getPreviousBlockSibling = ($pos) => {
	const parentDepth = $pos.depth - 1;
	if (parentDepth < 0) return null;
	const index = $pos.index(parentDepth);
	if (index === 0) return null;
	return $pos.node(parentDepth).child(index - 1);
};
function getSchemaTypeByName(name, schema) {
	return schema.nodes[name] || schema.marks[name] || null;
}
function getSplittedAttributes(extensionAttributes, typeName, attributes) {
	return Object.fromEntries(Object.entries(attributes).filter(([name]) => {
		const extensionAttribute = extensionAttributes.find((item) => {
			return item.type === typeName && item.name === name;
		});
		if (!extensionAttribute) return false;
		return extensionAttribute.attribute.keepOnSplit;
	}));
}
var getTextContentFromNodes = ($from, maxMatch = 500) => {
	let textBefore = "";
	const sliceEndPos = $from.parentOffset;
	$from.parent.nodesBetween(Math.max(0, sliceEndPos - maxMatch), sliceEndPos, (node, pos, parent, index) => {
		var _a, _b;
		const chunk = ((_b = (_a = node.type.spec).toText) == null ? void 0 : _b.call(_a, {
			node,
			pos,
			parent,
			index
		})) || node.textContent || "%leaf%";
		textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
	});
	return textBefore;
};
function isMarkActive(state, typeOrName, attributes = {}) {
	const { empty, ranges } = state.selection;
	const type = typeOrName ? getMarkType(typeOrName, state.schema) : null;
	if (empty) return !!(state.storedMarks || state.selection.$from.marks()).filter((mark) => {
		if (!type) return true;
		return type.name === mark.type.name;
	}).find((mark) => objectIncludes(mark.attrs, attributes, { strict: false }));
	let selectionRange = 0;
	const markRanges = [];
	ranges.forEach(({ $from, $to }) => {
		const from = $from.pos;
		const to = $to.pos;
		state.doc.nodesBetween(from, to, (node, pos) => {
			if (type && node.inlineContent && !node.type.allowsMarkType(type)) return false;
			if (!node.isText && !node.marks.length) return;
			const relativeFrom = Math.max(from, pos);
			const relativeTo = Math.min(to, pos + node.nodeSize);
			const range2 = relativeTo - relativeFrom;
			selectionRange += range2;
			markRanges.push(...node.marks.map((mark) => ({
				mark,
				from: relativeFrom,
				to: relativeTo
			})));
		});
	});
	if (selectionRange === 0) return false;
	const matchedRange = markRanges.filter((markRange) => {
		if (!type) return true;
		return type.name === markRange.mark.type.name;
	}).filter((markRange) => objectIncludes(markRange.mark.attrs, attributes, { strict: false })).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0);
	const excludedRange = markRanges.filter((markRange) => {
		if (!type) return true;
		return markRange.mark.type !== type && markRange.mark.type.excludes(type);
	}).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0);
	return (matchedRange > 0 ? matchedRange + excludedRange : matchedRange) >= selectionRange;
}
function isActive(state, name, attributes = {}) {
	if (!name) return isNodeActive(state, null, attributes) || isMarkActive(state, null, attributes);
	const schemaType = getSchemaTypeNameByName(name, state.schema);
	if (schemaType === "node") return isNodeActive(state, name, attributes);
	if (schemaType === "mark") return isMarkActive(state, name, attributes);
	return false;
}
var isAtEndOfNode = (state, nodeType) => {
	const { $from, $to, $anchor } = state.selection;
	if (nodeType) {
		const parentNode = findParentNode((node) => node.type.name === nodeType)(state.selection);
		if (!parentNode) return false;
		const $parentPos = state.doc.resolve(parentNode.pos + 1);
		if ($anchor.pos + 1 === $parentPos.end()) return true;
		return false;
	}
	if ($to.parentOffset < $to.parent.nodeSize - 2 || $from.pos !== $to.pos) return false;
	return true;
};
var isAtStartOfNode = (state) => {
	const { $from, $to } = state.selection;
	if ($from.parentOffset > 0 || $from.pos !== $to.pos) return false;
	return true;
};
function isExtensionRulesEnabled(extension, enabled) {
	if (Array.isArray(enabled)) return enabled.some((enabledExtension) => {
		return (typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name) === extension.name;
	});
	return enabled;
}
function isList(name, extensions) {
	const { nodeExtensions } = splitExtensions(extensions);
	const extension = nodeExtensions.find((item) => item.name === name);
	if (!extension) return false;
	const group = callOrReturn(getExtensionField(extension, "group", {
		name: extension.name,
		options: extension.options,
		storage: extension.storage
	}));
	if (typeof group !== "string") return false;
	return group.split(" ").includes("list");
}
function isNodeEmpty(node, { checkChildren = true, ignoreWhitespace = false } = {}) {
	var _a;
	if (ignoreWhitespace) {
		if (node.type.name === "hardBreak") return true;
		if (node.isText) return !/\S/.test((_a = node.text) != null ? _a : "");
	}
	if (node.isText) return !node.text;
	if (node.isAtom || node.isLeaf) return false;
	if (node.content.childCount === 0) return true;
	if (checkChildren) {
		let isContentEmpty = true;
		node.content.forEach((childNode) => {
			if (isContentEmpty === false) return;
			if (!isNodeEmpty(childNode, {
				ignoreWhitespace,
				checkChildren
			})) isContentEmpty = false;
		});
		return isContentEmpty;
	}
	return false;
}
function isNodeSelection(value) {
	return value instanceof NodeSelection;
}
var MappablePosition = class _MappablePosition {
	constructor(position) {
		this.position = position;
	}
	/**
	* Creates a MappablePosition from a JSON object.
	*/
	static fromJSON(json) {
		return new _MappablePosition(json.position);
	}
	/**
	* Converts the MappablePosition to a JSON object.
	*/
	toJSON() {
		return { position: this.position };
	}
};
function getUpdatedPosition(position, transaction) {
	const mapResult = transaction.mapping.mapResult(position.position);
	return {
		position: new MappablePosition(mapResult.pos),
		mapResult
	};
}
function createMappablePosition(position) {
	return new MappablePosition(position);
}
function canSetMark(state, tr, newMarkType) {
	var _a;
	const { selection } = tr;
	let cursor = null;
	if (isTextSelection(selection)) cursor = selection.$cursor;
	if (cursor) {
		const currentMarks = (_a = state.storedMarks) != null ? _a : cursor.marks();
		return cursor.parent.type.allowsMarkType(newMarkType) && (!!newMarkType.isInSet(currentMarks) || !currentMarks.some((mark) => mark.type.excludes(newMarkType)));
	}
	const { ranges } = selection;
	return ranges.some(({ $from, $to }) => {
		let someNodeSupportsMark = $from.depth === 0 ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType) : false;
		state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => {
			if (someNodeSupportsMark) return false;
			if (node.isInline) {
				const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType);
				const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks) || !node.marks.some((otherMark) => otherMark.type.excludes(newMarkType));
				someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType;
			}
			return !someNodeSupportsMark;
		});
		return someNodeSupportsMark;
	});
}
var setMark = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
	const { selection } = tr;
	const { empty, ranges } = selection;
	const type = getMarkType(typeOrName, state.schema);
	if (dispatch) {
		if (empty) {
			const oldAttributes = getMarkAttributes(state, type);
			tr.addStoredMark(type.create({
				...oldAttributes,
				...attributes
			}));
		} else ranges.forEach((range) => {
			const from = range.$from.pos;
			const to = range.$to.pos;
			state.doc.nodesBetween(from, to, (node, pos) => {
				const trimmedFrom = Math.max(pos, from);
				const trimmedTo = Math.min(pos + node.nodeSize, to);
				if (node.marks.find((mark) => mark.type === type)) node.marks.forEach((mark) => {
					if (type === mark.type) tr.addMark(trimmedFrom, trimmedTo, type.create({
						...mark.attrs,
						...attributes
					}));
				});
				else tr.addMark(trimmedFrom, trimmedTo, type.create(attributes));
			});
		});
	}
	return canSetMark(state, tr, type);
};
var setMeta = (key, value) => ({ tr }) => {
	tr.setMeta(key, value);
	return true;
};
var setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => {
	const type = getNodeType(typeOrName, state.schema);
	let attributesToCopy;
	if (state.selection.$anchor.sameParent(state.selection.$head)) attributesToCopy = state.selection.$anchor.parent.attrs;
	if (!type.isTextblock) {
		console.warn("[tiptap warn]: Currently \"setNode()\" only supports text block nodes.");
		return false;
	}
	return chain().command(({ commands }) => {
		if (setBlockType(type, {
			...attributesToCopy,
			...attributes
		})(state)) return true;
		return commands.clearNodes();
	}).command(({ state: updatedState }) => {
		return setBlockType(type, {
			...attributesToCopy,
			...attributes
		})(updatedState, dispatch);
	}).run();
};
var setNodeSelection = (position) => ({ tr, dispatch }) => {
	if (dispatch) {
		const { doc } = tr;
		const from = minMax(position, 0, doc.content.size);
		const selection = NodeSelection.create(doc, from);
		tr.setSelection(selection);
	}
	return true;
};
var setTextDirection = (direction, position) => ({ tr, state, dispatch }) => {
	const { selection } = state;
	let from;
	let to;
	if (typeof position === "number") {
		from = position;
		to = position;
	} else if (position && "from" in position && "to" in position) {
		from = position.from;
		to = position.to;
	} else {
		from = selection.from;
		to = selection.to;
	}
	if (dispatch) tr.doc.nodesBetween(from, to, (node, pos) => {
		if (node.isText) return;
		tr.setNodeMarkup(pos, void 0, {
			...node.attrs,
			dir: direction
		});
	});
	return true;
};
var setTextSelection = (position) => ({ tr, dispatch }) => {
	if (dispatch) {
		const { doc } = tr;
		const { from, to } = typeof position === "number" ? {
			from: position,
			to: position
		} : position;
		const minPos = TextSelection.atStart(doc).from;
		const maxPos = TextSelection.atEnd(doc).to;
		const resolvedFrom = minMax(from, minPos, maxPos);
		const resolvedEnd = minMax(to, minPos, maxPos);
		const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd);
		tr.setSelection(selection);
	}
	return true;
};
var sinkListItem = (typeOrName) => ({ state, dispatch }) => {
	return sinkListItem$1(getNodeType(typeOrName, state.schema))(state, dispatch);
};
function ensureMarks(state, splittableMarks) {
	const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks();
	if (marks) {
		const filteredMarks = marks.filter((mark) => splittableMarks == null ? void 0 : splittableMarks.includes(mark.type.name));
		state.tr.ensureMarks(filteredMarks);
	}
}
var splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor }) => {
	const { selection, doc } = tr;
	const { $from, $to } = selection;
	const extensionAttributes = editor.extensionManager.attributes;
	const newAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
	if (selection instanceof NodeSelection && selection.node.isBlock) {
		if (!$from.parentOffset || !canSplit(doc, $from.pos)) return false;
		if (dispatch) {
			if (keepMarks) ensureMarks(state, editor.extensionManager.splittableMarks);
			tr.split($from.pos).scrollIntoView();
		}
		return true;
	}
	if (!$from.parent.isBlock) return false;
	const atEnd = $to.parentOffset === $to.parent.content.size;
	const deflt = $from.depth === 0 ? void 0 : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
	let types = atEnd && deflt ? [{
		type: deflt,
		attrs: newAttributes
	}] : void 0;
	let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types);
	if (!types && !can && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) {
		can = true;
		types = deflt ? [{
			type: deflt,
			attrs: newAttributes
		}] : void 0;
	}
	if (dispatch) {
		if (can) {
			if (selection instanceof TextSelection) tr.deleteSelection();
			tr.split(tr.mapping.map($from.pos), 1, types);
			if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {
				const first2 = tr.mapping.map($from.before());
				const $first = tr.doc.resolve(first2);
				if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
			}
		}
		if (keepMarks) ensureMarks(state, editor.extensionManager.splittableMarks);
		tr.scrollIntoView();
	}
	return can;
};
var splitListItem = (typeOrName, overrideAttrs = {}) => ({ tr, state, dispatch, editor }) => {
	var _a;
	const type = getNodeType(typeOrName, state.schema);
	const { $from, $to } = state.selection;
	const node = state.selection.node;
	if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) return false;
	const grandParent = $from.node(-1);
	if (grandParent.type !== type) return false;
	const extensionAttributes = editor.extensionManager.attributes;
	if ($from.parent.content.size === 0 && $from.node(-1).childCount === $from.indexAfter(-1)) {
		if ($from.depth === 2 || $from.node(-3).type !== type || $from.index(-2) !== $from.node(-2).childCount - 1) return false;
		if (dispatch) {
			let wrap = Fragment$8.empty;
			const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3;
			for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d -= 1) wrap = Fragment$8.from($from.node(d).copy(wrap));
			const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3;
			const newNextTypeAttributes2 = {
				...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
				...overrideAttrs
			};
			const nextType2 = ((_a = type.contentMatch.defaultType) == null ? void 0 : _a.createAndFill(newNextTypeAttributes2)) || void 0;
			wrap = wrap.append(Fragment$8.from(type.createAndFill(null, nextType2) || void 0));
			const start = $from.before($from.depth - (depthBefore - 1));
			tr.replace(start, $from.after(-depthAfter), new Slice(wrap, 4 - depthBefore, 0));
			let sel = -1;
			tr.doc.nodesBetween(start, tr.doc.content.size, (n, pos) => {
				if (sel > -1) return false;
				if (n.isTextblock && n.content.size === 0) sel = pos + 1;
			});
			if (sel > -1) tr.setSelection(TextSelection.near(tr.doc.resolve(sel)));
			tr.scrollIntoView();
		}
		return true;
	}
	const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null;
	const newTypeAttributes = {
		...getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs),
		...overrideAttrs
	};
	const newNextTypeAttributes = {
		...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
		...overrideAttrs
	};
	tr.delete($from.pos, $to.pos);
	const types = nextType ? [{
		type,
		attrs: newTypeAttributes
	}, {
		type: nextType,
		attrs: newNextTypeAttributes
	}] : [{
		type,
		attrs: newTypeAttributes
	}];
	if (!canSplit(tr.doc, $from.pos, 2)) return false;
	if (dispatch) {
		const { selection, storedMarks } = state;
		const { splittableMarks } = editor.extensionManager;
		const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
		tr.split($from.pos, 2, types).scrollIntoView();
		if (!marks || !dispatch) return true;
		const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
		tr.ensureMarks(filteredMarks);
	}
	return true;
};
function normalizeListType(type) {
	return !type || type === "1" ? null : type;
}
function areListTypesCompatible(typeA, typeB) {
	return normalizeListType(typeA) === normalizeListType(typeB);
}
var joinListBackwards = (tr, listType) => {
	const list = findParentNode((node) => node.type === listType)(tr.selection);
	if (!list) return true;
	const before = tr.doc.resolve(Math.max(0, list.pos - 1)).before(list.depth);
	if (before === void 0) return true;
	const nodeBefore = tr.doc.nodeAt(before);
	if (!(list.node.type === (nodeBefore == null ? void 0 : nodeBefore.type) && canJoin(tr.doc, list.pos))) return true;
	if (!areListTypesCompatible(list.node.attrs.type, nodeBefore == null ? void 0 : nodeBefore.attrs.type)) return true;
	tr.join(list.pos);
	return true;
};
var joinListForwards = (tr, listType) => {
	const list = findParentNode((node) => node.type === listType)(tr.selection);
	if (!list) return true;
	const after = tr.doc.resolve(list.start).after(list.depth);
	if (after === void 0) return true;
	const nodeAfter = tr.doc.nodeAt(after);
	if (!(list.node.type === (nodeAfter == null ? void 0 : nodeAfter.type) && canJoin(tr.doc, after))) return true;
	if (!areListTypesCompatible(list.node.attrs.type, nodeAfter == null ? void 0 : nodeAfter.attrs.type)) return true;
	tr.join(after);
	return true;
};
function createInnerSelectionForWholeDocList(tr) {
	const doc = tr.doc;
	const list = doc.firstChild;
	if (!list) return null;
	const $start = doc.resolve(1);
	const $end = doc.resolve(list.nodeSize - 1);
	return TextSelection.between($start, $end);
}
var toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({ editor, tr, state, dispatch, chain, commands, can }) => {
	const { extensions, splittableMarks } = editor.extensionManager;
	const listType = getNodeType(listTypeOrName, state.schema);
	const itemType = getNodeType(itemTypeOrName, state.schema);
	const { selection, storedMarks } = state;
	const { $from, $to } = selection;
	const range = $from.blockRange($to);
	const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
	if (!range) return false;
	const parentList = findParentNode((node) => isList(node.type.name, extensions))(selection);
	const isAllSelection = selection.from === 0 && selection.to === state.doc.content.size;
	const topLevelNodes = state.doc.content.content;
	const soleTopLevelNode = topLevelNodes.length === 1 ? topLevelNodes[0] : null;
	const allSelectionList = isAllSelection && soleTopLevelNode && isList(soleTopLevelNode.type.name, extensions) ? {
		node: soleTopLevelNode,
		pos: 0,
		depth: 0
	} : null;
	const currentList = parentList != null ? parentList : allSelectionList;
	const isInsideExistingList = !!parentList && range.depth >= 1 && range.depth - parentList.depth <= 1;
	const hasWholeDocSelectedList = !!allSelectionList;
	if ((isInsideExistingList || hasWholeDocSelectedList) && currentList) {
		if (currentList.node.type === listType) {
			if (isAllSelection && hasWholeDocSelectedList) return chain().command(({ tr: trx, dispatch: disp }) => {
				const nextSelection = createInnerSelectionForWholeDocList(trx);
				if (!nextSelection) return false;
				trx.setSelection(nextSelection);
				if (disp) disp(trx);
				return true;
			}).liftListItem(itemType).run();
			return commands.liftListItem(itemType);
		}
		if (isList(currentList.node.type.name, extensions) && listType.validContent(currentList.node.content)) return chain().command(() => {
			tr.setNodeMarkup(currentList.pos, listType);
			return true;
		}).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
	}
	if (!keepMarks || !marks || !dispatch) return chain().command(() => {
		if (can().wrapInList(listType, attributes)) return true;
		return commands.clearNodes();
	}).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
	return chain().command(() => {
		const canWrapInList = can().wrapInList(listType, attributes);
		const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
		tr.ensureMarks(filteredMarks);
		if (canWrapInList) return true;
		return commands.clearNodes();
	}).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run();
};
var toggleMark = (typeOrName, attributes = {}, options = {}) => ({ state, commands }) => {
	const { extendEmptyMarkRange = false } = options;
	const type = getMarkType(typeOrName, state.schema);
	if (isMarkActive(state, type, attributes)) return commands.unsetMark(type, { extendEmptyMarkRange });
	return commands.setMark(type, attributes);
};
var toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands }) => {
	const type = getNodeType(typeOrName, state.schema);
	const toggleType = getNodeType(toggleTypeOrName, state.schema);
	const isActive2 = isNodeActive(state, type, attributes);
	let attributesToCopy;
	if (state.selection.$anchor.sameParent(state.selection.$head)) attributesToCopy = state.selection.$anchor.parent.attrs;
	if (isActive2) return commands.setNode(toggleType, attributesToCopy);
	return commands.setNode(type, {
		...attributesToCopy,
		...attributes
	});
};
var toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => {
	const type = getNodeType(typeOrName, state.schema);
	if (isNodeActive(state, type, attributes)) return commands.lift(type);
	return commands.wrapIn(type, attributes);
};
var undoInputRule = () => ({ state, dispatch }) => {
	const plugins = state.plugins;
	for (let i = 0; i < plugins.length; i += 1) {
		const plugin = plugins[i];
		let undoable;
		if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {
			if (dispatch) {
				const tr = state.tr;
				const toUndo = undoable.transform;
				for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) tr.step(toUndo.steps[j].invert(toUndo.docs[j]));
				if (undoable.text) {
					const marks = tr.doc.resolve(undoable.from).marks();
					tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks));
				} else tr.delete(undoable.from, undoable.to);
			}
			return true;
		}
	}
	return false;
};
var unsetAllMarks = (options = {}) => ({ tr, dispatch, editor }) => {
	const { ignoreClearable = false } = options;
	const { selection } = tr;
	const { empty, ranges } = selection;
	if (empty) return true;
	const { nonClearableMarks } = editor.extensionManager;
	if (dispatch) {
		const clearableMarkTypes = Object.values(editor.schema.marks).filter((markType) => ignoreClearable || !nonClearableMarks.includes(markType.name));
		ranges.forEach((range) => {
			for (const markType of clearableMarkTypes) tr.removeMark(range.$from.pos, range.$to.pos, markType);
		});
	}
	return true;
};
var unsetMark = (typeOrName, options = {}) => ({ tr, state, dispatch }) => {
	var _a;
	const { extendEmptyMarkRange = false } = options;
	const { selection } = tr;
	const type = getMarkType(typeOrName, state.schema);
	const { $from, empty, ranges } = selection;
	if (!dispatch) return true;
	if (empty && extendEmptyMarkRange) {
		let { from, to } = selection;
		const range = getMarkRange($from, type, (_a = $from.marks().find((mark) => mark.type === type)) == null ? void 0 : _a.attrs);
		if (range) {
			from = range.from;
			to = range.to;
		}
		tr.removeMark(from, to, type);
	} else ranges.forEach((range) => {
		tr.removeMark(range.$from.pos, range.$to.pos, type);
	});
	tr.removeStoredMark(type);
	return true;
};
var unsetTextDirection = (position) => ({ tr, state, dispatch }) => {
	const { selection } = state;
	let from;
	let to;
	if (typeof position === "number") {
		from = position;
		to = position;
	} else if (position && "from" in position && "to" in position) {
		from = position.from;
		to = position.to;
	} else {
		from = selection.from;
		to = selection.to;
	}
	if (dispatch) tr.doc.nodesBetween(from, to, (node, pos) => {
		if (node.isText) return;
		const newAttrs = { ...node.attrs };
		delete newAttrs.dir;
		tr.setNodeMarkup(pos, void 0, newAttrs);
	});
	return true;
};
var updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
	let nodeType = null;
	let markType = null;
	const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema);
	if (!schemaType) return false;
	if (schemaType === "node") nodeType = getNodeType(typeOrName, state.schema);
	if (schemaType === "mark") markType = getMarkType(typeOrName, state.schema);
	let canUpdate = false;
	tr.selection.ranges.forEach((range) => {
		const from = range.$from.pos;
		const to = range.$to.pos;
		let lastPos;
		let lastNode;
		let trimmedFrom;
		let trimmedTo;
		if (tr.selection.empty) state.doc.nodesBetween(from, to, (node, pos) => {
			if (nodeType && nodeType === node.type) {
				canUpdate = true;
				trimmedFrom = Math.max(pos, from);
				trimmedTo = Math.min(pos + node.nodeSize, to);
				lastPos = pos;
				lastNode = node;
			}
		});
		else state.doc.nodesBetween(from, to, (node, pos) => {
			if (pos < from && nodeType && nodeType === node.type) {
				canUpdate = true;
				trimmedFrom = Math.max(pos, from);
				trimmedTo = Math.min(pos + node.nodeSize, to);
				lastPos = pos;
				lastNode = node;
			}
			if (pos >= from && pos <= to) {
				if (nodeType && nodeType === node.type) {
					canUpdate = true;
					if (dispatch) tr.setNodeMarkup(pos, void 0, {
						...node.attrs,
						...attributes
					});
				}
				if (markType && node.marks.length) node.marks.forEach((mark) => {
					if (markType === mark.type) {
						canUpdate = true;
						if (dispatch) {
							const trimmedFrom2 = Math.max(pos, from);
							const trimmedTo2 = Math.min(pos + node.nodeSize, to);
							tr.addMark(trimmedFrom2, trimmedTo2, markType.create({
								...mark.attrs,
								...attributes
							}));
						}
					}
				});
			}
		});
		if (lastNode) {
			if (lastPos !== void 0 && dispatch) tr.setNodeMarkup(lastPos, void 0, {
				...lastNode.attrs,
				...attributes
			});
			if (markType && lastNode.marks.length) lastNode.marks.forEach((mark) => {
				if (markType === mark.type && dispatch) tr.addMark(trimmedFrom, trimmedTo, markType.create({
					...mark.attrs,
					...attributes
				}));
			});
		}
	});
	return canUpdate;
};
var DECORATION_MANAGER_PLUGIN_KEY = new PluginKey("__tiptap_decorations__");
var updateDecorations = (extensionName) => ({ tr, dispatch }) => {
	if (dispatch) tr.setMeta(DECORATION_MANAGER_PLUGIN_KEY, {
		type: "force",
		name: extensionName
	});
	return true;
};
var wrapIn = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
	return wrapIn$1(getNodeType(typeOrName, state.schema), attributes)(state, dispatch);
};
var wrapInList = (typeOrName, attributes = {}) => ({ state, dispatch }) => {
	return wrapInList$1(getNodeType(typeOrName, state.schema), attributes)(state, dispatch);
};
var depthByEditor = /* @__PURE__ */ new WeakMap();
function runInDecorationApplyScope(editor, callback) {
	var _a, _b;
	depthByEditor.set(editor, ((_a = depthByEditor.get(editor)) != null ? _a : 0) + 1);
	try {
		return callback();
	} finally {
		const remaining = ((_b = depthByEditor.get(editor)) != null ? _b : 1) - 1;
		if (remaining > 0) depthByEditor.set(editor, remaining);
		else depthByEditor.delete(editor);
	}
}
function isInDecorationApplyScope(editor) {
	return depthByEditor.has(editor);
}
var EventEmitter = class {
	constructor() {
		this.callbacks = {};
	}
	on(event, fn) {
		if (!this.callbacks[event]) this.callbacks[event] = [];
		this.callbacks[event].push(fn);
		return this;
	}
	emit(event, ...args) {
		const callbacks = this.callbacks[event];
		if (callbacks) callbacks.forEach((callback) => callback.apply(this, args));
		return this;
	}
	off(event, fn) {
		const callbacks = this.callbacks[event];
		if (callbacks) {
			if (fn) this.callbacks[event] = callbacks.filter((callback) => callback !== fn);
			else delete this.callbacks[event];
		}
		return this;
	}
	once(event, fn) {
		const onceFn = (...args) => {
			this.off(event, onceFn);
			fn.apply(this, args);
		};
		return this.on(event, onceFn);
	}
	removeAllListeners() {
		this.callbacks = {};
	}
};
var isDev$1 = typeof process !== "undefined" && false;
function isWidgetDecoration(decoration) {
	return decoration.kind === "widget";
}
function decorationsToPMDecorations(decorations, extensionName) {
	const pmDecorations = [];
	const widgetKeys = /* @__PURE__ */ new Set();
	for (const decoration of decorations) {
		if (decoration.kind === "widget") {
			if (isWidgetDecoration(decoration)) widgetKeys.add(decoration.key);
		}
		pmDecorations.push(decoration.toPMDecoration(extensionName));
	}
	return {
		decorations: pmDecorations,
		widgetKeys
	};
}
function buildDecorationSet(doc, decorations, extensionName) {
	const { decorations: pmDecorations, widgetKeys } = decorationsToPMDecorations(decorations, extensionName);
	return {
		set: DecorationSet.create(doc, pmDecorations),
		widgetKeys
	};
}
function rangeOwnsPosition({ position, from, to, docSize }) {
	if (position < from) return false;
	if (position < to) return true;
	return position === to && to === docSize;
}
function filterOutOfRangeDecorations({ decorations, from, to, docSize, extensionName, warnedExtensions }) {
	return decorations.filter((decoration) => {
		if (rangeOwnsPosition({
			position: decoration.anchor,
			from,
			to,
			docSize
		})) return true;
		if (decoration.anchor === to) return false;
		if (!warnedExtensions.has(extensionName)) {
			warnedExtensions.add(extensionName);
			console.warn(`[tiptap warn]: Extension "${extensionName}" returned a decoration outside the requested range [${from}, ${to}). It was ignored.`);
		}
		return false;
	});
}
function widgetKeyOf(decoration) {
	var _a;
	const key = (_a = decoration.spec) == null ? void 0 : _a.key;
	return typeof key === "string" ? key : void 0;
}
function findDuplicateWidgetKeys(decorationSet) {
	var _a, _b, _c;
	const extensionsByKey = /* @__PURE__ */ new Map();
	const counts = /* @__PURE__ */ new Map();
	for (const decoration of decorationSet.find()) {
		const key = widgetKeyOf(decoration);
		if (!key) continue;
		const extension = (_a = decoration.spec.extensionName) != null ? _a : "unknown";
		const extensions = (_b = extensionsByKey.get(key)) != null ? _b : /* @__PURE__ */ new Set();
		extensions.add(extension);
		extensionsByKey.set(key, extensions);
		counts.set(key, ((_c = counts.get(key)) != null ? _c : 0) + 1);
	}
	return Array.from(extensionsByKey, ([key, extensions]) => ({
		key,
		extensions
	})).filter(({ key }) => {
		var _a2;
		return ((_a2 = counts.get(key)) != null ? _a2 : 0) > 1;
	});
}
function isAttrStep(step) {
	return step.jsonID === "attr";
}
function hasResolvableChangedRange(step) {
	let hasMappedRange = false;
	step.getMap().forEach(() => {
		hasMappedRange = true;
	});
	if (hasMappedRange || isAttrStep(step)) return true;
	const positionalStep = step;
	return typeof positionalStep.from === "number" && typeof positionalStep.to === "number";
}
function blockRangeFor(doc, changed) {
	let from = null;
	let to = 0;
	let nodeStart = 0;
	for (let index = 0; index < doc.childCount; index += 1) {
		if (nodeStart > changed.to) break;
		const nodeEnd = nodeStart + doc.child(index).nodeSize;
		if (nodeEnd >= changed.from) {
			if (from === null) from = nodeStart;
			to = nodeEnd;
		}
		nodeStart = nodeEnd;
	}
	return from === null ? null : {
		from,
		to
	};
}
function getRebuildRanges(tr, doc) {
	if (tr.steps.some((step) => !hasResolvableChangedRange(step))) return { type: "full" };
	const newRanges = getChangedRanges(tr).map(({ newRange }) => newRange);
	tr.steps.forEach((step, index) => {
		if (!isAttrStep(step)) return;
		const mapping = tr.mapping.slice(index);
		newRanges.push({
			from: mapping.map(step.pos, -1),
			to: mapping.map(step.pos + 1)
		});
	});
	const ranges = [];
	for (const newRange of newRanges) {
		const blockRange = blockRangeFor(doc, newRange);
		if (blockRange) ranges.push(blockRange);
	}
	ranges.sort((a, b) => a.from - b.from);
	const merged = [];
	for (const range of ranges) {
		const last = merged[merged.length - 1];
		if (last && range.from <= last.to) last.to = Math.max(last.to, range.to);
		else merged.push({ ...range });
	}
	return {
		type: "ranges",
		ranges: merged
	};
}
function mapDecorationSet(set, mapping, doc, widgetKeys) {
	return set.map(mapping, doc, { onRemove: (removedSpec) => {
		const key = removedSpec == null ? void 0 : removedSpec.key;
		if (typeof key === "string") widgetKeys.delete(key);
	} });
}
function mapDecorations(name, previous, tr) {
	var _a, _b;
	const previousSet = (_a = previous.decorationSetsByExtension[name]) != null ? _a : DecorationSet.empty;
	const widgetKeys = new Set((_b = previous.widgetKeysByExtension[name]) != null ? _b : []);
	return {
		set: mapDecorationSet(previousSet, tr.mapping, tr.doc, widgetKeys),
		widgetKeys
	};
}
function mergeDecorationSets(doc, decorationSetsByExtension) {
	const allDecorations = Object.values(decorationSetsByExtension).flatMap((set) => set.find());
	return DecorationSet.create(doc, allDecorations);
}
function unionWidgetKeys(widgetKeysByExtension) {
	const merged = /* @__PURE__ */ new Set();
	for (const keys of Object.values(widgetKeysByExtension)) for (const key of keys) merged.add(key);
	return merged;
}
function validateDecorationSpec(name, spec) {
	var _a;
	switch ((_a = spec.update) != null ? _a : "document") {
		case "document":
			if (spec.createInRange) throw new Error(`[tiptap error]: Extension "${name}" provides createInRange() but does not use the "changedRanges" decoration update strategy.`);
			return;
		case "changedRanges":
			if (!spec.createInRange) throw new Error(`[tiptap error]: Extension "${name}" uses the "changedRanges" decoration update strategy but does not provide createInRange().`);
			return;
		case "manual":
			if (spec.createInRange) throw new Error(`[tiptap error]: Extension "${name}" uses the "manual" decoration update strategy, which is not compatible with createInRange(). createInRange() requires the "changedRanges" strategy.`);
			if (spec.shouldUpdate) throw new Error(`[tiptap error]: Extension "${name}" cannot combine the "manual" decoration update strategy with shouldUpdate().`);
			return;
		default: throw new Error(`[tiptap error]: Extension "${name}" uses an unknown decoration update strategy. Expected "document", "changedRanges", or "manual".`);
	}
}
function shouldRecomputeDecoration(spec, props, forced) {
	if (forced) return true;
	if (spec.update === "manual") return false;
	return spec.shouldUpdate ? spec.shouldUpdate(props) : props.tr.docChanged;
}
var EMPTY_KEYS = /* @__PURE__ */ new Set();
var DecorationManager = class {
	constructor(options) {
		this.warnedWidgetKeys = /* @__PURE__ */ new Set();
		this.warnedOutOfRangeExtensions = /* @__PURE__ */ new Set();
		this.handleBeforeTransaction = ({ nextState }) => {
			const state = DECORATION_MANAGER_PLUGIN_KEY.getState(nextState);
			if (state) this.warnDuplicateWidgetKeys(state);
		};
		this.editor = options.editor;
		this.entries = this.resolveEntries(options.entries);
		this.entries.forEach(({ name, spec }) => validateDecorationSpec(name, spec));
		this.plugin = this.entries.length > 0 ? this.createPlugin() : null;
		this.editor.on("beforeTransaction", this.handleBeforeTransaction);
	}
	destroy() {
		this.editor.off("beforeTransaction", this.handleBeforeTransaction);
	}
	/**
	* Returns the set of live widget keys from all decoration extensions.
	* @returns A readonly set of widget keys
	*/
	liveWidgetKeys() {
		var _a, _b;
		return (_b = (_a = DECORATION_MANAGER_PLUGIN_KEY.getState(this.editor.state)) == null ? void 0 : _a.widgetKeys) != null ? _b : EMPTY_KEYS;
	}
	/**
	* The mounted editor view, or `null` when destroyed. Decoration callbacks
	* must never receive the placeholder view `editor.view` falls back to.
	* @returns The mounted editor view, or `null`
	*/
	get mountedView() {
		return this.editor.isDestroyed ? null : this.editor.view;
	}
	/**
	* Resolves decoration entries by calling the addDecorations function for each extension entry.
	* @param entries The decoration manager entries to resolve
	* @returns An array of resolved decoration entries
	*/
	resolveEntries(entries) {
		const resolved = [];
		for (const { name, addDecorations } of entries) {
			const spec = addDecorations();
			if (spec) resolved.push({
				name,
				spec
			});
		}
		return resolved;
	}
	/**
	* Creates the ProseMirror plugin for managing decorations.
	* @returns A ProseMirror plugin with state management
	*/
	createPlugin() {
		const { editor, entries } = this;
		return new Plugin({
			key: DECORATION_MANAGER_PLUGIN_KEY,
			state: {
				init: (_config, state) => {
					const decorationSetsByExtension = {};
					const widgetKeysByExtension = {};
					for (const { name, spec } of entries) {
						const { set, widgetKeys } = this.buildFullSet(name, spec, state);
						decorationSetsByExtension[name] = set;
						widgetKeysByExtension[name] = widgetKeys;
					}
					const managerState = {
						decorationSetsByExtension,
						widgetKeysByExtension,
						mergedDecorationSet: this.buildMergedSet(state.doc, decorationSetsByExtension),
						widgetKeys: unionWidgetKeys(widgetKeysByExtension)
					};
					this.warnDuplicateWidgetKeys(managerState);
					return managerState;
				},
				apply: (tr, previous, oldState, newState) => {
					const meta = tr.getMeta(DECORATION_MANAGER_PLUGIN_KEY);
					const forceAll = (meta == null ? void 0 : meta.type) === "force" && !meta.name;
					const forceName = (meta == null ? void 0 : meta.type) === "force" ? meta.name : void 0;
					const decorationSetsByExtension = {};
					const widgetKeysByExtension = {};
					const recomputedNames = /* @__PURE__ */ new Set();
					runInDecorationApplyScope(editor, () => {
						for (const { name, spec } of entries) {
							const forced = forceAll || forceName === name;
							if (!shouldRecomputeDecoration(spec, {
								editor,
								tr,
								oldState,
								newState
							}, forced)) {
								const result = mapDecorations(name, previous, tr);
								decorationSetsByExtension[name] = result.set;
								widgetKeysByExtension[name] = result.widgetKeys;
							} else if (spec.update === "changedRanges" && tr.docChanged && !forced) {
								const result = this.applyChangedRangesRecompute(name, spec, previous, tr, newState);
								decorationSetsByExtension[name] = result.set;
								widgetKeysByExtension[name] = result.widgetKeys;
								recomputedNames.add(name);
							} else {
								const { set, widgetKeys } = this.buildFullSet(name, spec, newState);
								decorationSetsByExtension[name] = set;
								widgetKeysByExtension[name] = widgetKeys;
								recomputedNames.add(name);
							}
						}
					});
					if (recomputedNames.size === 0 && !tr.docChanged) return previous;
					return {
						decorationSetsByExtension,
						widgetKeysByExtension,
						mergedDecorationSet: this.mergeAfterApply({
							entries,
							previous,
							tr,
							decorationSetsByExtension,
							recomputedNames
						}),
						widgetKeys: unionWidgetKeys(widgetKeysByExtension)
					};
				}
			},
			props: { decorations(state) {
				var _a, _b;
				return (_b = (_a = DECORATION_MANAGER_PLUGIN_KEY.getState(state)) == null ? void 0 : _a.mergedDecorationSet) != null ? _b : DecorationSet.empty;
			} }
		});
	}
	/**
	* Applies changed ranges recomputation to a decoration set, dropping stale decorations and rebuilding only the touched blocks.
	* @param name The name of the decoration extension
	* @param spec The decoration spec
	* @param previous The previous decoration manager state
	* @param tr The transaction to apply
	* @param newState The new editor state
	* @returns The updated decoration set and widget keys
	*/
	applyChangedRangesRecompute(name, spec, previous, tr, newState) {
		const resolution = getRebuildRanges(tr, newState.doc);
		if (resolution.type === "full") return this.buildFullSet(name, spec, newState);
		return this.rebuildRanges(name, spec, previous, tr, newState, resolution.ranges);
	}
	/**
	* Rebuilds decorations for the changed block ranges: maps the previous set
	* forward, then for each range removes stale decorations, calls
	* `createInRange`, and adds the new ones while syncing widget keys.
	* @param name The extension name.
	* @param spec The decoration spec.
	* @param previous The previous decoration manager state.
	* @param tr The transaction to apply.
	* @param newState The new editor state.
	* @param ranges The block ranges to rebuild.
	* @returns The updated decoration set and widget keys.
	*/
	rebuildRanges(name, spec, previous, tr, newState, ranges) {
		var _a, _b;
		const previousSet = (_a = previous.decorationSetsByExtension[name]) != null ? _a : DecorationSet.empty;
		const widgetKeys = new Set((_b = previous.widgetKeysByExtension[name]) != null ? _b : []);
		let set = mapDecorationSet(previousSet, tr.mapping, tr.doc, widgetKeys);
		const docSize = newState.doc.content.size;
		for (const { from, to } of ranges) {
			const stale = set.find(from, to).filter((decoration) => rangeOwnsPosition({
				position: decoration.from,
				from,
				to,
				docSize
			}));
			for (const decoration of stale) {
				const key = widgetKeyOf(decoration);
				if (key) widgetKeys.delete(key);
			}
			set = set.remove(stale);
			const { decorations: pmDecorations, widgetKeys: addedKeys } = decorationsToPMDecorations(filterOutOfRangeDecorations({
				decorations: this.runCreate(name, "createInRange", () => spec.createInRange({
					editor: this.editor,
					state: newState,
					view: this.mountedView,
					from,
					to
				})),
				from,
				to,
				docSize,
				extensionName: name,
				warnedExtensions: this.warnedOutOfRangeExtensions
			}), name);
			set = set.add(newState.doc, pmDecorations);
			for (const key of addedKeys) widgetKeys.add(key);
		}
		return {
			set,
			widgetKeys
		};
	}
	/**
	* Builds a full decoration set for the entire document.
	* @param name The name of the decoration extension
	* @param spec The decoration spec
	* @param state The editor state
	* @returns The decoration set and widget keys
	*/
	buildFullSet(name, spec, state) {
		const decorations = this.runCreate(name, "create", () => spec.create({
			editor: this.editor,
			state,
			view: this.mountedView
		}));
		return buildDecorationSet(state.doc, decorations, name);
	}
	/**
	* Runs a decoration callback and swallows anything it throws. These run inside
	* `state.apply`, where an uncaught error would abort the whole transaction.
	* @param name The extension name.
	* @param method The callback name, used in the error message.
	* @param create The callback to run.
	* @returns The decorations, or an empty array if the callback threw.
	*/
	runCreate(name, method, create) {
		try {
			return create();
		} catch (error) {
			console.error(`[tiptap error]: Extension "${name}" threw in \`addDecorations().${method}()\`. Its decorations were dropped for this update.`, error);
			return [];
		}
	}
	warnDuplicateWidgetKeys(state) {
		if (!isDev$1) return;
		if (state.widgetKeys.size === 0) {
			this.warnedWidgetKeys.clear();
			return;
		}
		const duplicateKeys = findDuplicateWidgetKeys(state.mergedDecorationSet);
		const nextWarningKeys = new Set(duplicateKeys.map(({ key }) => key));
		for (const { key, extensions } of duplicateKeys) {
			if (this.warnedWidgetKeys.has(key)) continue;
			const names = Array.from(extensions).map((name) => `"${name}"`).join(", ");
			console.warn(`[tiptap warn]: Duplicate widget decoration key "${key}" in extension${extensions.size === 1 ? "" : "s"} ${names}. Widget decoration keys must be globally unique, otherwise ProseMirror misplaces the widget DOM. Use a stable, unique key (e.g. \`comment-\${id}\`).`);
		}
		this.warnedWidgetKeys = nextWarningKeys;
	}
	/**
	* Builds the merged DecorationSet during init. Skips the merge for a
	* single extension since its per-extension set is already correct.
	* @param doc The document to build the merged set for.
	* @param decorationSetsByExtension The per-extension decoration sets.
	* @returns The merged decoration set.
	*/
	buildMergedSet(doc, decorationSetsByExtension) {
		const names = Object.keys(decorationSetsByExtension);
		if (names.length === 1) return decorationSetsByExtension[names[0]];
		return mergeDecorationSets(doc, decorationSetsByExtension);
	}
	/**
	* Computes the merged DecorationSet after apply. Single extension skips the
	* merge; nothing recomputed maps the previous merged set forward; otherwise
	* the merge is rebuilt from the per-extension sets.
	*/
	mergeAfterApply({ entries, previous, tr, decorationSetsByExtension, recomputedNames }) {
		if (entries.length === 1) return decorationSetsByExtension[entries[0].name];
		if (recomputedNames.size === 0) return previous.mergedDecorationSet.map(tr.mapping, tr.doc);
		return mergeDecorationSets(tr.doc, decorationSetsByExtension);
	}
};
function createStyleTag(style2, nonce, suffix) {
	const tiptapStyleTag = document.querySelector(`style[data-tiptap-style${suffix ? `-${suffix}` : ""}]`);
	if (tiptapStyleTag !== null) return tiptapStyleTag;
	const styleNode = document.createElement("style");
	if (nonce) styleNode.setAttribute("nonce", nonce);
	styleNode.setAttribute(`data-tiptap-style${suffix ? `-${suffix}` : ""}`, "");
	styleNode.innerHTML = style2;
	document.getElementsByTagName("head")[0].appendChild(styleNode);
	return styleNode;
}
function isNumber(value) {
	return typeof value === "number";
}
function getType(value) {
	return Object.prototype.toString.call(value).slice(8, -1);
}
function isPlainObject(value) {
	if (getType(value) !== "Object") return false;
	return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype;
}
__export$1({}, {
	createAtomBlockMarkdownSpec: () => createAtomBlockMarkdownSpec,
	createBlockMarkdownSpec: () => createBlockMarkdownSpec,
	createInlineMarkdownSpec: () => createInlineMarkdownSpec,
	parseAttributes: () => parseAttributes,
	parseIndentedBlocks: () => parseIndentedBlocks,
	renderNestedMarkdownContent: () => renderNestedMarkdownContent,
	serializeAttributes: () => serializeAttributes
});
function parseAttributes(attrString) {
	if (!(attrString == null ? void 0 : attrString.trim())) return {};
	const attributes = {};
	const quotedStrings = [];
	const tempString = attrString.replace(/["']([^"']*)["']/g, (match) => {
		quotedStrings.push(match);
		return `__QUOTED_${quotedStrings.length - 1}__`;
	});
	const classMatches = tempString.match(/(?:^|\s)\.([\w-]+)/g);
	if (classMatches) attributes.class = classMatches.map((match) => match.trim().slice(1)).join(" ");
	const idMatch = tempString.match(/(?:^|\s)#([\w-]+)/);
	if (idMatch) attributes.id = idMatch[1];
	Array.from(tempString.matchAll(/([a-zA-Z][\w-]*)\s*=\s*(__QUOTED_\d+__)/g)).forEach(([, key, quotedRef]) => {
		var _a;
		const quotedIndex = parseInt(((_a = quotedRef.match(/__QUOTED_(\d+)__/)) == null ? void 0 : _a[1]) || "0", 10);
		const quotedValue = quotedStrings[quotedIndex];
		if (quotedValue) attributes[key] = quotedValue.slice(1, -1);
	});
	const cleanString = tempString.replace(/(?:^|\s)\.([\w-]+)/g, "").replace(/(?:^|\s)#([\w-]+)/g, "").replace(/([a-zA-Z][\w-]*)\s*=\s*__QUOTED_\d+__/g, "").trim();
	if (cleanString) cleanString.split(/\s+/).filter(Boolean).forEach((attr) => {
		if (attr.match(/^[a-zA-Z][\w-]*$/)) attributes[attr] = true;
	});
	return attributes;
}
function serializeAttributes(attributes) {
	if (!attributes || Object.keys(attributes).length === 0) return "";
	const parts = [];
	if (attributes.class) String(attributes.class).split(/\s+/).filter(Boolean).forEach((cls) => parts.push(`.${cls}`));
	if (attributes.id) parts.push(`#${attributes.id}`);
	Object.entries(attributes).forEach(([key, value]) => {
		if (key === "class" || key === "id") return;
		if (value === true) parts.push(key);
		else if (value !== false && value != null) parts.push(`${key}="${String(value)}"`);
	});
	return parts.join(" ");
}
function createAtomBlockMarkdownSpec(options) {
	const { nodeName, name: markdownName, parseAttributes: parseAttributes2 = parseAttributes, serializeAttributes: serializeAttributes2 = serializeAttributes, defaultAttributes = {}, requiredAttributes = [], allowedAttributes } = options;
	const blockName = markdownName || nodeName;
	const filterAttributes = (attrs) => {
		if (!allowedAttributes) return attrs;
		const filtered = {};
		allowedAttributes.forEach((key) => {
			if (key in attrs) filtered[key] = attrs[key];
		});
		return filtered;
	};
	return {
		parseMarkdown: (token, h2) => {
			const attrs = {
				...defaultAttributes,
				...token.attributes
			};
			return h2.createNode(nodeName, attrs, []);
		},
		markdownTokenizer: {
			name: nodeName,
			level: "block",
			start(src) {
				var _a;
				const regex = new RegExp(`^:::${blockName}(?:\\s|$)`, "m");
				const index = (_a = src.match(regex)) == null ? void 0 : _a.index;
				return index !== void 0 ? index : -1;
			},
			tokenize(src, _tokens, _lexer) {
				const regex = new RegExp(`^:::${blockName}(?:\\s+\\{([^}]*)\\})?\\s*:::(?:\\n|$)`);
				const match = src.match(regex);
				if (!match) return;
				const attrString = match[1] || "";
				const attributes = parseAttributes2(attrString);
				if (requiredAttributes.find((required) => !(required in attributes))) return;
				return {
					type: nodeName,
					raw: match[0],
					attributes
				};
			}
		},
		renderMarkdown: (node) => {
			const filteredAttrs = filterAttributes(node.attrs || {});
			const attrs = serializeAttributes2(filteredAttrs);
			const attrString = attrs ? ` {${attrs}}` : "";
			return `:::${blockName}${attrString} :::`;
		}
	};
}
function createBlockMarkdownSpec(options) {
	const { nodeName, name: markdownName, getContent, parseAttributes: parseAttributes2 = parseAttributes, serializeAttributes: serializeAttributes2 = serializeAttributes, defaultAttributes = {}, content = "block", allowedAttributes } = options;
	const blockName = markdownName || nodeName;
	const filterAttributes = (attrs) => {
		if (!allowedAttributes) return attrs;
		const filtered = {};
		allowedAttributes.forEach((key) => {
			if (key in attrs) filtered[key] = attrs[key];
		});
		return filtered;
	};
	return {
		parseMarkdown: (token, h2) => {
			let nodeContent;
			if (getContent) {
				const contentResult = getContent(token);
				nodeContent = typeof contentResult === "string" ? [{
					type: "text",
					text: contentResult
				}] : contentResult;
			} else if (content === "block") nodeContent = h2.parseChildren(token.tokens || []);
			else nodeContent = h2.parseInline(token.tokens || []);
			const attrs = {
				...defaultAttributes,
				...token.attributes
			};
			return h2.createNode(nodeName, attrs, nodeContent);
		},
		markdownTokenizer: {
			name: nodeName,
			level: "block",
			start(src) {
				var _a;
				const regex = new RegExp(`^:::${blockName}`, "m");
				const index = (_a = src.match(regex)) == null ? void 0 : _a.index;
				return index !== void 0 ? index : -1;
			},
			tokenize(src, _tokens, lexer) {
				var _a;
				const openingRegex = new RegExp(`^:::${blockName}(?:\\s+\\{([^}]*)\\})?\\s*\\n`);
				const openingMatch = src.match(openingRegex);
				if (!openingMatch) return;
				const [openingTag, attrString = ""] = openingMatch;
				const attributes = parseAttributes2(attrString);
				let level = 1;
				const position = openingTag.length;
				let matchedContent = "";
				const blockPattern = /^:::([\w-]*)(\s.*)?/gm;
				const remaining = src.slice(position);
				blockPattern.lastIndex = 0;
				for (;;) {
					const match = blockPattern.exec(remaining);
					if (match === null) break;
					const matchPos = match.index;
					const blockType = match[1];
					if ((_a = match[2]) == null ? void 0 : _a.endsWith(":::")) continue;
					if (blockType) level += 1;
					else {
						level -= 1;
						if (level === 0) {
							const rawContent = remaining.slice(0, matchPos);
							matchedContent = rawContent.trim();
							const fullMatch = src.slice(0, position + matchPos + match[0].length);
							let contentTokens = [];
							if (matchedContent) {
								if (content === "block") {
									contentTokens = lexer.blockTokens(rawContent);
									contentTokens.forEach((token) => {
										if (token.text && (!token.tokens || token.tokens.length === 0)) token.tokens = lexer.inlineTokens(token.text);
									});
									while (contentTokens.length > 0) {
										const lastToken = contentTokens[contentTokens.length - 1];
										if (lastToken.type === "paragraph" && (!lastToken.text || lastToken.text.trim() === "")) contentTokens.pop();
										else break;
									}
								} else contentTokens = lexer.inlineTokens(matchedContent);
							}
							return {
								type: nodeName,
								raw: fullMatch,
								attributes,
								content: matchedContent,
								tokens: contentTokens
							};
						}
					}
				}
			}
		},
		renderMarkdown: (node, h2) => {
			const filteredAttrs = filterAttributes(node.attrs || {});
			const attrs = serializeAttributes2(filteredAttrs);
			const attrString = attrs ? ` {${attrs}}` : "";
			const renderedContent = h2.renderChildren(node.content || [], "\n\n");
			return `:::${blockName}${attrString}

${renderedContent}

:::`;
		}
	};
}
function parseShortcodeAttributes(attrString) {
	if (!attrString.trim()) return {};
	const attributes = {};
	const regex = /(\w+)=(?:"([^"]*)"|'([^']*)')/g;
	let match = regex.exec(attrString);
	while (match !== null) {
		const [, key, doubleQuoted, singleQuoted] = match;
		attributes[key] = doubleQuoted || singleQuoted;
		match = regex.exec(attrString);
	}
	return attributes;
}
function serializeShortcodeAttributes(attrs) {
	return Object.entries(attrs).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}="${value}"`).join(" ");
}
function createInlineMarkdownSpec(options) {
	const { nodeName, name: shortcodeName, getContent, parseAttributes: parseAttributes2 = parseShortcodeAttributes, serializeAttributes: serializeAttributes2 = serializeShortcodeAttributes, defaultAttributes = {}, selfClosing = false, allowedAttributes } = options;
	const shortcode = shortcodeName || nodeName;
	const filterAttributes = (attrs) => {
		if (!allowedAttributes) return attrs;
		const filtered = {};
		allowedAttributes.forEach((attr) => {
			const attrName = typeof attr === "string" ? attr : attr.name;
			const skipIfDefault = typeof attr === "string" ? void 0 : attr.skipIfDefault;
			if (attrName in attrs) {
				const value = attrs[attrName];
				if (skipIfDefault !== void 0 && value === skipIfDefault) return;
				filtered[attrName] = value;
			}
		});
		return filtered;
	};
	const escapedShortcode = shortcode.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
	return {
		parseMarkdown: (token, h2) => {
			const attrs = {
				...defaultAttributes,
				...token.attributes
			};
			if (selfClosing) return h2.createNode(nodeName, attrs);
			const content = getContent ? getContent(token) : token.content || "";
			if (content) return h2.createNode(nodeName, attrs, [h2.createTextNode(content)]);
			return h2.createNode(nodeName, attrs, []);
		},
		markdownTokenizer: {
			name: nodeName,
			level: "inline",
			start(src) {
				const startPattern = selfClosing ? new RegExp(`\\[${escapedShortcode}\\s*[^\\]]*\\]`) : new RegExp(`\\[${escapedShortcode}\\s*[^\\]]*\\][\\s\\S]*?\\[\\/${escapedShortcode}\\]`);
				const match = src.match(startPattern);
				const index = match == null ? void 0 : match.index;
				return index !== void 0 ? index : -1;
			},
			tokenize(src, _tokens, _lexer) {
				const tokenPattern = selfClosing ? new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]`) : new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escapedShortcode}\\]`);
				const match = src.match(tokenPattern);
				if (!match) return;
				let content = "";
				let attrString = "";
				if (selfClosing) {
					const [, attrs] = match;
					attrString = attrs;
				} else {
					const [, attrs, contentMatch] = match;
					attrString = attrs;
					content = contentMatch || "";
				}
				const attributes = parseAttributes2(attrString.trim());
				return {
					type: nodeName,
					raw: match[0],
					content: content.trim(),
					attributes
				};
			}
		},
		renderMarkdown: (node) => {
			let content = "";
			if (getContent) content = getContent(node);
			else if (node.content && node.content.length > 0) content = node.content.filter((child) => child.type === "text").map((child) => child.text).join("");
			const filteredAttrs = filterAttributes(node.attrs || {});
			const attrs = serializeAttributes2(filteredAttrs);
			const attrString = attrs ? ` ${attrs}` : "";
			if (selfClosing) return `[${shortcode}${attrString}]`;
			return `[${shortcode}${attrString}]${content}[/${shortcode}]`;
		}
	};
}
function parseIndentedBlocks(src, config, lexer) {
	var _a, _b, _c, _d;
	const lines = src.split("\n");
	const items = [];
	let totalRaw = "";
	let i = 0;
	const baseIndentSize = config.baseIndentSize || 2;
	while (i < lines.length) {
		const currentLine = lines[i];
		const itemMatch = currentLine.match(config.itemPattern);
		if (!itemMatch) {
			if (items.length > 0) break;
			else if (currentLine.trim() === "") {
				i += 1;
				totalRaw = `${totalRaw}${currentLine}
`;
				continue;
			} else return;
		}
		const itemData = config.extractItemData(itemMatch);
		const { indentLevel, mainContent } = itemData;
		totalRaw = `${totalRaw}${currentLine}
`;
		const itemContent = [mainContent];
		i += 1;
		while (i < lines.length) {
			const nextLine = lines[i];
			if (nextLine.trim() === "") {
				const nextNonEmptyIndex = lines.slice(i + 1).findIndex((l) => l.trim() !== "");
				if (nextNonEmptyIndex === -1) break;
				if ((((_b = (_a = lines[i + 1 + nextNonEmptyIndex].match(/^(\s*)/)) == null ? void 0 : _a[1]) == null ? void 0 : _b.length) || 0) > indentLevel) {
					itemContent.push(nextLine);
					totalRaw = `${totalRaw}${nextLine}
`;
					i += 1;
					continue;
				} else break;
			}
			if ((((_d = (_c = nextLine.match(/^(\s*)/)) == null ? void 0 : _c[1]) == null ? void 0 : _d.length) || 0) > indentLevel) {
				itemContent.push(nextLine);
				totalRaw = `${totalRaw}${nextLine}
`;
				i += 1;
			} else break;
		}
		let nestedTokens;
		const nestedContent = itemContent.slice(1);
		if (nestedContent.length > 0) {
			const dedentedNested = nestedContent.map((nestedLine) => nestedLine.slice(indentLevel + baseIndentSize)).join("\n");
			if (dedentedNested.trim()) {
				if (config.customNestedParser) nestedTokens = config.customNestedParser(dedentedNested);
				else nestedTokens = lexer.blockTokens(dedentedNested);
			}
		}
		const token = config.createToken(itemData, nestedTokens);
		items.push(token);
	}
	if (items.length === 0) return;
	return {
		items,
		raw: totalRaw
	};
}
function renderNestedMarkdownContent(node, h2, prefixOrGenerator, ctx) {
	if (!node || !Array.isArray(node.content)) return "";
	const prefix = typeof prefixOrGenerator === "function" ? prefixOrGenerator(ctx) : prefixOrGenerator;
	const [content, ...children] = node.content;
	let output = `${prefix}${h2.renderChildren([content])}`;
	if (children && children.length > 0) children.forEach((child, index) => {
		var _a, _b;
		const childContent = (_b = (_a = h2.renderChild) == null ? void 0 : _a.call(h2, child, index + 1)) != null ? _b : h2.renderChildren([child]);
		if (childContent !== void 0 && childContent !== null) {
			const indentedChild = childContent.split("\n").map((line) => line ? h2.indent(line) : h2.indent("")).join("\n");
			output += child.type === "paragraph" ? `

${indentedChild}` : `
${indentedChild}`;
		}
	});
	return output;
}
function mergeDeep(target, source) {
	const output = { ...target };
	if (isPlainObject(target) && isPlainObject(source)) Object.keys(source).forEach((key) => {
		if (isPlainObject(source[key]) && isPlainObject(target[key])) output[key] = mergeDeep(target[key], source[key]);
		else output[key] = source[key];
	});
	return output;
}
function updateMarkViewAttributes(checkMark, editor, attrs = {}) {
	const { state } = editor;
	const { doc, tr } = state;
	const thisMark = checkMark;
	doc.descendants((node, pos) => {
		const from = tr.mapping.map(pos);
		const to = tr.mapping.map(pos) + node.nodeSize;
		let foundMark = null;
		node.marks.forEach((mark) => {
			if (mark !== thisMark) return false;
			foundMark = mark;
		});
		if (!foundMark) return;
		let needsUpdate = false;
		Object.keys(attrs).forEach((k) => {
			if (attrs[k] !== foundMark.attrs[k]) needsUpdate = true;
		});
		if (needsUpdate) {
			const updatedMark = checkMark.type.create({
				...checkMark.attrs,
				...attrs
			});
			tr.removeMark(from, to, checkMark.type);
			tr.addMark(from, to, updatedMark);
		}
	});
	if (tr.docChanged) editor.view.dispatch(tr);
}
var InputRule = class {
	constructor(config) {
		var _a;
		this.find = config.find;
		this.handler = config.handler;
		this.undoable = (_a = config.undoable) != null ? _a : true;
	}
};
var inputRuleMatcherHandler = (text, find) => {
	if (isRegExp(find)) return find.exec(text);
	const inputRuleMatch = find(text);
	if (!inputRuleMatch) return null;
	const result = [inputRuleMatch.text];
	result.index = inputRuleMatch.index;
	result.input = text;
	result.data = inputRuleMatch.data;
	if (inputRuleMatch.replaceWith) {
		if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) console.warn("[tiptap warn]: \"inputRuleMatch.replaceWith\" must be part of \"inputRuleMatch.text\".");
		result.push(inputRuleMatch.replaceWith);
	}
	return result;
};
function run(config) {
	var _a;
	const { editor, from, to, text, rules, plugin } = config;
	const { view } = editor;
	if (view.composing) return false;
	const $from = view.state.doc.resolve(from);
	if ($from.parent.type.spec.code || !!((_a = $from.nodeBefore || $from.nodeAfter) == null ? void 0 : _a.marks.find((mark) => mark.type.spec.code))) return false;
	let matched = false;
	const textBefore = getTextContentFromNodes($from) + text;
	rules.forEach((rule) => {
		if (matched) return;
		const match = inputRuleMatcherHandler(textBefore, rule.find);
		if (!match) return;
		const matchedDocLength = match[0].length - text.length;
		if (matchedDocLength > 0) {
			const matchStartOffset = $from.parentOffset - matchedDocLength;
			if (matchStartOffset < 0 || $from.parent.textBetween(matchStartOffset, $from.parentOffset) !== match[0].slice(0, matchedDocLength)) return;
		}
		const tr = view.state.tr;
		const state = createChainableState({
			state: view.state,
			transaction: tr
		});
		const range = {
			from: from - (match[0].length - text.length),
			to
		};
		const { commands, chain, can } = new CommandManager({
			editor,
			state
		});
		if (rule.handler({
			state,
			range,
			match,
			commands,
			chain,
			can
		}) === null || !tr.steps.length) return;
		if (rule.undoable) tr.setMeta(plugin, {
			transform: tr,
			from,
			to,
			text
		});
		view.dispatch(tr);
		matched = true;
	});
	return matched;
}
function inputRulesPlugin(props) {
	const { editor, rules } = props;
	const plugin = new Plugin({
		state: {
			init() {
				return null;
			},
			apply(tr, prev, state) {
				const stored = tr.getMeta(plugin);
				if (stored) return stored;
				const simulatedInputMeta = tr.getMeta("applyInputRules");
				if (!!simulatedInputMeta) setTimeout(() => {
					let { text } = simulatedInputMeta;
					if (typeof text === "string") text = text;
					else text = getHTMLFromFragment(Fragment$8.from(text), state.schema);
					const { from } = simulatedInputMeta;
					const to = from + text.length;
					run({
						editor,
						from,
						to,
						text,
						rules,
						plugin
					});
				});
				return tr.selectionSet || tr.docChanged ? null : prev;
			}
		},
		props: {
			handleTextInput(view, from, to, text) {
				return run({
					editor,
					from,
					to,
					text,
					rules,
					plugin
				});
			},
			handleDOMEvents: { compositionend: (view) => {
				setTimeout(() => {
					const { $cursor } = view.state.selection;
					if ($cursor) run({
						editor,
						from: $cursor.pos,
						to: $cursor.pos,
						text: "",
						rules,
						plugin
					});
				});
				return false;
			} },
			handleKeyDown(view, event) {
				if (event.key !== "Enter") return false;
				const { $cursor } = view.state.selection;
				if ($cursor) return run({
					editor,
					from: $cursor.pos,
					to: $cursor.pos,
					text: "\n",
					rules,
					plugin
				});
				return false;
			}
		},
		isInputRules: true
	});
	return plugin;
}
var Extendable = class {
	constructor(config = {}) {
		this.type = "extendable";
		this.parent = null;
		this.child = null;
		this.name = "";
		this.config = { name: this.name };
		this.config = {
			...this.config,
			...config
		};
		this.name = this.config.name;
	}
	get options() {
		return { ...callOrReturn(getExtensionField(this, "addOptions", { name: this.name })) };
	}
	get storage() {
		return { ...callOrReturn(getExtensionField(this, "addStorage", {
			name: this.name,
			options: this.options
		})) };
	}
	configure(options = {}) {
		const extension = this.extend({
			...this.config,
			addOptions: () => {
				return mergeDeep(this.options, options);
			}
		});
		extension.name = this.name;
		extension.parent = this.parent;
		this.child = null;
		return extension;
	}
	extend(extendedConfig = {}) {
		const extension = new this.constructor({
			...this.config,
			...extendedConfig
		});
		extension.parent = this;
		this.child = extension;
		extension.name = "name" in extendedConfig ? extendedConfig.name : extension.parent.name;
		return extension;
	}
};
var Mark = class _Mark extends Extendable {
	constructor() {
		super(...arguments);
		this.type = "mark";
	}
	/**
	* Create a new Mark instance
	* @param config - Mark configuration object or a function that returns a configuration object
	*/
	static create(config = {}) {
		const resolvedConfig = typeof config === "function" ? config() : config;
		return new _Mark(resolvedConfig);
	}
	static handleExit({ editor, mark }) {
		const { tr } = editor.state;
		const currentPos = editor.state.selection.$from;
		if (currentPos.pos === currentPos.end()) {
			const currentMarks = currentPos.marks();
			if (!!!currentMarks.find((m) => (m == null ? void 0 : m.type.name) === mark.name)) return false;
			const removeMark = currentMarks.find((m) => (m == null ? void 0 : m.type.name) === mark.name);
			if (removeMark) tr.removeStoredMark(removeMark);
			tr.insertText(" ", currentPos.pos);
			editor.view.dispatch(tr);
			return true;
		}
		return false;
	}
	configure(options) {
		return super.configure(options);
	}
	extend(extendedConfig) {
		const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig;
		return super.extend(resolvedConfig);
	}
};
var PasteRule = class {
	constructor(config) {
		this.find = config.find;
		this.handler = config.handler;
	}
};
var pasteRuleMatcherHandler = (text, find, event) => {
	if (isRegExp(find)) return [...text.matchAll(find)];
	const matches = find(text, event);
	if (!matches) return [];
	return matches.map((pasteRuleMatch) => {
		const result = [pasteRuleMatch.text];
		result.index = pasteRuleMatch.index;
		result.input = text;
		result.data = pasteRuleMatch.data;
		if (pasteRuleMatch.replaceWith) {
			if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) console.warn("[tiptap warn]: \"pasteRuleMatch.replaceWith\" must be part of \"pasteRuleMatch.text\".");
			result.push(pasteRuleMatch.replaceWith);
		}
		return result;
	});
};
function run2(config) {
	const { editor, state, from, to, rule, pasteEvent, dropEvent } = config;
	const { commands, chain, can } = new CommandManager({
		editor,
		state
	});
	const handlers = [];
	state.doc.nodesBetween(from, to, (node, pos) => {
		var _a, _b, _c, _d, _e;
		if (((_b = (_a = node.type) == null ? void 0 : _a.spec) == null ? void 0 : _b.code) || !(node.isText || node.isTextblock || node.isInline)) return;
		const contentSize = (_e = (_d = (_c = node.content) == null ? void 0 : _c.size) != null ? _d : node.nodeSize) != null ? _e : 0;
		const resolvedFrom = Math.max(from, pos);
		const resolvedTo = Math.min(to, pos + contentSize);
		if (resolvedFrom >= resolvedTo) return;
		pasteRuleMatcherHandler(node.isText ? node.text || "" : node.textBetween(resolvedFrom - pos, resolvedTo - pos, void 0, "￼"), rule.find, pasteEvent).forEach((match) => {
			if (match.index === void 0) return;
			const start = resolvedFrom + match.index + 1;
			const end = start + match[0].length;
			const range = {
				from: state.tr.mapping.map(start),
				to: state.tr.mapping.map(end)
			};
			const handler = rule.handler({
				state,
				range,
				match,
				commands,
				chain,
				can,
				pasteEvent,
				dropEvent
			});
			handlers.push(handler);
		});
	});
	return handlers.every((handler) => handler !== null);
}
var tiptapDragFromOtherEditor = null;
var createClipboardPasteEvent = (text) => {
	var _a;
	const event = new ClipboardEvent("paste", { clipboardData: new DataTransfer() });
	(_a = event.clipboardData) == null || _a.setData("text/html", text);
	return event;
};
function pasteRulesPlugin(props) {
	const { editor, rules } = props;
	let dragSourceElement = null;
	let isPastedFromProseMirror = false;
	let isDroppedFromProseMirror = false;
	let pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
	let dropEvent;
	try {
		dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null;
	} catch {
		dropEvent = null;
	}
	const processEvent = ({ state, from, to, rule, pasteEvt }) => {
		const tr = state.tr;
		const chainableState = createChainableState({
			state,
			transaction: tr
		});
		if (!run2({
			editor,
			state: chainableState,
			from: Math.max(from - 1, 0),
			to: to.b - 1,
			rule,
			pasteEvent: pasteEvt,
			dropEvent
		}) || !tr.steps.length) return;
		try {
			dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null;
		} catch {
			dropEvent = null;
		}
		pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null;
		return tr;
	};
	return rules.map((rule) => {
		return new Plugin({
			view(view) {
				const handleDragstart = (event) => {
					var _a;
					dragSourceElement = ((_a = view.dom.parentElement) == null ? void 0 : _a.contains(event.target)) ? view.dom.parentElement : null;
					if (dragSourceElement) tiptapDragFromOtherEditor = editor;
				};
				const handleDragend = () => {
					if (tiptapDragFromOtherEditor) tiptapDragFromOtherEditor = null;
				};
				window.addEventListener("dragstart", handleDragstart);
				window.addEventListener("dragend", handleDragend);
				return { destroy() {
					window.removeEventListener("dragstart", handleDragstart);
					window.removeEventListener("dragend", handleDragend);
				} };
			},
			props: { handleDOMEvents: {
				drop: (view, event) => {
					isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement;
					dropEvent = event;
					if (!isDroppedFromProseMirror) {
						const dragFromOtherEditor = tiptapDragFromOtherEditor;
						if (dragFromOtherEditor == null ? void 0 : dragFromOtherEditor.isEditable) setTimeout(() => {
							const selection = dragFromOtherEditor.state.selection;
							if (selection) dragFromOtherEditor.commands.deleteRange({
								from: selection.from,
								to: selection.to
							});
						}, 10);
					}
					return false;
				},
				paste: (_view, event) => {
					var _a;
					const html = (_a = event.clipboardData) == null ? void 0 : _a.getData("text/html");
					pasteEvent = event;
					isPastedFromProseMirror = !!(html == null ? void 0 : html.includes("data-pm-slice"));
					return false;
				}
			} },
			appendTransaction: (transactions, oldState, state) => {
				const transaction = transactions[0];
				const isPaste = transaction.getMeta("uiEvent") === "paste" && !isPastedFromProseMirror;
				const isDrop = transaction.getMeta("uiEvent") === "drop" && !isDroppedFromProseMirror;
				const simulatedPasteMeta = transaction.getMeta("applyPasteRules");
				const isSimulatedPaste = !!simulatedPasteMeta;
				if (!isPaste && !isDrop && !isSimulatedPaste) return;
				if (isSimulatedPaste) {
					let { text } = simulatedPasteMeta;
					if (typeof text === "string") text = text;
					else text = getHTMLFromFragment(Fragment$8.from(text), state.schema);
					const { from: from2 } = simulatedPasteMeta;
					const to2 = from2 + text.length;
					const pasteEvt = createClipboardPasteEvent(text);
					return processEvent({
						rule,
						state,
						from: from2,
						to: { b: to2 },
						pasteEvt
					});
				}
				const from = oldState.doc.content.findDiffStart(state.doc.content);
				const to = oldState.doc.content.findDiffEnd(state.doc.content);
				if (!isNumber(from) || !to || from === to.b) return;
				return processEvent({
					rule,
					state,
					from,
					to,
					pasteEvt: pasteEvent
				});
			}
		});
	});
}
var ExtensionManager = class {
	constructor(extensions, editor) {
		this.splittableMarks = [];
		this.nonClearableMarks = [];
		this.decorationManager = null;
		this.editor = editor;
		this.baseExtensions = extensions;
		this.extensions = resolveExtensions(extensions);
		this.schema = getSchemaByResolvedExtensions(this.extensions, editor);
		this.setupExtensions();
	}
	/**
	* Get all commands from the extensions.
	* @returns An object with all commands where the key is the command name and the value is the command function
	*/
	get commands() {
		return this.extensions.reduce((commands, extension) => {
			const addCommands = getExtensionField(extension, "addCommands", {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor: this.editor,
				type: getSchemaTypeByName(extension.name, this.schema)
			});
			if (!addCommands) return commands;
			return {
				...commands,
				...addCommands()
			};
		}, {});
	}
	/**
	* Get all registered Prosemirror plugins from the extensions.
	* @returns An array of Prosemirror plugins
	*/
	get plugins() {
		const { editor } = this;
		const allPlugins = sortExtensions([...this.extensions].reverse()).flatMap((extension) => {
			const context = {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor,
				type: getSchemaTypeByName(extension.name, this.schema)
			};
			const plugins = [];
			const addKeyboardShortcuts = getExtensionField(extension, "addKeyboardShortcuts", context);
			let defaultBindings = {};
			if (extension.type === "mark" && getExtensionField(extension, "exitable", context)) defaultBindings.ArrowRight = () => Mark.handleExit({
				editor,
				mark: extension
			});
			if (addKeyboardShortcuts) {
				const bindings = Object.fromEntries(Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => {
					return [shortcut, () => method({ editor })];
				}));
				defaultBindings = {
					...defaultBindings,
					...bindings
				};
			}
			const keyMapPlugin = keymap(defaultBindings);
			plugins.push(keyMapPlugin);
			const addInputRules = getExtensionField(extension, "addInputRules", context);
			if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {
				const rules = addInputRules();
				if (rules && rules.length) {
					const inputResult = inputRulesPlugin({
						editor,
						rules
					});
					const inputPlugins = Array.isArray(inputResult) ? inputResult : [inputResult];
					plugins.push(...inputPlugins);
				}
			}
			const addPasteRules = getExtensionField(extension, "addPasteRules", context);
			if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {
				const rules = addPasteRules();
				if (rules && rules.length) {
					const pasteRules = pasteRulesPlugin({
						editor,
						rules
					});
					plugins.push(...pasteRules);
				}
			}
			const addProseMirrorPlugins = getExtensionField(extension, "addProseMirrorPlugins", context);
			if (addProseMirrorPlugins) {
				const proseMirrorPlugins = addProseMirrorPlugins();
				plugins.push(...proseMirrorPlugins);
			}
			return plugins;
		});
		const decorationPlugin = this.createDecorationPlugin();
		if (decorationPlugin) allPlugins.push(decorationPlugin);
		return allPlugins;
	}
	/**
	* Aggregates decorations from extensions into a single plugin, or returns null
	* if none exist. Destroys the previous manager to avoid orphaned listeners.
	* @returns A ProseMirror plugin or `null`
	* @example
	* const plugin = editor.extensionManager.createDecorationPlugin()
	*/
	createDecorationPlugin() {
		var _a;
		const { editor } = this;
		(_a = this.decorationManager) == null || _a.destroy();
		const entries = [];
		this.extensions.forEach((extension) => {
			const addDecorations = getExtensionField(extension, "addDecorations", {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor,
				type: getSchemaTypeByName(extension.name, this.schema)
			});
			if (!addDecorations) return;
			entries.push({
				name: extension.name,
				addDecorations
			});
		});
		this.decorationManager = new DecorationManager({
			editor,
			entries
		});
		return this.decorationManager.plugin;
	}
	/**
	* Get all attributes from the extensions.
	* @returns An array of attributes
	*/
	get attributes() {
		return getAttributesFromExtensions(this.extensions);
	}
	/**
	* Get all node views from the extensions.
	* @returns An object with all node views where the key is the node name and the value is the node view function
	*/
	get nodeViews() {
		const { editor } = this;
		const { nodeExtensions } = splitExtensions(this.extensions);
		return Object.fromEntries(nodeExtensions.filter((extension) => !!getExtensionField(extension, "addNodeView")).map((extension) => {
			const extensionAttributes = this.attributes.filter((attribute) => attribute.type === extension.name);
			const addNodeView = getExtensionField(extension, "addNodeView", {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor,
				type: getNodeType(extension.name, this.schema)
			});
			if (!addNodeView) return [];
			const nodeViewResult = addNodeView();
			if (!nodeViewResult) return [];
			const nodeview = (node, view, getPos, decorations, innerDecorations) => {
				const HTMLAttributes = getRenderedAttributes(node, extensionAttributes);
				return nodeViewResult({
					node,
					view,
					getPos,
					decorations,
					innerDecorations,
					editor,
					extension,
					HTMLAttributes
				});
			};
			return [extension.name, nodeview];
		}));
	}
	/**
	* Get the composed dispatchTransaction function from all extensions.
	* @param baseDispatch The base dispatch function (e.g. from the editor or user props)
	* @returns A composed dispatch function
	*/
	dispatchTransaction(baseDispatch) {
		const { editor } = this;
		return sortExtensions([...this.extensions].reverse()).reduceRight((next, extension) => {
			const context = {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor,
				type: getSchemaTypeByName(extension.name, this.schema)
			};
			const dispatchTransaction = getExtensionField(extension, "dispatchTransaction", context);
			if (!dispatchTransaction) return next;
			return (transaction) => {
				dispatchTransaction.call(context, {
					transaction,
					next
				});
			};
		}, baseDispatch);
	}
	/**
	* Get the composed transformPastedHTML function from all extensions.
	* @param baseTransform The base transform function (e.g. from the editor props)
	* @returns A composed transform function that chains all extension transforms
	*/
	transformPastedHTML(baseTransform) {
		const { editor } = this;
		return sortExtensions([...this.extensions]).reduce((transform, extension) => {
			const context = {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor,
				type: getSchemaTypeByName(extension.name, this.schema)
			};
			const extensionTransform = getExtensionField(extension, "transformPastedHTML", context);
			if (!extensionTransform) return transform;
			return (html, view) => {
				const transformedHtml = transform(html, view);
				return extensionTransform.call(context, transformedHtml);
			};
		}, baseTransform || ((html) => html));
	}
	get markViews() {
		const { editor } = this;
		const { markExtensions } = splitExtensions(this.extensions);
		return Object.fromEntries(markExtensions.filter((extension) => !!getExtensionField(extension, "addMarkView")).map((extension) => {
			const extensionAttributes = this.attributes.filter((attribute) => attribute.type === extension.name);
			const addMarkView = getExtensionField(extension, "addMarkView", {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor,
				type: getMarkType(extension.name, this.schema)
			});
			if (!addMarkView) return [];
			const markView = (mark, view, inline) => {
				const HTMLAttributes = getRenderedAttributes(mark, extensionAttributes);
				return addMarkView()({
					mark,
					view,
					inline,
					editor,
					extension,
					HTMLAttributes,
					updateAttributes: (attrs) => {
						updateMarkViewAttributes(mark, editor, attrs);
					}
				});
			};
			return [extension.name, markView];
		}));
	}
	/**
	* Destroy the extension manager and clean up all extension references
	* to prevent memory leaks through parent/child extension chains.
	*
	* Walks each extension's full parent chain and nulls every forward
	* `parent.child → current` link where the parent still points to the
	* current node. This breaks the retention path from module-scope
	* singleton roots through deep extend() chains.
	*
	* Only ancestor `.child` links matching the current chain are cleared.
	* The `.parent` pointer on ancestors is never touched — extensions
	* may be shared across live editors, so their own backward references
	* and non-matching forward links must remain intact.
	*/
	destroy() {
		var _a;
		(_a = this.decorationManager) == null || _a.destroy();
		this.extensions.forEach((extension) => {
			let current = extension;
			while (current.parent) {
				const parent = current.parent;
				if (parent.child === current) parent.child = null;
				current = parent;
			}
		});
		this.extensions = [];
		this.baseExtensions = [];
		this.decorationManager = null;
		this.schema = null;
		this.editor = null;
	}
	/**
	* Go through all extensions, create extension storages & setup marks
	* & bind editor event listener.
	*/
	setupExtensions() {
		const extensions = this.extensions;
		this.editor.extensionStorage = Object.fromEntries(extensions.map((extension) => [extension.name, extension.storage]));
		extensions.forEach((extension) => {
			var _a, _b;
			const context = {
				name: extension.name,
				options: extension.options,
				storage: this.editor.extensionStorage[extension.name],
				editor: this.editor,
				type: getSchemaTypeByName(extension.name, this.schema)
			};
			if (extension.type === "mark") {
				if ((_a = callOrReturn(getExtensionField(extension, "keepOnSplit", context))) != null ? _a : true) this.splittableMarks.push(extension.name);
				if (!((_b = callOrReturn(getExtensionField(extension, "clearable", context))) != null ? _b : true)) this.nonClearableMarks.push(extension.name);
			}
			const onBeforeCreate = getExtensionField(extension, "onBeforeCreate", context);
			const onCreate = getExtensionField(extension, "onCreate", context);
			const onUpdate = getExtensionField(extension, "onUpdate", context);
			const onSelectionUpdate = getExtensionField(extension, "onSelectionUpdate", context);
			const onTransaction = getExtensionField(extension, "onTransaction", context);
			const onFocus = getExtensionField(extension, "onFocus", context);
			const onBlur = getExtensionField(extension, "onBlur", context);
			const onDestroy = getExtensionField(extension, "onDestroy", context);
			if (onBeforeCreate) this.editor.on("beforeCreate", onBeforeCreate);
			if (onCreate) this.editor.on("create", onCreate);
			if (onUpdate) this.editor.on("update", onUpdate);
			if (onSelectionUpdate) this.editor.on("selectionUpdate", onSelectionUpdate);
			if (onTransaction) this.editor.on("transaction", onTransaction);
			if (onFocus) this.editor.on("focus", onFocus);
			if (onBlur) this.editor.on("blur", onBlur);
			if (onDestroy) this.editor.on("destroy", onDestroy);
		});
	}
};
ExtensionManager.resolve = resolveExtensions;
ExtensionManager.sort = sortExtensions;
ExtensionManager.flatten = flattenExtensions;
__export$1({}, {
	ClipboardTextSerializer: () => ClipboardTextSerializer,
	Commands: () => Commands,
	Delete: () => Delete,
	Drop: () => Drop,
	Editable: () => Editable,
	FocusEvents: () => FocusEvents,
	Keymap: () => Keymap,
	Paste: () => Paste,
	Tabindex: () => Tabindex,
	TextDirection: () => TextDirection$1,
	focusEventsPluginKey: () => focusEventsPluginKey
});
var Extension = class _Extension extends Extendable {
	constructor() {
		super(...arguments);
		this.type = "extension";
	}
	/**
	* Create a new Extension instance
	* @param config - Extension configuration object or a function that returns a configuration object
	*/
	static create(config = {}) {
		const resolvedConfig = typeof config === "function" ? config() : config;
		return new _Extension(resolvedConfig);
	}
	configure(options) {
		return super.configure(options);
	}
	extend(extendedConfig) {
		const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig;
		return super.extend(resolvedConfig);
	}
};
var ClipboardTextSerializer = Extension.create({
	name: "clipboardTextSerializer",
	addOptions() {
		return { blockSeparator: void 0 };
	},
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("clipboardTextSerializer"),
			props: { clipboardTextSerializer: () => {
				const { editor } = this;
				const { state, schema } = editor;
				const { doc, selection } = state;
				const textSerializers = getTextSerializersFromSchema(schema);
				const { blockSeparator } = this.options;
				const options = {
					...blockSeparator !== void 0 ? { blockSeparator } : {},
					textSerializers
				};
				return [...selection.ranges].sort((a, b) => a.$from.pos - b.$from.pos).map(({ $from, $to }) => getTextBetween(doc, {
					from: $from.pos,
					to: $to.pos
				}, options)).join(blockSeparator != null ? blockSeparator : "\n\n");
			} }
		})];
	}
});
var Commands = Extension.create({
	name: "commands",
	addCommands() {
		return { ...commands_exports };
	}
});
var Delete = Extension.create({
	name: "delete",
	onUpdate({ transaction, appendedTransactions }) {
		var _a, _b, _c;
		const callback = () => {
			var _a2, _b2, _c2, _d;
			if ((_d = (_c2 = (_b2 = (_a2 = this.editor.options.coreExtensionOptions) == null ? void 0 : _a2.delete) == null ? void 0 : _b2.filterTransaction) == null ? void 0 : _c2.call(_b2, transaction)) != null ? _d : transaction.getMeta("y-sync$")) return;
			const nextTransaction = combineTransactionSteps(transaction.before, [transaction, ...appendedTransactions]);
			getChangedRanges(nextTransaction).forEach((change) => {
				if (nextTransaction.mapping.mapResult(change.oldRange.from).deletedAfter && nextTransaction.mapping.mapResult(change.oldRange.to).deletedBefore) nextTransaction.before.nodesBetween(change.oldRange.from, change.oldRange.to, (node, from) => {
					const to = from + node.nodeSize - 2;
					const isFullyWithinRange = change.oldRange.from <= from && to <= change.oldRange.to;
					this.editor.emit("delete", {
						type: "node",
						node,
						from,
						to,
						newFrom: nextTransaction.mapping.map(from),
						newTo: nextTransaction.mapping.map(to),
						deletedRange: change.oldRange,
						newRange: change.newRange,
						partial: !isFullyWithinRange,
						editor: this.editor,
						transaction,
						combinedTransform: nextTransaction
					});
				});
			});
			const mapping = nextTransaction.mapping;
			nextTransaction.steps.forEach((step, index) => {
				var _a3, _b3;
				if (step instanceof RemoveMarkStep) {
					const newStart = mapping.slice(index).map(step.from, -1);
					const newEnd = mapping.slice(index).map(step.to);
					const oldStart = mapping.invert().map(newStart, -1);
					const oldEnd = mapping.invert().map(newEnd);
					const foundBeforeMark = newStart > 0 ? (_a3 = nextTransaction.doc.nodeAt(newStart - 1)) == null ? void 0 : _a3.marks.some((mark) => mark.eq(step.mark)) : false;
					const foundAfterMark = (_b3 = nextTransaction.doc.nodeAt(newEnd)) == null ? void 0 : _b3.marks.some((mark) => mark.eq(step.mark));
					this.editor.emit("delete", {
						type: "mark",
						mark: step.mark,
						from: step.from,
						to: step.to,
						deletedRange: {
							from: oldStart,
							to: oldEnd
						},
						newRange: {
							from: newStart,
							to: newEnd
						},
						partial: Boolean(foundAfterMark || foundBeforeMark),
						editor: this.editor,
						transaction,
						combinedTransform: nextTransaction
					});
				}
			});
		};
		if ((_c = (_b = (_a = this.editor.options.coreExtensionOptions) == null ? void 0 : _a.delete) == null ? void 0 : _b.async) != null ? _c : true) setTimeout(callback, 0);
		else callback();
	}
});
var Drop = Extension.create({
	name: "drop",
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("tiptapDrop"),
			props: { handleDrop: (_, e, slice, moved) => {
				this.editor.emit("drop", {
					editor: this.editor,
					event: e,
					slice,
					moved
				});
			} }
		})];
	}
});
var Editable = Extension.create({
	name: "editable",
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("editable"),
			props: { editable: () => this.editor.options.editable }
		})];
	}
});
var focusEventsPluginKey = new PluginKey("focusEvents");
var FocusEvents = Extension.create({
	name: "focusEvents",
	addProseMirrorPlugins() {
		const { editor } = this;
		return [new Plugin({
			key: focusEventsPluginKey,
			props: { handleDOMEvents: {
				focus: (view, event) => {
					editor.isFocused = true;
					const transaction = editor.state.tr.setMeta("focus", { event }).setMeta("addToHistory", false);
					view.dispatch(transaction);
					return false;
				},
				blur: (view, event) => {
					editor.isFocused = false;
					const transaction = editor.state.tr.setMeta("blur", { event }).setMeta("addToHistory", false);
					view.dispatch(transaction);
					return false;
				}
			} }
		})];
	}
});
var Keymap = Extension.create({
	name: "keymap",
	addKeyboardShortcuts() {
		const handleBackspace = () => this.editor.commands.first(({ commands }) => [
			() => commands.undoInputRule(),
			() => commands.command(({ tr }) => {
				const { selection, doc } = tr;
				const { empty, $anchor } = selection;
				const { pos, parent } = $anchor;
				const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr.doc.resolve(pos - 1) : $anchor;
				const parentIsIsolating = $parentPos.parent.type.spec.isolating;
				const parentPos = $anchor.pos - $anchor.parentOffset;
				const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos : Selection$1.atStart(doc).from === pos;
				if (!empty || !parent.type.isTextblock || parent.textContent.length || !isAtStart || isAtStart && $anchor.parent.type.name === "paragraph") return false;
				return commands.clearNodes();
			}),
			() => commands.deleteSelection(),
			() => commands.joinBackward(),
			() => commands.selectNodeBackward()
		]);
		const handleDelete = () => this.editor.commands.first(({ commands }) => [
			() => commands.deleteSelection(),
			() => commands.deleteCurrentNode(),
			() => commands.joinForward(),
			() => commands.selectNodeForward()
		]);
		const handleEnter = () => this.editor.commands.first(({ commands }) => [
			() => commands.newlineInCode(),
			() => commands.createParagraphNear(),
			() => commands.liftEmptyBlock(),
			() => commands.splitBlock()
		]);
		const baseKeymap = {
			Enter: handleEnter,
			"Mod-Enter": () => this.editor.commands.exitCode(),
			Backspace: handleBackspace,
			"Mod-Backspace": handleBackspace,
			"Shift-Backspace": handleBackspace,
			Delete: handleDelete,
			"Mod-Delete": handleDelete,
			"Mod-a": () => this.editor.commands.selectAll()
		};
		const pcKeymap = { ...baseKeymap };
		const macKeymap = {
			...baseKeymap,
			"Ctrl-h": handleBackspace,
			"Alt-Backspace": handleBackspace,
			"Ctrl-d": handleDelete,
			"Ctrl-Alt-Backspace": handleDelete,
			"Alt-Delete": handleDelete,
			"Alt-d": handleDelete,
			"Ctrl-a": () => this.editor.commands.selectTextblockStart(),
			"Ctrl-e": () => this.editor.commands.selectTextblockEnd()
		};
		if (isiOS() || isMacOS()) return macKeymap;
		return pcKeymap;
	},
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("clearDocument"),
			appendTransaction: (transactions, oldState, newState) => {
				if (transactions.some((tr2) => tr2.getMeta("composition"))) return;
				const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
				const ignoreTr = transactions.some((transaction) => transaction.getMeta("preventClearDocument"));
				if (!docChanges || ignoreTr) return;
				const { empty, from, to } = oldState.selection;
				const allFrom = Selection$1.atStart(oldState.doc).from;
				const allEnd = Selection$1.atEnd(oldState.doc).to;
				if (empty || !(from === allFrom && to === allEnd)) return;
				if (!isNodeEmpty(newState.doc)) return;
				const tr = newState.tr;
				const state = createChainableState({
					state: newState,
					transaction: tr
				});
				const { commands } = new CommandManager({
					editor: this.editor,
					state
				});
				commands.clearNodes();
				if (!tr.steps.length) return;
				return tr;
			}
		})];
	}
});
var Paste = Extension.create({
	name: "paste",
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("tiptapPaste"),
			props: { handlePaste: (_view, e, slice) => {
				this.editor.emit("paste", {
					editor: this.editor,
					event: e,
					slice
				});
			} }
		})];
	}
});
var Tabindex = Extension.create({
	name: "tabindex",
	addOptions() {
		return { value: void 0 };
	},
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("tabindex"),
			props: { attributes: () => {
				var _a;
				if (!this.editor.isEditable && this.options.value === void 0) return {};
				return { tabindex: (_a = this.options.value) != null ? _a : "0" };
			} }
		})];
	}
});
var TextDirection$1 = Extension.create({
	name: "textDirection",
	addOptions() {
		return { direction: void 0 };
	},
	addGlobalAttributes() {
		if (!this.options.direction) return [];
		const { nodeExtensions } = splitExtensions(this.extensions);
		return [{
			types: nodeExtensions.filter((extension) => extension.name !== "text").map((extension) => extension.name),
			attributes: { dir: {
				default: this.options.direction,
				parseHTML: (element) => {
					const dir = element.getAttribute("dir");
					if (dir && (dir === "ltr" || dir === "rtl" || dir === "auto")) return dir;
					return this.options.direction;
				},
				renderHTML: (attributes) => {
					if (!attributes.dir) return {};
					return { dir: attributes.dir };
				}
			} }
		}];
	},
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("textDirection"),
			props: { attributes: () => {
				const direction = this.options.direction;
				if (!direction) return {};
				return { dir: direction };
			} }
		})];
	}
});
var hasChecked = false;
function warnOnDuplicatedProseMirrorModel(schema) {
	if (hasChecked) return;
	hasChecked = true;
	let content;
	try {
		content = ReplaceStep.fromJSON(schema, {
			from: 0,
			to: 0
		}).slice.content;
	} catch {
		return;
	}
	if (content instanceof Fragment$8) return;
	console.warn("[tiptap warn]: prosemirror-model is loaded more than once. Wrapping and splitting nodes will fail. Deduplicate it in your lock file, or alias it to a single copy in your bundler.");
}
var NodePos = class _NodePos {
	constructor(pos, editor, isBlock = false, node = null) {
		this.currentNode = null;
		this.actualDepth = null;
		this.isBlock = isBlock;
		this.resolvedPos = pos;
		this.editor = editor;
		this.currentNode = node;
	}
	get name() {
		return this.node.type.name;
	}
	get node() {
		return this.currentNode || this.resolvedPos.node();
	}
	get element() {
		return this.editor.view.domAtPos(this.pos).node;
	}
	get depth() {
		var _a;
		return (_a = this.actualDepth) != null ? _a : this.resolvedPos.depth;
	}
	get pos() {
		return this.resolvedPos.pos;
	}
	get content() {
		return this.node.content;
	}
	set content(content) {
		let from = this.from;
		let to = this.to;
		if (this.isBlock) {
			if (this.content.size === 0) {
				console.error(`You can\u2019t set content on a block node. Tried to set content on ${this.name} at ${this.pos}`);
				return;
			}
			from = this.from + 1;
			to = this.to - 1;
		}
		this.editor.commands.insertContentAt({
			from,
			to
		}, content);
	}
	get attributes() {
		return this.node.attrs;
	}
	get textContent() {
		return this.node.textContent;
	}
	get size() {
		return this.node.nodeSize;
	}
	get from() {
		if (this.isBlock) return this.pos;
		return this.resolvedPos.start(this.resolvedPos.depth);
	}
	get range() {
		return {
			from: this.from,
			to: this.to
		};
	}
	get to() {
		if (this.isBlock) return this.pos + this.size;
		return this.resolvedPos.end(this.resolvedPos.depth) + (this.node.isText ? 0 : 1);
	}
	get parent() {
		if (this.depth === 0) return null;
		const parentPos = this.resolvedPos.start(this.resolvedPos.depth - 1);
		const $pos = this.resolvedPos.doc.resolve(parentPos);
		return new _NodePos($pos, this.editor);
	}
	get before() {
		let $pos = this.resolvedPos.doc.resolve(this.from - (this.isBlock ? 1 : 2));
		if ($pos.depth !== this.depth) $pos = this.resolvedPos.doc.resolve(this.from - 3);
		return new _NodePos($pos, this.editor);
	}
	get after() {
		let $pos = this.resolvedPos.doc.resolve(this.to + (this.isBlock ? 2 : 1));
		if ($pos.depth !== this.depth) $pos = this.resolvedPos.doc.resolve(this.to + 3);
		return new _NodePos($pos, this.editor);
	}
	get children() {
		const children = [];
		this.node.content.forEach((node, offset) => {
			const isBlock = node.isBlock && !node.isTextblock;
			const isNonTextAtom = node.isAtom && !node.isText;
			const isInline = node.isInline;
			const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1);
			if (targetPos < 0 || targetPos > this.resolvedPos.doc.nodeSize - 2) return;
			const $pos = this.resolvedPos.doc.resolve(targetPos);
			if (!isBlock && !isInline && $pos.depth <= this.depth) return;
			const childNodePos = new _NodePos($pos, this.editor, isBlock, isBlock || isInline ? node : null);
			if (isBlock) childNodePos.actualDepth = this.depth + 1;
			children.push(childNodePos);
		});
		return children;
	}
	get firstChild() {
		return this.children[0] || null;
	}
	get lastChild() {
		const children = this.children;
		return children[children.length - 1] || null;
	}
	closest(selector, attributes = {}) {
		let node = null;
		let currentNode = this.parent;
		while (currentNode && !node) {
			if (currentNode.node.type.name === selector) {
				if (Object.keys(attributes).length > 0) {
					const nodeAttributes = currentNode.node.attrs;
					const attrKeys = Object.keys(attributes);
					for (let index = 0; index < attrKeys.length; index += 1) {
						const key = attrKeys[index];
						if (nodeAttributes[key] !== attributes[key]) break;
					}
				} else node = currentNode;
			}
			currentNode = currentNode.parent;
		}
		return node;
	}
	querySelector(selector, attributes = {}) {
		return this.querySelectorAll(selector, attributes, true)[0] || null;
	}
	querySelectorAll(selector, attributes = {}, firstItemOnly = false) {
		let nodes = [];
		if (!this.children || this.children.length === 0) return nodes;
		const attrKeys = Object.keys(attributes);
		this.children.forEach((childPos) => {
			if (firstItemOnly && nodes.length > 0) return;
			if (childPos.node.type.name === selector) {
				if (attrKeys.every((key) => attributes[key] === childPos.node.attrs[key])) nodes.push(childPos);
			}
			if (firstItemOnly && nodes.length > 0) return;
			nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly));
		});
		return nodes;
	}
	setAttribute(attributes) {
		const { tr } = this.editor.state;
		tr.setNodeMarkup(this.from, void 0, {
			...this.node.attrs,
			...attributes
		});
		this.editor.view.dispatch(tr);
	}
};
var style = `.ProseMirror {
  position: relative;
}

.ProseMirror {
  word-wrap: break-word;
  white-space: pre-wrap;
  white-space: break-spaces;
  -webkit-font-variant-ligatures: none;
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */
}

.ProseMirror [contenteditable="false"] {
  white-space: normal;
}

.ProseMirror [contenteditable="false"] [contenteditable="true"] {
  white-space: pre-wrap;
}

.ProseMirror pre {
  white-space: pre-wrap;
}

img.ProseMirror-separator {
  display: inline !important;
  border: none !important;
  margin: 0 !important;
  width: 0 !important;
  height: 0 !important;
}

.ProseMirror-gapcursor {
  display: none;
  pointer-events: none;
  position: absolute;
  margin: 0;
}

.ProseMirror-gapcursor:after {
  content: "";
  display: block;
  position: absolute;
  top: -2px;
  width: 20px;
  border-top: 1px solid black;
  animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
}

@keyframes ProseMirror-cursor-blink {
  to {
    visibility: hidden;
  }
}

.ProseMirror-hideselection *::selection {
  background: transparent;
}

.ProseMirror-hideselection *::-moz-selection {
  background: transparent;
}

.ProseMirror-hideselection * {
  caret-color: transparent;
}

.ProseMirror-focused .ProseMirror-gapcursor {
  display: block;
}`;
var Editor = class extends EventEmitter {
	constructor(options = {}) {
		super();
		this.css = null;
		this.className = "tiptap";
		this.editorView = null;
		this.isFocused = false;
		this.destroyed = false;
		/**
		* The editor is considered initialized after the `create` event has been emitted.
		*/
		this.isInitialized = false;
		this.extensionStorage = {};
		/**
		* A unique ID for this editor instance.
		*/
		this.instanceId = Math.random().toString(36).slice(2, 9);
		this.hasWarnedStaleDecorationRead = false;
		this.options = {
			element: typeof document !== "undefined" ? document.createElement("div") : null,
			content: "",
			injectCSS: true,
			injectNonce: void 0,
			extensions: [],
			autofocus: false,
			editable: true,
			textDirection: void 0,
			editorProps: {},
			parseOptions: {},
			coreExtensionOptions: {},
			enableInputRules: true,
			enablePasteRules: true,
			enableCoreExtensions: true,
			enableContentCheck: false,
			emitContentError: false,
			onBeforeCreate: () => null,
			onCreate: () => null,
			onMount: () => null,
			onUnmount: () => null,
			onUpdate: () => null,
			onSelectionUpdate: () => null,
			onTransaction: () => null,
			onFocus: () => null,
			onBlur: () => null,
			onDestroy: () => null,
			onContentError: ({ error }) => {
				throw error;
			},
			onPaste: () => null,
			onDrop: () => null,
			onDelete: () => null,
			enableExtensionDispatchTransaction: true
		};
		this.isCapturingTransaction = false;
		this.capturedTransaction = null;
		/**
		* Returns a set of utilities for working with positions and ranges.
		*/
		this.utils = {
			getUpdatedPosition,
			createMappablePosition
		};
		this.setOptions(options);
		this.createExtensionManager();
		this.createCommandManager();
		this.createSchema();
		this.on("beforeCreate", this.options.onBeforeCreate);
		this.emit("beforeCreate", { editor: this });
		this.on("mount", this.options.onMount);
		this.on("unmount", this.options.onUnmount);
		this.on("contentError", this.options.onContentError);
		this.on("create", this.options.onCreate);
		this.on("update", this.options.onUpdate);
		this.on("selectionUpdate", this.options.onSelectionUpdate);
		this.on("transaction", this.options.onTransaction);
		this.on("focus", this.options.onFocus);
		this.on("blur", this.options.onBlur);
		this.on("destroy", this.options.onDestroy);
		this.on("drop", ({ event, slice, moved }) => this.options.onDrop(event, slice, moved));
		this.on("paste", ({ event, slice }) => this.options.onPaste(event, slice));
		this.on("delete", this.options.onDelete);
		const initialDoc = this.createDoc();
		if (!this.editorState) {
			const selection = resolveFocusPosition(initialDoc, this.options.autofocus);
			this.editorState = EditorState.create({
				doc: initialDoc,
				schema: this.schema,
				selection: selection || void 0
			});
		}
		warnOnDuplicatedProseMirrorModel(this.schema);
		if (this.options.element) this.mount(this.options.element);
	}
	/**
	* Attach the editor to the DOM, creating a new editor view.
	*/
	mount(el) {
		if (typeof document === "undefined") throw new Error(`[tiptap error]: The editor cannot be mounted because there is no 'document' defined in this environment.`);
		this.createView(el);
		this.emit("mount", { editor: this });
		if (this.css && !document.head.contains(this.css)) document.head.appendChild(this.css);
		window.setTimeout(() => {
			if (this.isDestroyed) return;
			if (this.options.autofocus !== false && this.options.autofocus !== null) this.commands.focus(this.options.autofocus);
			this.emit("create", { editor: this });
			this.isInitialized = true;
		}, 0);
	}
	/**
	* Remove the editor from the DOM, but still allow remounting at a different point in time
	*/
	unmount() {
		if (this.editorView) {
			this.editorState = this.editorView.state;
			const dom = this.editorView.dom;
			if (dom == null ? void 0 : dom.editor) delete dom.editor;
			this.editorView.destroy();
		}
		this.editorView = null;
		this.isInitialized = false;
		if (this.css && !document.querySelectorAll(`.${this.className}`).length) try {
			if (typeof this.css.remove === "function") this.css.remove();
			else if (this.css.parentNode) this.css.parentNode.removeChild(this.css);
		} catch (error) {
			console.warn("Failed to remove CSS element:", error);
		}
		this.css = null;
		this.emit("unmount", { editor: this });
	}
	/**
	* Returns the editor storage.
	*/
	get storage() {
		return this.extensionStorage;
	}
	/**
	* An object of all registered commands.
	*/
	get commands() {
		return this.commandManager.commands;
	}
	/**
	* Create a command chain to call multiple commands at once.
	*/
	chain() {
		if (!this.commandManager) return CommandManager.createFakeChain();
		return this.commandManager.chain();
	}
	/**
	* Check if a command or a command chain can be executed. Without executing it.
	*/
	can() {
		if (!this.commandManager) return CommandManager.createFallbackCan();
		return this.commandManager.can();
	}
	/**
	* Inject CSS styles.
	*/
	injectCSS() {
		if (this.options.injectCSS && typeof document !== "undefined") this.css = createStyleTag(style, this.options.injectNonce);
	}
	/**
	* Update editor options.
	*
	* @param options A list of options
	*/
	setOptions(options = {}) {
		this.options = {
			...this.options,
			...options
		};
		if (!this.editorView || !this.state || this.isDestroyed) return;
		if (this.options.editorProps) this.view.setProps(this.options.editorProps);
		this.view.updateState(this.state);
	}
	/**
	* Update editable state of the editor.
	*/
	setEditable(editable, emitUpdate = true) {
		this.setOptions({ editable });
		if (emitUpdate) this.emit("update", {
			editor: this,
			transaction: this.state.tr,
			appendedTransactions: []
		});
	}
	/**
	* Returns whether the editor is editable.
	*/
	get isEditable() {
		return this.options.editable && this.view && this.view.editable;
	}
	/**
	* Returns the editor view.
	*/
	get view() {
		if (this.editorView) return this.editorView;
		return new Proxy({
			state: this.editorState,
			updateState: (state) => {
				this.editorState = state;
			},
			dispatch: (tr) => {
				this.dispatchTransaction(tr);
			},
			composing: false,
			dragging: null,
			editable: true,
			isDestroyed: false
		}, { get: (obj, key) => {
			if (this.editorView) return this.editorView[key];
			if (key === "state") return this.editorState;
			if (key in obj) return Reflect.get(obj, key);
			throw new Error(`[tiptap error]: The editor view is not available. Cannot access view['${key}']. The editor may not be mounted yet.`);
		} });
	}
	/**
	* Returns the editor state.
	*/
	get state() {
		if (isDev$1 && !this.hasWarnedStaleDecorationRead && isInDecorationApplyScope(this)) {
			this.hasWarnedStaleDecorationRead = true;
			console.warn("[tiptap warn]: `editor.state` was read while decoration `create()` was running. It returns the pre-transaction document. Use the `state` argument passed to `create()` instead. Helpers like `editor.isActive()` read `editor.state` too, so pass `state` to their standalone versions instead of calling them on the editor.");
		}
		if (this.editorView) this.editorState = this.view.state;
		return this.editorState;
	}
	/**
	* Register a ProseMirror plugin.
	*
	* @param plugin A ProseMirror plugin
	* @param handlePlugins Control how to merge the plugin into the existing plugins.
	* @returns The new editor state
	*/
	registerPlugin(plugin, handlePlugins) {
		const plugins = isFunction$3(handlePlugins) ? handlePlugins(plugin, [...this.state.plugins]) : [...this.state.plugins, plugin];
		const state = this.state.reconfigure({ plugins });
		this.view.updateState(state);
		return state;
	}
	/**
	* Unregister a ProseMirror plugin.
	*
	* @param nameOrPluginKeyToRemove The plugins name
	* @returns The new editor state or undefined if the editor is destroyed
	*/
	unregisterPlugin(nameOrPluginKeyToRemove) {
		if (this.isDestroyed) return;
		const prevPlugins = this.state.plugins;
		let plugins = prevPlugins;
		[].concat(nameOrPluginKeyToRemove).forEach((nameOrPluginKey) => {
			const name = typeof nameOrPluginKey === "string" ? `${nameOrPluginKey}$` : nameOrPluginKey.key;
			plugins = plugins.filter((plugin) => !plugin.key.startsWith(name));
		});
		if (prevPlugins.length === plugins.length) return;
		const state = this.state.reconfigure({ plugins });
		this.view.updateState(state);
		return state;
	}
	/**
	* Creates an extension manager.
	*/
	createExtensionManager() {
		var _a, _b, _c, _d;
		const allExtensions = [...this.options.enableCoreExtensions ? [
			Editable,
			ClipboardTextSerializer.configure({ blockSeparator: (_b = (_a = this.options.coreExtensionOptions) == null ? void 0 : _a.clipboardTextSerializer) == null ? void 0 : _b.blockSeparator }),
			Commands,
			FocusEvents,
			Keymap,
			Tabindex.configure({ value: (_d = (_c = this.options.coreExtensionOptions) == null ? void 0 : _c.tabindex) == null ? void 0 : _d.value }),
			Drop,
			Paste,
			Delete,
			TextDirection$1.configure({ direction: this.options.textDirection })
		].filter((ext) => {
			if (typeof this.options.enableCoreExtensions === "object") return this.options.enableCoreExtensions[ext.name] !== false;
			return true;
		}) : [], ...this.options.extensions].filter((extension) => {
			return [
				"extension",
				"node",
				"mark"
			].includes(extension == null ? void 0 : extension.type);
		});
		this.extensionManager = new ExtensionManager(allExtensions, this);
	}
	/**
	* Creates an command manager.
	*/
	createCommandManager() {
		this.commandManager = new CommandManager({ editor: this });
	}
	/**
	* Creates a ProseMirror schema.
	*/
	createSchema() {
		this.schema = this.extensionManager.schema;
	}
	/**
	* Creates the initial document.
	*/
	createDoc() {
		let doc;
		try {
			doc = createDocument(this.options.content, this.schema, this.options.parseOptions, { errorOnInvalidContent: this.options.enableContentCheck });
		} catch (e) {
			if (!(e instanceof Error) || !["[tiptap error]: Invalid JSON content", "[tiptap error]: Invalid HTML content"].includes(e.message)) throw e;
			const fallbackDoc = createDocument(this.options.content, this.schema, this.options.parseOptions, { errorOnInvalidContent: false });
			this.editorState = EditorState.create({
				doc: fallbackDoc,
				schema: this.schema,
				selection: resolveFocusPosition(fallbackDoc, this.options.autofocus) || void 0
			});
			this.emit("contentError", {
				editor: this,
				error: e,
				disableCollaboration: () => {
					if ("collaboration" in this.storage && typeof this.storage.collaboration === "object" && this.storage.collaboration) this.storage.collaboration.isDisabled = true;
					this.options.extensions = this.options.extensions.filter((extension) => extension.name !== "collaboration");
					this.createExtensionManager();
				}
			});
			return this.editorState.doc;
		}
		return doc;
	}
	/**
	* Creates a ProseMirror view.
	*/
	createView(element) {
		const { editorProps, enableExtensionDispatchTransaction } = this.options;
		const baseDispatch = editorProps.dispatchTransaction || this.dispatchTransaction.bind(this);
		const dispatch = enableExtensionDispatchTransaction ? this.extensionManager.dispatchTransaction(baseDispatch) : baseDispatch;
		const baseTransformPastedHTML = editorProps.transformPastedHTML;
		const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML);
		this.editorView = new EditorView(element, {
			...editorProps,
			attributes: {
				role: "textbox",
				...editorProps == null ? void 0 : editorProps.attributes
			},
			dispatchTransaction: dispatch,
			transformPastedHTML,
			state: this.editorState,
			markViews: this.extensionManager.markViews,
			nodeViews: this.extensionManager.nodeViews
		});
		const newState = this.state.reconfigure({ plugins: this.extensionManager.plugins });
		this.view.updateState(newState);
		this.prependClass();
		this.injectCSS();
		const dom = this.view.dom;
		dom.editor = this;
	}
	/**
	* Creates all node and mark views.
	*/
	createNodeViews() {
		if (this.view.isDestroyed) return;
		this.view.setProps({
			markViews: this.extensionManager.markViews,
			nodeViews: this.extensionManager.nodeViews
		});
	}
	/**
	* Prepend class name to element.
	*/
	prependClass() {
		this.view.dom.className = `${this.className} ${this.view.dom.className}`;
	}
	captureTransaction(fn) {
		this.isCapturingTransaction = true;
		fn();
		this.isCapturingTransaction = false;
		const tr = this.capturedTransaction;
		this.capturedTransaction = null;
		return tr;
	}
	/**
	* The callback over which to send transactions (state updates) produced by the view.
	*
	* @param transaction An editor state transaction
	*/
	dispatchTransaction(transaction) {
		if (this.view.isDestroyed) return;
		if (this.isCapturingTransaction) {
			if (!this.capturedTransaction) {
				this.capturedTransaction = transaction;
				return;
			}
			transaction.steps.forEach((step) => {
				var _a;
				return (_a = this.capturedTransaction) == null ? void 0 : _a.step(step);
			});
			return;
		}
		const { state, transactions } = this.state.applyTransaction(transaction);
		const selectionHasChanged = !this.state.selection.eq(state.selection);
		const rootTrWasApplied = transactions.includes(transaction);
		const prevState = this.state;
		this.emit("beforeTransaction", {
			editor: this,
			transaction,
			nextState: state
		});
		if (!rootTrWasApplied) return;
		this.view.updateState(state);
		this.emit("transaction", {
			editor: this,
			transaction,
			appendedTransactions: transactions.slice(1)
		});
		if (selectionHasChanged) this.emit("selectionUpdate", {
			editor: this,
			transaction
		});
		const mostRecentFocusTr = transactions.findLast((tr) => tr.getMeta("focus") || tr.getMeta("blur"));
		const focus2 = mostRecentFocusTr == null ? void 0 : mostRecentFocusTr.getMeta("focus");
		const blur2 = mostRecentFocusTr == null ? void 0 : mostRecentFocusTr.getMeta("blur");
		if (focus2) this.emit("focus", {
			editor: this,
			event: focus2.event,
			transaction: mostRecentFocusTr
		});
		if (blur2) this.emit("blur", {
			editor: this,
			event: blur2.event,
			transaction: mostRecentFocusTr
		});
		if (transaction.getMeta("preventUpdate") || !transactions.some((tr) => tr.docChanged) || prevState.doc.eq(state.doc)) return;
		this.emit("update", {
			editor: this,
			transaction,
			appendedTransactions: transactions.slice(1)
		});
	}
	/**
	* Get attributes of the currently selected node or mark.
	*/
	getAttributes(nameOrType) {
		return getAttributes(this.state, nameOrType);
	}
	isActive(nameOrAttributes, attributesOrUndefined) {
		const name = typeof nameOrAttributes === "string" ? nameOrAttributes : null;
		const attributes = typeof nameOrAttributes === "string" ? attributesOrUndefined : nameOrAttributes;
		return isActive(this.state, name, attributes);
	}
	/**
	* Get the document as JSON.
	*/
	getJSON() {
		return this.state.doc.toJSON();
	}
	/**
	* Get the document as HTML.
	*/
	getHTML() {
		return getHTMLFromFragment(this.state.doc.content, this.schema);
	}
	/**
	* Get the document as text.
	*/
	getText(options) {
		const { blockSeparator = "\n\n", textSerializers = {} } = options || {};
		return getText(this.state.doc, {
			blockSeparator,
			textSerializers: {
				...getTextSerializersFromSchema(this.schema),
				...textSerializers
			}
		});
	}
	/**
	* Check if there is no content.
	*/
	get isEmpty() {
		return isNodeEmpty(this.state.doc);
	}
	/**
	* Destroy the editor.
	*/
	destroy() {
		if (this.destroyed) return;
		this.destroyed = true;
		this.emit("destroy");
		this.unmount();
		this.removeAllListeners();
		this.extensionManager.destroy();
		this.extensionManager = null;
		this.schema = null;
		this.commandManager = null;
		this.extensionStorage = {};
	}
	/**
	* Check if the editor is already destroyed.
	*/
	get isDestroyed() {
		var _a, _b;
		return (_b = (_a = this.editorView) == null ? void 0 : _a.isDestroyed) != null ? _b : true;
	}
	$node(selector, attributes) {
		var _a;
		return ((_a = this.$doc) == null ? void 0 : _a.querySelector(selector, attributes)) || null;
	}
	$nodes(selector, attributes) {
		var _a;
		return ((_a = this.$doc) == null ? void 0 : _a.querySelectorAll(selector, attributes)) || null;
	}
	$pos(pos) {
		const $pos = this.state.doc.resolve(pos);
		const node = pos > 0 && $pos.nodeAfter && !$pos.nodeAfter.isText && $pos.nodeAfter.isAtom ? $pos.nodeAfter : null;
		return new NodePos($pos, this, false, node);
	}
	get $doc() {
		return this.$pos(0);
	}
};
function markInputRule(config) {
	return new InputRule({
		find: config.find,
		handler: ({ state, range, match }) => {
			const attributes = callOrReturn(config.getAttributes, void 0, match);
			if (attributes === false || attributes === null) return null;
			const { tr } = state;
			const captureGroup = match[match.length - 1];
			const fullMatch = match[0];
			if (captureGroup) {
				const startSpaces = fullMatch.search(/\S/);
				const textStart = range.from + fullMatch.indexOf(captureGroup);
				const textEnd = textStart + captureGroup.length;
				if (getMarksBetween(range.from, range.to, state.doc).filter((item) => {
					return item.mark.type.excluded.find((type) => type === config.type && type !== item.mark.type);
				}).filter((item) => item.to > textStart).length) return null;
				if (textEnd < range.to) tr.delete(textEnd, range.to);
				if (textStart > range.from) tr.delete(range.from + startSpaces, textStart);
				const markEnd = range.from + startSpaces + captureGroup.length;
				tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {}));
				tr.removeStoredMark(config.type);
			}
		},
		undoable: config.undoable
	});
}
function nodeInputRule(config) {
	return new InputRule({
		find: config.find,
		handler: ({ state, range, match }) => {
			const attributes = callOrReturn(config.getAttributes, void 0, match) || {};
			const { tr } = state;
			const start = range.from;
			let end = range.to;
			const newNode = config.type.create(attributes);
			if (match[1]) {
				let matchStart = start + match[0].lastIndexOf(match[1]);
				if (matchStart > end) matchStart = end;
				else end = matchStart + match[1].length;
				const lastChar = match[0][match[0].length - 1];
				tr.insertText(lastChar, start + match[0].length - 1);
				tr.replaceWith(matchStart, end, newNode);
			} else if (match[0]) {
				const insertionStart = config.type.isInline ? start : start - 1;
				tr.insert(insertionStart, config.type.create(attributes)).delete(tr.mapping.map(start), tr.mapping.map(end));
			}
			tr.scrollIntoView();
		},
		undoable: config.undoable
	});
}
function textblockTypeInputRule(config) {
	return new InputRule({
		find: config.find,
		handler: ({ state, range, match }) => {
			const $start = state.doc.resolve(range.from);
			const attributes = callOrReturn(config.getAttributes, void 0, match) || {};
			if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), config.type)) return null;
			state.tr.delete(range.from, range.to).setBlockType(range.from, range.from, config.type, attributes);
		},
		undoable: config.undoable
	});
}
function wrappingInputRule(config) {
	return new InputRule({
		find: config.find,
		handler: ({ state, range, match, chain }) => {
			const attributes = callOrReturn(config.getAttributes, void 0, match) || {};
			const tr = state.tr.delete(range.from, range.to);
			const blockRange = tr.doc.resolve(range.from).blockRange();
			const wrapping = blockRange && findWrapping(blockRange, config.type, attributes);
			if (!wrapping) return null;
			tr.wrap(blockRange, wrapping);
			if (config.keepMarks && config.editor) {
				const { selection, storedMarks } = state;
				const { splittableMarks } = config.editor.extensionManager;
				const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks();
				if (marks) {
					const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name));
					tr.ensureMarks(filteredMarks);
				}
			}
			if (config.keepAttributes) {
				const nodeType = config.type.name === "bulletList" || config.type.name === "orderedList" ? "listItem" : "taskList";
				chain().updateAttributes(nodeType, attributes).run();
			}
			const before = tr.doc.resolve(range.from - 1).nodeBefore;
			if (before && before.type === config.type && canJoin(tr.doc, range.from - 1) && (!config.joinPredicate || config.joinPredicate(match, before))) tr.join(range.from - 1);
		},
		undoable: config.undoable
	});
}
var isTouchEvent = (e) => {
	return "touches" in e;
};
var ResizableNodeView = class {
	/**
	* Creates a new ResizableNodeView instance.
	*
	* The constructor sets up the resize handles, applies initial sizing from
	* node attributes, and configures all resize behavior options.
	*
	* @param options - Configuration options for the resizable node view
	*/
	constructor(options) {
		/** Active resize handle directions */
		this.directions = [
			"bottom-left",
			"bottom-right",
			"top-left",
			"top-right"
		];
		/** Minimum allowed dimensions */
		this.minSize = {
			height: 8,
			width: 8
		};
		/** Whether to always preserve aspect ratio */
		this.preserveAspectRatio = false;
		/** CSS class names for elements */
		this.classNames = {
			container: "",
			wrapper: "",
			handle: "",
			resizing: ""
		};
		/** Initial width of the element (for aspect ratio calculation) */
		this.initialWidth = 0;
		/** Initial height of the element (for aspect ratio calculation) */
		this.initialHeight = 0;
		/** Calculated aspect ratio (width / height) */
		this.aspectRatio = 1;
		/** Whether a resize operation is currently active */
		this.isResizing = false;
		/** The handle currently being dragged */
		this.activeHandle = null;
		/** Starting mouse X position when resize began */
		this.startX = 0;
		/** Starting mouse Y position when resize began */
		this.startY = 0;
		/** Element width when resize began */
		this.startWidth = 0;
		/** Element height when resize began */
		this.startHeight = 0;
		/** Whether Shift key is currently pressed (for temporary aspect ratio lock) */
		this.isShiftKeyPressed = false;
		/** Last known editable state of the editor */
		this.lastEditableState = void 0;
		/** Map of handle elements by direction */
		this.handleMap = /* @__PURE__ */ new Map();
		/**
		* Handles mouse movement during an active resize.
		*
		* Calculates the delta from the starting position, computes new dimensions
		* based on the active handle direction, applies constraints and aspect ratio,
		* then updates the element's style and calls the onResize callback.
		*
		* @param event - The mouse move event
		*/
		this.handleMouseMove = (event) => {
			if (!this.isResizing || !this.activeHandle) return;
			const deltaX = event.clientX - this.startX;
			const deltaY = event.clientY - this.startY;
			this.handleResize(deltaX, deltaY);
		};
		this.handleTouchMove = (event) => {
			if (!this.isResizing || !this.activeHandle) return;
			const touch = event.touches[0];
			if (!touch) return;
			const deltaX = touch.clientX - this.startX;
			const deltaY = touch.clientY - this.startY;
			this.handleResize(deltaX, deltaY);
		};
		/**
		* Completes the resize operation when the mouse button is released.
		*
		* Captures final dimensions, calls the onCommit callback to persist changes,
		* removes the resizing state and class, and cleans up document-level listeners.
		*/
		this.handleMouseUp = () => {
			if (!this.isResizing) return;
			const finalWidth = this.element.offsetWidth;
			const finalHeight = this.element.offsetHeight;
			this.onCommit(finalWidth, finalHeight);
			this.isResizing = false;
			this.activeHandle = null;
			this.container.dataset.resizeState = "false";
			if (this.classNames.resizing) this.container.classList.remove(this.classNames.resizing);
			document.removeEventListener("mousemove", this.handleMouseMove);
			document.removeEventListener("mouseup", this.handleMouseUp);
			document.removeEventListener("keydown", this.handleKeyDown);
			document.removeEventListener("keyup", this.handleKeyUp);
		};
		/**
		* Tracks Shift key state to enable temporary aspect ratio locking.
		*
		* When Shift is pressed during resize, aspect ratio is preserved even if
		* preserveAspectRatio is false.
		*
		* @param event - The keyboard event
		*/
		this.handleKeyDown = (event) => {
			if (event.key === "Shift") this.isShiftKeyPressed = true;
		};
		/**
		* Tracks Shift key release to disable temporary aspect ratio locking.
		*
		* @param event - The keyboard event
		*/
		this.handleKeyUp = (event) => {
			if (event.key === "Shift") this.isShiftKeyPressed = false;
		};
		var _a, _b, _c, _d, _e, _f;
		this.node = options.node;
		this.editor = options.editor;
		this.element = options.element;
		this.element.draggable = false;
		this.contentElement = options.contentElement;
		this.getPos = options.getPos;
		this.onResize = options.onResize;
		this.onCommit = options.onCommit;
		this.onUpdate = options.onUpdate;
		if ((_a = options.options) == null ? void 0 : _a.min) this.minSize = {
			...this.minSize,
			...options.options.min
		};
		if ((_b = options.options) == null ? void 0 : _b.max) this.maxSize = options.options.max;
		if ((_c = options == null ? void 0 : options.options) == null ? void 0 : _c.directions) this.directions = options.options.directions;
		if ((_d = options.options) == null ? void 0 : _d.preserveAspectRatio) this.preserveAspectRatio = options.options.preserveAspectRatio;
		if ((_e = options.options) == null ? void 0 : _e.className) this.classNames = {
			container: options.options.className.container || "",
			wrapper: options.options.className.wrapper || "",
			handle: options.options.className.handle || "",
			resizing: options.options.className.resizing || ""
		};
		if ((_f = options.options) == null ? void 0 : _f.createCustomHandle) this.createCustomHandle = options.options.createCustomHandle;
		this.wrapper = this.createWrapper();
		this.container = this.createContainer();
		this.applyInitialSize();
		this.attachHandles();
		this.editor.on("update", this.handleEditorUpdate.bind(this));
	}
	/**
	* Returns the top-level DOM node that should be placed in the editor.
	*
	* This is required by the ProseMirror NodeView interface. The container
	* includes the wrapper, handles, and the actual content element.
	*
	* @returns The container element to be inserted into the editor
	*/
	get dom() {
		return this.container;
	}
	get contentDOM() {
		var _a;
		return (_a = this.contentElement) != null ? _a : null;
	}
	handleEditorUpdate() {
		const isEditable = this.editor.isEditable;
		if (isEditable === this.lastEditableState) return;
		this.lastEditableState = isEditable;
		if (!isEditable) this.removeHandles();
		else if (isEditable && this.handleMap.size === 0) this.attachHandles();
	}
	/**
	* Called when the node's content or attributes change.
	*
	* Updates the internal node reference. If a custom `onUpdate` callback
	* was provided, it will be called to handle additional update logic.
	*
	* @param node - The new/updated node
	* @param decorations - Node decorations
	* @param innerDecorations - Inner decorations
	* @returns `false` if the node type has changed (requires full rebuild), otherwise the result of `onUpdate` or `true`
	*/
	update(node, decorations, innerDecorations) {
		if (node.type !== this.node.type) return false;
		this.node = node;
		if (this.onUpdate) return this.onUpdate(node, decorations, innerDecorations);
		return true;
	}
	/**
	* Cleanup method called when the node view is being removed.
	*
	* Removes all event listeners to prevent memory leaks. This is required
	* by the ProseMirror NodeView interface. If a resize is active when
	* destroy is called, it will be properly cancelled.
	*/
	destroy() {
		if (this.isResizing) {
			this.container.dataset.resizeState = "false";
			if (this.classNames.resizing) this.container.classList.remove(this.classNames.resizing);
			document.removeEventListener("mousemove", this.handleMouseMove);
			document.removeEventListener("mouseup", this.handleMouseUp);
			document.removeEventListener("keydown", this.handleKeyDown);
			document.removeEventListener("keyup", this.handleKeyUp);
			this.isResizing = false;
			this.activeHandle = null;
		}
		this.editor.off("update", this.handleEditorUpdate.bind(this));
		this.container.remove();
	}
	/**
	* Creates the outer container element.
	*
	* The container is the top-level element returned by the NodeView and
	* wraps the entire resizable node. It's set up with flexbox to handle
	* alignment and includes data attributes for styling and identification.
	*
	* @returns The container element
	*/
	createContainer() {
		const element = document.createElement("div");
		element.dataset.resizeContainer = "";
		element.dataset.node = this.node.type.name;
		element.style.display = this.node.type.isInline ? "inline-flex" : "flex";
		if (this.classNames.container) element.className = this.classNames.container;
		element.appendChild(this.wrapper);
		return element;
	}
	/**
	* Creates the wrapper element that contains the content and handles.
	*
	* The wrapper uses relative positioning so that resize handles can be
	* positioned absolutely within it. This is the direct parent of the
	* content element being made resizable.
	*
	* @returns The wrapper element
	*/
	createWrapper() {
		const element = document.createElement("div");
		element.style.position = "relative";
		element.style.display = "block";
		element.dataset.resizeWrapper = "";
		if (this.classNames.wrapper) element.className = this.classNames.wrapper;
		element.appendChild(this.element);
		return element;
	}
	/**
	* Creates a resize handle element for a specific direction.
	*
	* Each handle is absolutely positioned and includes a data attribute
	* identifying its direction for styling purposes.
	*
	* @param direction - The resize direction for this handle
	* @returns The handle element
	*/
	createHandle(direction) {
		const handle = document.createElement("div");
		handle.dataset.resizeHandle = direction;
		handle.style.position = "absolute";
		if (this.classNames.handle) handle.className = this.classNames.handle;
		return handle;
	}
	/**
	* Positions a handle element according to its direction.
	*
	* Corner handles (e.g., 'top-left') are positioned at the intersection
	* of two edges. Edge handles (e.g., 'top') span the full width or height.
	*
	* @param handle - The handle element to position
	* @param direction - The direction determining the position
	*/
	positionHandle(handle, direction) {
		const isTop = direction.includes("top");
		const isBottom = direction.includes("bottom");
		const isLeft = direction.includes("left");
		const isRight = direction.includes("right");
		if (isTop) handle.style.top = "0";
		if (isBottom) handle.style.bottom = "0";
		if (isLeft) handle.style.left = "0";
		if (isRight) handle.style.right = "0";
		if (direction === "top" || direction === "bottom") {
			handle.style.left = "0";
			handle.style.right = "0";
		}
		if (direction === "left" || direction === "right") {
			handle.style.top = "0";
			handle.style.bottom = "0";
		}
	}
	/**
	* Creates and attaches all resize handles to the wrapper.
	*
	* Iterates through the configured directions, creates a handle for each,
	* positions it, attaches the mousedown listener, and appends it to the DOM.
	*/
	attachHandles() {
		this.directions.forEach((direction) => {
			let handle;
			if (this.createCustomHandle) handle = this.createCustomHandle(direction);
			else handle = this.createHandle(direction);
			if (!(handle instanceof HTMLElement)) {
				console.warn(`[ResizableNodeView] createCustomHandle("${direction}") did not return an HTMLElement. Falling back to default handle.`);
				handle = this.createHandle(direction);
			}
			if (!this.createCustomHandle) this.positionHandle(handle, direction);
			handle.addEventListener("mousedown", (event) => this.handleResizeStart(event, direction));
			handle.addEventListener("touchstart", (event) => this.handleResizeStart(event, direction));
			this.handleMap.set(direction, handle);
			this.wrapper.appendChild(handle);
		});
	}
	/**
	* Removes all resize handles from the wrapper.
	*
	* Cleans up the handle map and removes each handle element from the DOM.
	*/
	removeHandles() {
		this.handleMap.forEach((el) => el.remove());
		this.handleMap.clear();
	}
	/**
	* Applies initial sizing from node attributes to the element.
	*
	* If width/height attributes exist on the node, they're applied to the element.
	* Otherwise, the element's natural/current dimensions are measured. The aspect
	* ratio is calculated for later use in aspect-ratio-preserving resizes.
	*/
	applyInitialSize() {
		const width = this.node.attrs.width;
		const height = this.node.attrs.height;
		if (width) {
			this.element.style.width = `${width}px`;
			this.initialWidth = width;
		} else this.initialWidth = this.element.offsetWidth;
		if (height) {
			this.element.style.height = `${height}px`;
			this.initialHeight = height;
		} else this.initialHeight = this.element.offsetHeight;
		if (this.initialWidth > 0 && this.initialHeight > 0) this.aspectRatio = this.initialWidth / this.initialHeight;
	}
	/**
	* Initiates a resize operation when a handle is clicked.
	*
	* Captures the starting mouse position and element dimensions, sets up
	* the resize state, adds the resizing class and state attribute, and
	* attaches document-level listeners for mouse movement and keyboard input.
	*
	* @param event - The mouse down event
	* @param direction - The direction of the handle being dragged
	*/
	handleResizeStart(event, direction) {
		event.preventDefault();
		event.stopPropagation();
		this.isResizing = true;
		this.activeHandle = direction;
		if (isTouchEvent(event)) {
			this.startX = event.touches[0].clientX;
			this.startY = event.touches[0].clientY;
		} else {
			this.startX = event.clientX;
			this.startY = event.clientY;
		}
		this.startWidth = this.element.offsetWidth;
		this.startHeight = this.element.offsetHeight;
		if (this.startWidth > 0 && this.startHeight > 0) this.aspectRatio = this.startWidth / this.startHeight;
		if (this.getPos() !== void 0) {}
		this.container.dataset.resizeState = "true";
		if (this.classNames.resizing) this.container.classList.add(this.classNames.resizing);
		document.addEventListener("mousemove", this.handleMouseMove);
		document.addEventListener("touchmove", this.handleTouchMove);
		document.addEventListener("mouseup", this.handleMouseUp);
		document.addEventListener("keydown", this.handleKeyDown);
		document.addEventListener("keyup", this.handleKeyUp);
	}
	handleResize(deltaX, deltaY) {
		if (!this.activeHandle) return;
		const shouldPreserveAspectRatio = this.preserveAspectRatio || this.isShiftKeyPressed;
		const { width, height } = this.calculateNewDimensions(this.activeHandle, deltaX, deltaY);
		const constrained = this.applyConstraints(width, height, shouldPreserveAspectRatio);
		this.element.style.width = `${constrained.width}px`;
		this.element.style.height = `${constrained.height}px`;
		if (this.onResize) this.onResize(constrained.width, constrained.height);
	}
	/**
	* Calculates new dimensions based on mouse delta and resize direction.
	*
	* Takes the starting dimensions and applies the mouse movement delta
	* according to the handle direction. For corner handles, both dimensions
	* are affected. For edge handles, only one dimension changes. If aspect
	* ratio should be preserved, delegates to applyAspectRatio.
	*
	* @param direction - The active resize handle direction
	* @param deltaX - Horizontal mouse movement since resize start
	* @param deltaY - Vertical mouse movement since resize start
	* @returns The calculated width and height
	*/
	calculateNewDimensions(direction, deltaX, deltaY) {
		let newWidth = this.startWidth;
		let newHeight = this.startHeight;
		const isRight = direction.includes("right");
		const isLeft = direction.includes("left");
		const isBottom = direction.includes("bottom");
		const isTop = direction.includes("top");
		if (isRight) newWidth = this.startWidth + deltaX;
		else if (isLeft) newWidth = this.startWidth - deltaX;
		if (isBottom) newHeight = this.startHeight + deltaY;
		else if (isTop) newHeight = this.startHeight - deltaY;
		if (direction === "right" || direction === "left") newWidth = this.startWidth + (isRight ? deltaX : -deltaX);
		if (direction === "top" || direction === "bottom") newHeight = this.startHeight + (isBottom ? deltaY : -deltaY);
		if (this.preserveAspectRatio || this.isShiftKeyPressed) return this.applyAspectRatio(newWidth, newHeight, direction);
		return {
			width: newWidth,
			height: newHeight
		};
	}
	/**
	* Applies min/max constraints to dimensions.
	*
	* When aspect ratio is NOT preserved, constraints are applied independently
	* to width and height. When aspect ratio IS preserved, constraints are
	* applied while maintaining the aspect ratio—if one dimension hits a limit,
	* the other is recalculated proportionally.
	*
	* This ensures that aspect ratio is never broken when constrained.
	*
	* @param width - The unconstrained width
	* @param height - The unconstrained height
	* @param preserveAspectRatio - Whether to maintain aspect ratio while constraining
	* @returns The constrained dimensions
	*/
	applyConstraints(width, height, preserveAspectRatio) {
		var _a, _b, _c, _d;
		if (!preserveAspectRatio) {
			let constrainedWidth2 = Math.max(this.minSize.width, width);
			let constrainedHeight2 = Math.max(this.minSize.height, height);
			if ((_a = this.maxSize) == null ? void 0 : _a.width) constrainedWidth2 = Math.min(this.maxSize.width, constrainedWidth2);
			if ((_b = this.maxSize) == null ? void 0 : _b.height) constrainedHeight2 = Math.min(this.maxSize.height, constrainedHeight2);
			return {
				width: constrainedWidth2,
				height: constrainedHeight2
			};
		}
		let constrainedWidth = width;
		let constrainedHeight = height;
		if (constrainedWidth < this.minSize.width) {
			constrainedWidth = this.minSize.width;
			constrainedHeight = constrainedWidth / this.aspectRatio;
		}
		if (constrainedHeight < this.minSize.height) {
			constrainedHeight = this.minSize.height;
			constrainedWidth = constrainedHeight * this.aspectRatio;
		}
		if (((_c = this.maxSize) == null ? void 0 : _c.width) && constrainedWidth > this.maxSize.width) {
			constrainedWidth = this.maxSize.width;
			constrainedHeight = constrainedWidth / this.aspectRatio;
		}
		if (((_d = this.maxSize) == null ? void 0 : _d.height) && constrainedHeight > this.maxSize.height) {
			constrainedHeight = this.maxSize.height;
			constrainedWidth = constrainedHeight * this.aspectRatio;
		}
		return {
			width: constrainedWidth,
			height: constrainedHeight
		};
	}
	/**
	* Adjusts dimensions to maintain the original aspect ratio.
	*
	* For horizontal handles (left/right), uses width as the primary dimension
	* and calculates height from it. For vertical handles (top/bottom), uses
	* height as primary and calculates width. For corner handles, uses width
	* as the primary dimension.
	*
	* @param width - The new width
	* @param height - The new height
	* @param direction - The active resize direction
	* @returns Dimensions adjusted to preserve aspect ratio
	*/
	applyAspectRatio(width, height, direction) {
		const isHorizontal = direction === "left" || direction === "right";
		const isVertical = direction === "top" || direction === "bottom";
		if (isHorizontal) return {
			width,
			height: width / this.aspectRatio
		};
		if (isVertical) return {
			width: height * this.aspectRatio,
			height
		};
		return {
			width,
			height: width / this.aspectRatio
		};
	}
};
var Node3 = class _Node extends Extendable {
	constructor() {
		super(...arguments);
		this.type = "node";
	}
	/**
	* Create a new Node instance
	* @param config - Node configuration object or a function that returns a configuration object
	*/
	static create(config = {}) {
		const resolvedConfig = typeof config === "function" ? config() : config;
		return new _Node(resolvedConfig);
	}
	configure(options) {
		return super.configure(options);
	}
	extend(extendedConfig) {
		const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig;
		return super.extend(resolvedConfig);
	}
};
function markPasteRule(config) {
	return new PasteRule({
		find: config.find,
		handler: ({ state, range, match, pasteEvent }) => {
			const attributes = callOrReturn(config.getAttributes, void 0, match, pasteEvent);
			if (attributes === false || attributes === null) return null;
			const { tr } = state;
			const captureGroup = match[match.length - 1];
			const fullMatch = match[0];
			let markEnd = range.to;
			if (captureGroup) {
				const startSpaces = fullMatch.search(/\S/);
				const textStart = range.from + fullMatch.indexOf(captureGroup);
				const textEnd = textStart + captureGroup.length;
				if (getMarksBetween(range.from, range.to, state.doc).filter((item) => {
					return item.mark.type.excluded.find((type) => type === config.type && type !== item.mark.type);
				}).filter((item) => item.to > textStart).length) return null;
				if (textEnd < range.to) tr.delete(textEnd, range.to);
				if (textStart > range.from) tr.delete(range.from + startSpaces, textStart);
				markEnd = range.from + startSpaces + captureGroup.length;
				tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {}));
				if (!(match.index !== void 0 && match.input !== void 0 && match.index + match[0].length >= match.input.length)) tr.removeStoredMark(config.type);
			}
		}
	});
}
//#endregion
//#region ../../node_modules/.pnpm/fast-equals@5.4.1/node_modules/fast-equals/dist/es/index.mjs
var { getOwnPropertyNames, getOwnPropertySymbols } = Object;
var { hasOwnProperty } = Object.prototype;
/**
* Combine two comparators into a single comparators.
*/
function combineComparators(comparatorA, comparatorB) {
	return function isEqual(a, b, state) {
		return comparatorA(a, b, state) && comparatorB(a, b, state);
	};
}
/**
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
* for circular references to be safely included in the comparison without creating
* stack overflows.
*/
function createIsCircular(areItemsEqual) {
	return function isCircular(a, b, state) {
		if (!a || !b || typeof a !== "object" || typeof b !== "object") return areItemsEqual(a, b, state);
		const { cache } = state;
		const cachedA = cache.get(a);
		const cachedB = cache.get(b);
		if (cachedA && cachedB) return cachedA === b && cachedB === a;
		cache.set(a, b);
		cache.set(b, a);
		const result = areItemsEqual(a, b, state);
		cache.delete(a);
		cache.delete(b);
		return result;
	};
}
/**
* Get the `@@toStringTag` of the value, if it exists.
*/
function getShortTag(value) {
	return value != null ? value[Symbol.toStringTag] : void 0;
}
/**
* Get the properties to strictly examine, which include both own properties that are
* not enumerable and symbol properties.
*/
function getStrictProperties(object) {
	return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
}
/**
* Whether the object contains the property passed as an own property.
*/
var hasOwn = Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property));
/**
* Whether the values passed are strictly equal or both NaN.
*/
function sameValueZeroEqual(a, b) {
	return a === b || !a && !b && a !== a && b !== b;
}
var PREACT_VNODE = "__v";
var PREACT_OWNER = "__o";
var REACT_OWNER = "_owner";
var { getOwnPropertyDescriptor, keys } = Object;
/**
* Whether the array buffers are equal in value.
*/
function areArrayBuffersEqual(a, b) {
	return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a), new Uint8Array(b));
}
/**
* Whether the arrays are equal in value.
*/
function areArraysEqual(a, b, state) {
	let index = a.length;
	if (b.length !== index) return false;
	while (index-- > 0) if (!state.equals(a[index], b[index], index, index, a, b, state)) return false;
	return true;
}
/**
* Whether the dataviews are equal in value.
*/
function areDataViewsEqual(a, b) {
	return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a.buffer, a.byteOffset, a.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength));
}
/**
* Whether the dates passed are equal in value.
*/
function areDatesEqual(a, b) {
	return sameValueZeroEqual(a.getTime(), b.getTime());
}
/**
* Whether the errors passed are equal in value.
*/
function areErrorsEqual(a, b) {
	return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;
}
/**
* Whether the functions passed are equal in value.
*/
function areFunctionsEqual(a, b) {
	return a === b;
}
/**
* Whether the `Map`s are equal in value.
*/
function areMapsEqual(a, b, state) {
	const size = a.size;
	if (size !== b.size) return false;
	if (!size) return true;
	const matchedIndices = new Array(size);
	const aIterable = a.entries();
	let aResult;
	let bResult;
	let index = 0;
	while (aResult = aIterable.next()) {
		if (aResult.done) break;
		const bIterable = b.entries();
		let hasMatch = false;
		let matchIndex = 0;
		while (bResult = bIterable.next()) {
			if (bResult.done) break;
			if (matchedIndices[matchIndex]) {
				matchIndex++;
				continue;
			}
			const aEntry = aResult.value;
			const bEntry = bResult.value;
			if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state) && state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
				hasMatch = matchedIndices[matchIndex] = true;
				break;
			}
			matchIndex++;
		}
		if (!hasMatch) return false;
		index++;
	}
	return true;
}
/**
* Whether the numbers are equal in value.
*/
var areNumbersEqual = sameValueZeroEqual;
/**
* Whether the objects are equal in value.
*/
function areObjectsEqual(a, b, state) {
	const properties = keys(a);
	let index = properties.length;
	if (keys(b).length !== index) return false;
	while (index-- > 0) if (!isPropertyEqual(a, b, state, properties[index])) return false;
	return true;
}
/**
* Whether the objects are equal in value with strict property checking.
*/
function areObjectsEqualStrict(a, b, state) {
	const properties = getStrictProperties(a);
	let index = properties.length;
	if (getStrictProperties(b).length !== index) return false;
	let property;
	let descriptorA;
	let descriptorB;
	while (index-- > 0) {
		property = properties[index];
		if (!isPropertyEqual(a, b, state, property)) return false;
		descriptorA = getOwnPropertyDescriptor(a, property);
		descriptorB = getOwnPropertyDescriptor(b, property);
		if ((descriptorA || descriptorB) && (!descriptorA || !descriptorB || descriptorA.configurable !== descriptorB.configurable || descriptorA.enumerable !== descriptorB.enumerable || descriptorA.writable !== descriptorB.writable)) return false;
	}
	return true;
}
/**
* Whether the primitive wrappers passed are equal in value.
*/
function arePrimitiveWrappersEqual(a, b) {
	return sameValueZeroEqual(a.valueOf(), b.valueOf());
}
/**
* Whether the regexps passed are equal in value.
*/
function areRegExpsEqual(a, b) {
	return a.source === b.source && a.flags === b.flags;
}
/**
* Whether the `Set`s are equal in value.
*/
function areSetsEqual(a, b, state) {
	const size = a.size;
	if (size !== b.size) return false;
	if (!size) return true;
	const matchedIndices = new Array(size);
	const aIterable = a.values();
	let aResult;
	let bResult;
	while (aResult = aIterable.next()) {
		if (aResult.done) break;
		const bIterable = b.values();
		let hasMatch = false;
		let matchIndex = 0;
		while (bResult = bIterable.next()) {
			if (bResult.done) break;
			if (!matchedIndices[matchIndex] && state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
				hasMatch = matchedIndices[matchIndex] = true;
				break;
			}
			matchIndex++;
		}
		if (!hasMatch) return false;
	}
	return true;
}
/**
* Whether the TypedArray instances are equal in value.
*/
function areTypedArraysEqual(a, b) {
	let index = a.byteLength;
	if (b.byteLength !== index || a.byteOffset !== b.byteOffset) return false;
	while (index-- > 0) if (a[index] !== b[index]) return false;
	return true;
}
/**
* Whether the URL instances are equal in value.
*/
function areUrlsEqual(a, b) {
	return a.hostname === b.hostname && a.pathname === b.pathname && a.protocol === b.protocol && a.port === b.port && a.hash === b.hash && a.username === b.username && a.password === b.password;
}
function isPropertyEqual(a, b, state, property) {
	if ((property === REACT_OWNER || property === PREACT_OWNER || property === PREACT_VNODE) && (a.$$typeof || b.$$typeof)) return true;
	return hasOwn(b, property) && state.equals(a[property], b[property], property, property, a, b, state);
}
var ARRAY_BUFFER_TAG = "[object ArrayBuffer]";
var ARGUMENTS_TAG = "[object Arguments]";
var BOOLEAN_TAG = "[object Boolean]";
var DATA_VIEW_TAG = "[object DataView]";
var DATE_TAG = "[object Date]";
var ERROR_TAG = "[object Error]";
var MAP_TAG = "[object Map]";
var NUMBER_TAG = "[object Number]";
var OBJECT_TAG = "[object Object]";
var REG_EXP_TAG = "[object RegExp]";
var SET_TAG = "[object Set]";
var STRING_TAG = "[object String]";
var TYPED_ARRAY_TAGS = {
	"[object Int8Array]": true,
	"[object Uint8Array]": true,
	"[object Uint8ClampedArray]": true,
	"[object Int16Array]": true,
	"[object Uint16Array]": true,
	"[object Int32Array]": true,
	"[object Uint32Array]": true,
	"[object Float16Array]": true,
	"[object Float32Array]": true,
	"[object Float64Array]": true,
	"[object BigInt64Array]": true,
	"[object BigUint64Array]": true
};
var URL_TAG = "[object URL]";
var toString = Object.prototype.toString;
/**
* Create a comparator method based on the type-specific equality comparators passed.
*/
function createEqualityComparator({ areArrayBuffersEqual, areArraysEqual, areDataViewsEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, unknownTagComparators }) {
	/**
	* compare the value of the two objects and return true if they are equivalent in values
	*/
	return function comparator(a, b, state) {
		if (a === b) return true;
		if (a == null || b == null) return false;
		const type = typeof a;
		if (type !== typeof b) return false;
		if (type !== "object") {
			if (type === "number") return areNumbersEqual(a, b, state);
			if (type === "function") return areFunctionsEqual(a, b, state);
			return false;
		}
		const constructor = a.constructor;
		if (constructor !== b.constructor) return false;
		if (constructor === Object) return areObjectsEqual(a, b, state);
		if (Array.isArray(a)) return areArraysEqual(a, b, state);
		if (constructor === Date) return areDatesEqual(a, b, state);
		if (constructor === RegExp) return areRegExpsEqual(a, b, state);
		if (constructor === Map) return areMapsEqual(a, b, state);
		if (constructor === Set) return areSetsEqual(a, b, state);
		const tag = toString.call(a);
		if (tag === DATE_TAG) return areDatesEqual(a, b, state);
		if (tag === REG_EXP_TAG) return areRegExpsEqual(a, b, state);
		if (tag === MAP_TAG) return areMapsEqual(a, b, state);
		if (tag === SET_TAG) return areSetsEqual(a, b, state);
		if (tag === OBJECT_TAG) return typeof a.then !== "function" && typeof b.then !== "function" && areObjectsEqual(a, b, state);
		if (tag === URL_TAG) return areUrlsEqual(a, b, state);
		if (tag === ERROR_TAG) return areErrorsEqual(a, b, state);
		if (tag === ARGUMENTS_TAG) return areObjectsEqual(a, b, state);
		if (TYPED_ARRAY_TAGS[tag]) return areTypedArraysEqual(a, b, state);
		if (tag === ARRAY_BUFFER_TAG) return areArrayBuffersEqual(a, b, state);
		if (tag === DATA_VIEW_TAG) return areDataViewsEqual(a, b, state);
		if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) return arePrimitiveWrappersEqual(a, b, state);
		if (unknownTagComparators) {
			let unknownTagComparator = unknownTagComparators[tag];
			if (!unknownTagComparator) {
				const shortTag = getShortTag(a);
				if (shortTag) unknownTagComparator = unknownTagComparators[shortTag];
			}
			if (unknownTagComparator) return unknownTagComparator(a, b, state);
		}
		return false;
	};
}
/**
* Create the configuration object used for building comparators.
*/
function createEqualityComparatorConfig({ circular, createCustomConfig, strict }) {
	let config = {
		areArrayBuffersEqual,
		areArraysEqual: strict ? areObjectsEqualStrict : areArraysEqual,
		areDataViewsEqual,
		areDatesEqual,
		areErrorsEqual,
		areFunctionsEqual,
		areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
		areNumbersEqual,
		areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
		arePrimitiveWrappersEqual,
		areRegExpsEqual,
		areSetsEqual: strict ? combineComparators(areSetsEqual, areObjectsEqualStrict) : areSetsEqual,
		areTypedArraysEqual: strict ? combineComparators(areTypedArraysEqual, areObjectsEqualStrict) : areTypedArraysEqual,
		areUrlsEqual,
		unknownTagComparators: void 0
	};
	if (createCustomConfig) config = Object.assign({}, config, createCustomConfig(config));
	if (circular) {
		const areArraysEqual = createIsCircular(config.areArraysEqual);
		const areMapsEqual = createIsCircular(config.areMapsEqual);
		const areObjectsEqual = createIsCircular(config.areObjectsEqual);
		const areSetsEqual = createIsCircular(config.areSetsEqual);
		config = Object.assign({}, config, {
			areArraysEqual,
			areMapsEqual,
			areObjectsEqual,
			areSetsEqual
		});
	}
	return config;
}
/**
* Default equality comparator pass-through, used as the standard `isEqual` creator for
* use inside the built comparator.
*/
function createInternalEqualityComparator(compare) {
	return function(a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {
		return compare(a, b, state);
	};
}
/**
* Create the `isEqual` function used by the consuming application.
*/
function createIsEqual({ circular, comparator, createState, equals, strict }) {
	if (createState) return function isEqual(a, b) {
		const { cache = circular ? /* @__PURE__ */ new WeakMap() : void 0, meta } = createState();
		return comparator(a, b, {
			cache,
			equals,
			meta,
			strict
		});
	};
	if (circular) return function isEqual(a, b) {
		return comparator(a, b, {
			cache: /* @__PURE__ */ new WeakMap(),
			equals,
			meta: void 0,
			strict
		});
	};
	const state = {
		cache: void 0,
		equals,
		meta: void 0,
		strict
	};
	return function isEqual(a, b) {
		return comparator(a, b, state);
	};
}
/**
* Whether the items passed are deeply-equal in value.
*/
var deepEqual = createCustomEqual();
createCustomEqual({ strict: true });
createCustomEqual({ circular: true });
createCustomEqual({
	circular: true,
	strict: true
});
createCustomEqual({ createInternalComparator: () => sameValueZeroEqual });
createCustomEqual({
	strict: true,
	createInternalComparator: () => sameValueZeroEqual
});
createCustomEqual({
	circular: true,
	createInternalComparator: () => sameValueZeroEqual
});
createCustomEqual({
	circular: true,
	createInternalComparator: () => sameValueZeroEqual,
	strict: true
});
/**
* Create a custom equality comparison method.
*
* This can be done to create very targeted comparisons in extreme hot-path scenarios
* where the standard methods are not performant enough, but can also be used to provide
* support for legacy environments that do not support expected features like
* `RegExp.prototype.flags` out of the box.
*/
function createCustomEqual(options = {}) {
	const { circular = false, createInternalComparator: createCustomInternalComparator, createState, strict = false } = options;
	const comparator = createEqualityComparator(createEqualityComparatorConfig(options));
	return createIsEqual({
		circular,
		comparator,
		createState,
		equals: createCustomInternalComparator ? createCustomInternalComparator(comparator) : createInternalEqualityComparator(comparator),
		strict
	});
}
//#endregion
//#region ../../node_modules/.pnpm/use-sync-external-store@1.6.0_react@19.2.8/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.js
/**
* @license React
* use-sync-external-store-shim/with-selector.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var require_with_selector_production = /* @__PURE__ */ __commonJSMin(((exports) => {
	var React = require_react();
	var shim = require_shim();
	function is(x, y) {
		return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
	}
	var objectIs = "function" === typeof Object.is ? Object.is : is;
	var useSyncExternalStore = shim.useSyncExternalStore;
	var useRef = React.useRef;
	var useEffect = React.useEffect;
	var useMemo = React.useMemo;
	var useDebugValue = React.useDebugValue;
	exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
		var instRef = useRef(null);
		if (null === instRef.current) {
			var inst = {
				hasValue: !1,
				value: null
			};
			instRef.current = inst;
		} else inst = instRef.current;
		instRef = useMemo(function() {
			function memoizedSelector(nextSnapshot) {
				if (!hasMemo) {
					hasMemo = !0;
					memoizedSnapshot = nextSnapshot;
					nextSnapshot = selector(nextSnapshot);
					if (void 0 !== isEqual && inst.hasValue) {
						var currentSelection = inst.value;
						if (isEqual(currentSelection, nextSnapshot)) return memoizedSelection = currentSelection;
					}
					return memoizedSelection = nextSnapshot;
				}
				currentSelection = memoizedSelection;
				if (objectIs(memoizedSnapshot, nextSnapshot)) return currentSelection;
				var nextSelection = selector(nextSnapshot);
				if (void 0 !== isEqual && isEqual(currentSelection, nextSelection)) return memoizedSnapshot = nextSnapshot, currentSelection;
				memoizedSnapshot = nextSnapshot;
				return memoizedSelection = nextSelection;
			}
			var hasMemo = !1, memoizedSnapshot, memoizedSelection, maybeGetServerSnapshot = void 0 === getServerSnapshot ? null : getServerSnapshot;
			return [function() {
				return memoizedSelector(getSnapshot());
			}, null === maybeGetServerSnapshot ? void 0 : function() {
				return memoizedSelector(maybeGetServerSnapshot());
			}];
		}, [
			getSnapshot,
			getServerSnapshot,
			selector,
			isEqual
		]);
		var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
		useEffect(function() {
			inst.hasValue = !0;
			inst.value = value;
		}, [value]);
		useDebugValue(value);
		return value;
	};
}));
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+react@3.30.2_@floating-ui+dom@1.7.6_@tiptap+core@3.30.2_@tiptap+pm@3.30.2__@tip_f8cd67bcdbcd36023f82bd0da000a2e4/node_modules/@tiptap/react/dist/index.js
var import_with_selector = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = require_with_selector_production();
})))();
var mergeRefs = (...refs) => {
	return (node) => {
		refs.forEach((ref) => {
			if (typeof ref === "function") ref(node);
			else if (ref) ref.current = node;
		});
	};
};
var Portals = ({ contentComponent }) => {
	const renderers = (0, import_shim.useSyncExternalStore)(contentComponent.subscribe, contentComponent.getSnapshot, contentComponent.getServerSnapshot);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: Object.values(renderers) });
};
function createContentComponent() {
	const subscribers = /* @__PURE__ */ new Set();
	let renderers = {};
	let isNotificationQueued = false;
	const notifySubscribers = () => {
		if (isNotificationQueued || !subscribers.size) return;
		isNotificationQueued = true;
		queueMicrotask(() => {
			isNotificationQueued = false;
			subscribers.forEach((subscriber) => subscriber());
		});
	};
	return {
		/**
		* Subscribe to the editor instance's changes.
		*/
		subscribe(callback) {
			subscribers.add(callback);
			return () => {
				subscribers.delete(callback);
			};
		},
		getSnapshot() {
			return renderers;
		},
		getServerSnapshot() {
			return renderers;
		},
		/**
		* Adds a new NodeView Renderer to the editor.
		*/
		setRenderer(id, renderer) {
			renderers = {
				...renderers,
				[id]: import_react_dom.createPortal(renderer.reactElement, renderer.element, id)
			};
			notifySubscribers();
		},
		/**
		* Removes a NodeView Renderer from the editor.
		*/
		removeRenderer(id) {
			const nextRenderers = { ...renderers };
			delete nextRenderers[id];
			renderers = nextRenderers;
			notifySubscribers();
		}
	};
}
var PureEditorContent = class extends import_react.Component {
	constructor(props) {
		super(props);
		this.editorContentRef = import_react.createRef();
	}
	componentDidMount() {
		this.init();
	}
	componentDidUpdate() {
		this.init();
	}
	init() {
		var _a;
		const editor = this.props.editor;
		if (editor && !editor.isDestroyed && ((_a = editor.view.dom) == null ? void 0 : _a.parentNode)) {
			if (editor.contentComponent) return;
			const element = this.editorContentRef.current;
			element.append(...editor.view.dom.parentNode.childNodes);
			editor.setOptions({ element });
			editor.contentComponent = createContentComponent();
			editor.createNodeViews();
			editor.isEditorContentInitialized = true;
			this.forceUpdate();
		}
	}
	componentWillUnmount() {
		var _a;
		const editor = this.props.editor;
		if (!editor) return;
		editor.isEditorContentInitialized = false;
		if (!editor.isDestroyed) editor.view.setProps({ nodeViews: {} });
		editor.contentComponent = null;
		try {
			if (!((_a = editor.view.dom) == null ? void 0 : _a.parentNode)) return;
			const newElement = document.createElement("div");
			newElement.append(...editor.view.dom.parentNode.childNodes);
			editor.setOptions({ element: newElement });
		} catch {}
	}
	render() {
		const { editor, innerRef, ...rest } = this.props;
		return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			ref: mergeRefs(innerRef, this.editorContentRef),
			...rest
		}), (editor == null ? void 0 : editor.contentComponent) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portals, { contentComponent: editor.contentComponent })] });
	}
};
var EditorContentWithKey = (0, import_react.forwardRef)((props, ref) => {
	const key = import_react.useMemo(() => {
		return Math.floor(Math.random() * 4294967295).toString();
	}, [props.editor]);
	return import_react.createElement(PureEditorContent, {
		key,
		innerRef: ref,
		...props
	});
});
var EditorContent = import_react.memo(EditorContentWithKey);
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react.useLayoutEffect : import_react.useEffect;
var EditorStateManager = class {
	constructor(initialEditor) {
		this.transactionNumber = 0;
		this.lastTransactionNumber = 0;
		this.subscribers = /* @__PURE__ */ new Set();
		this.editor = initialEditor;
		this.lastSnapshot = {
			editor: initialEditor,
			transactionNumber: 0
		};
		this.getSnapshot = this.getSnapshot.bind(this);
		this.getServerSnapshot = this.getServerSnapshot.bind(this);
		this.watch = this.watch.bind(this);
		this.subscribe = this.subscribe.bind(this);
	}
	/**
	* Get the current editor instance.
	*/
	getSnapshot() {
		if (this.transactionNumber === this.lastTransactionNumber) return this.lastSnapshot;
		this.lastTransactionNumber = this.transactionNumber;
		this.lastSnapshot = {
			editor: this.editor,
			transactionNumber: this.transactionNumber
		};
		return this.lastSnapshot;
	}
	/**
	* Always disable the editor on the server-side.
	*/
	getServerSnapshot() {
		return {
			editor: null,
			transactionNumber: 0
		};
	}
	/**
	* Subscribe to the editor instance's changes.
	*/
	subscribe(callback) {
		this.subscribers.add(callback);
		return () => {
			this.subscribers.delete(callback);
		};
	}
	/**
	* Watch the editor instance for changes.
	*/
	watch(nextEditor) {
		this.editor = nextEditor;
		if (this.editor) {
			let lastTransaction;
			const fn = (props) => {
				if ((props == null ? void 0 : props.transaction) !== void 0 && props.transaction === lastTransaction) return;
				lastTransaction = props == null ? void 0 : props.transaction;
				this.transactionNumber += 1;
				this.subscribers.forEach((callback) => callback());
			};
			const currentEditor = this.editor;
			currentEditor.on("transaction", fn);
			currentEditor.on("update", fn);
			return () => {
				currentEditor.off("transaction", fn);
				currentEditor.off("update", fn);
			};
		}
	}
};
function useEditorState(options) {
	var _a;
	const [editorStateManager] = (0, import_react.useState)(() => new EditorStateManager(options.editor));
	const selectedState = (0, import_with_selector.useSyncExternalStoreWithSelector)(editorStateManager.subscribe, editorStateManager.getSnapshot, editorStateManager.getServerSnapshot, options.selector, (_a = options.equalityFn) != null ? _a : deepEqual);
	useIsomorphicLayoutEffect(() => {
		return editorStateManager.watch(options.editor);
	}, [options.editor, editorStateManager]);
	(0, import_react.useDebugValue)(selectedState);
	return selectedState;
}
var isDev = false;
var isSSR = typeof window === "undefined";
var isNext = isSSR || Boolean(typeof window !== "undefined" && window.next);
var EditorInstanceManager = class _EditorInstanceManager {
	constructor(options) {
		/**
		* The current editor instance.
		*/
		this.editor = null;
		/**
		* The subscriptions to notify when the editor instance
		* has been created or destroyed.
		*/
		this.subscriptions = /* @__PURE__ */ new Set();
		/**
		* Whether the editor has been mounted.
		*/
		this.isComponentMounted = false;
		/**
		* The most recent dependencies array.
		*/
		this.previousDeps = null;
		/**
		* The unique instance ID. This is used to identify the editor instance. And will be re-generated for each new instance.
		*/
		this.instanceId = "";
		this.options = options;
		this.subscriptions = /* @__PURE__ */ new Set();
		this.setEditor(this.getInitialEditor());
		this.scheduleDestroy();
		this.getEditor = this.getEditor.bind(this);
		this.getServerSnapshot = this.getServerSnapshot.bind(this);
		this.subscribe = this.subscribe.bind(this);
		this.refreshEditorInstance = this.refreshEditorInstance.bind(this);
		this.scheduleDestroy = this.scheduleDestroy.bind(this);
		this.onRender = this.onRender.bind(this);
		this.createEditor = this.createEditor.bind(this);
	}
	setEditor(editor) {
		this.editor = editor;
		this.instanceId = Math.random().toString(36).slice(2, 9);
		this.subscriptions.forEach((cb) => cb());
	}
	getInitialEditor() {
		const explicit = this.options.current.immediatelyRender;
		let immediatelyRender = explicit != null ? explicit : true;
		if (isSSR) {
			if (immediatelyRender && isDev) console.warn("SSR detected. `immediatelyRender` has been set to false to avoid hydration mismatches");
			immediatelyRender = false;
		} else if (isNext && explicit === void 0) {
			immediatelyRender = false;
			if (isDev) console.warn("Next.js detected. `immediatelyRender` defaults to false to avoid hydration mismatches. Pass `immediatelyRender: true` explicitly if you are rendering the editor only on the client.");
		}
		return immediatelyRender ? this.createEditor() : null;
	}
	/**
	* Create a new editor instance. And attach event listeners.
	*/
	createEditor() {
		return new Editor({
			...this.options.current,
			onBeforeCreate: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onBeforeCreate) == null ? void 0 : _b.call(_a, ...args);
			},
			onBlur: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onBlur) == null ? void 0 : _b.call(_a, ...args);
			},
			onCreate: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onCreate) == null ? void 0 : _b.call(_a, ...args);
			},
			onDestroy: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onDestroy) == null ? void 0 : _b.call(_a, ...args);
			},
			onFocus: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onFocus) == null ? void 0 : _b.call(_a, ...args);
			},
			onSelectionUpdate: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onSelectionUpdate) == null ? void 0 : _b.call(_a, ...args);
			},
			onTransaction: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onTransaction) == null ? void 0 : _b.call(_a, ...args);
			},
			onUpdate: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onUpdate) == null ? void 0 : _b.call(_a, ...args);
			},
			onContentError: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onContentError) == null ? void 0 : _b.call(_a, ...args);
			},
			onDrop: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onDrop) == null ? void 0 : _b.call(_a, ...args);
			},
			onPaste: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onPaste) == null ? void 0 : _b.call(_a, ...args);
			},
			onDelete: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onDelete) == null ? void 0 : _b.call(_a, ...args);
			},
			onMount: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onMount) == null ? void 0 : _b.call(_a, ...args);
			},
			onUnmount: (...args) => {
				var _a, _b;
				return (_b = (_a = this.options.current).onUnmount) == null ? void 0 : _b.call(_a, ...args);
			}
		});
	}
	/**
	* Get the current editor instance.
	*/
	getEditor() {
		return this.editor;
	}
	/**
	* Always disable the editor on the server-side.
	*/
	getServerSnapshot() {
		return null;
	}
	/**
	* Subscribe to the editor instance's changes.
	*/
	subscribe(onStoreChange) {
		this.subscriptions.add(onStoreChange);
		return () => {
			this.subscriptions.delete(onStoreChange);
		};
	}
	static compareOptions(a, b) {
		return Object.keys(a).every((key) => {
			if ([
				"onCreate",
				"onBeforeCreate",
				"onDestroy",
				"onUpdate",
				"onTransaction",
				"onFocus",
				"onBlur",
				"onSelectionUpdate",
				"onContentError",
				"onDrop",
				"onPaste"
			].includes(key)) return true;
			if (key === "extensions" && a.extensions && b.extensions) {
				if (a.extensions.length !== b.extensions.length) return false;
				return a.extensions.every((extension, index) => {
					var _a;
					if (extension !== ((_a = b.extensions) == null ? void 0 : _a[index])) return false;
					return true;
				});
			}
			if (a[key] !== b[key]) return false;
			return true;
		});
	}
	/**
	* On each render, we will create, update, or destroy the editor instance.
	* @param deps The dependencies to watch for changes
	* @returns A cleanup function
	*/
	onRender(deps) {
		return () => {
			this.isComponentMounted = true;
			clearTimeout(this.scheduledDestructionTimeout);
			if (this.editor && !this.editor.isDestroyed && deps.length === 0) {
				if (!_EditorInstanceManager.compareOptions(this.options.current, this.editor.options)) this.editor.setOptions({
					...this.options.current,
					editable: this.editor.isEditable
				});
			} else this.refreshEditorInstance(deps);
			return () => {
				this.isComponentMounted = false;
				this.scheduleDestroy();
			};
		};
	}
	/**
	* Recreate the editor instance if the dependencies have changed.
	*/
	refreshEditorInstance(deps) {
		if (this.editor && !this.editor.isDestroyed) {
			if (this.previousDeps === null) {
				this.previousDeps = deps;
				return;
			}
			if (this.previousDeps.length === deps.length && this.previousDeps.every((dep, index) => dep === deps[index])) return;
		}
		if (this.editor && !this.editor.isDestroyed) this.editor.destroy();
		this.setEditor(this.createEditor());
		this.previousDeps = deps;
	}
	/**
	* Schedule the destruction of the editor instance.
	* This will only destroy the editor if it was not mounted on the next tick.
	* This is to avoid destroying the editor instance when it's actually still mounted.
	*/
	scheduleDestroy() {
		const currentInstanceId = this.instanceId;
		const currentEditor = this.editor;
		this.scheduledDestructionTimeout = setTimeout(() => {
			if (this.isComponentMounted && this.instanceId === currentInstanceId) {
				if (currentEditor) currentEditor.setOptions(this.options.current);
				return;
			}
			if (currentEditor && !currentEditor.isDestroyed) {
				currentEditor.destroy();
				if (this.instanceId === currentInstanceId) this.setEditor(null);
			}
		}, 1);
	}
};
function useEditor(options = {}, deps = []) {
	const mostRecentOptions = (0, import_react.useRef)(options);
	mostRecentOptions.current = options;
	const [instanceManager] = (0, import_react.useState)(() => new EditorInstanceManager(mostRecentOptions));
	const editor = (0, import_shim.useSyncExternalStore)(instanceManager.subscribe, instanceManager.getEditor, instanceManager.getServerSnapshot);
	(0, import_react.useDebugValue)(editor);
	(0, import_react.useEffect)(instanceManager.onRender(deps));
	useEditorState({
		editor,
		selector: ({ transactionNumber }) => {
			if (options.shouldRerenderOnTransaction === false || options.shouldRerenderOnTransaction === void 0) return null;
			if (options.immediatelyRender && transactionNumber === 0) return 0;
			return transactionNumber + 1;
		}
	});
	return editor;
}
var EditorContext = (0, import_react.createContext)({ editor: null });
EditorContext.Consumer;
var ReactNodeViewContext = (0, import_react.createContext)({
	onDragStart: () => {},
	nodeViewContentChildren: void 0,
	nodeViewContentRef: () => {}
});
var useReactNodeView = () => (0, import_react.useContext)(ReactNodeViewContext);
import_react.forwardRef((props, ref) => {
	const { onDragStart } = useReactNodeView();
	const Tag = props.as || "div";
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag, {
		...props,
		ref,
		"data-node-view-wrapper": "",
		onDragStart,
		style: {
			whiteSpace: "normal",
			...props.style
		}
	});
});
import_react.createContext({ markViewContentRef: () => {} });
var TiptapContext = (0, import_react.createContext)({ get editor() {
	throw new Error("useTiptap must be used within a <Tiptap> provider");
} });
TiptapContext.displayName = "TiptapContext";
var useTiptap = () => (0, import_react.useContext)(TiptapContext);
function TiptapWrapper({ children, ...props }) {
	const resolvedEditor = "editor" in props ? props.editor : props.instance;
	if (!resolvedEditor) throw new Error("Tiptap: An editor instance is required. Pass a non-null `editor` prop.");
	const tiptapContextValue = (0, import_react.useMemo)(() => ({ editor: resolvedEditor }), [resolvedEditor]);
	const legacyContextValue = (0, import_react.useMemo)(() => ({ editor: resolvedEditor }), [resolvedEditor]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorContext.Provider, {
		value: legacyContextValue,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TiptapContext.Provider, {
			value: tiptapContextValue,
			children
		})
	});
}
TiptapWrapper.displayName = "Tiptap";
function TiptapContent({ ...rest }) {
	const { editor } = useTiptap();
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorContent, {
		editor,
		...rest
	});
}
TiptapContent.displayName = "Tiptap.Content";
Object.assign(TiptapWrapper, { 
/**
* The Tiptap Content component that renders the EditorContent with the editor instance from the context.
* @see TiptapContent
*/
Content: TiptapContent });
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+core@3.30.2_@tiptap+pm@3.30.2/node_modules/@tiptap/core/dist/jsx-runtime/jsx-runtime.js
function render(tag, attributes, hasMultipleChildren) {
	if (tag === "slot") return 0;
	if (tag instanceof Function) return tag(attributes);
	const { children, ...rest } = attributes != null ? attributes : {};
	if (tag === "svg") throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");
	if (hasMultipleChildren && Array.isArray(children)) return [
		tag,
		rest,
		...children
	];
	return [
		tag,
		rest,
		children
	];
}
var h = (tag, attributes) => render(tag, attributes, false);
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-bold@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2_/node_modules/@tiptap/extension-bold/dist/index.js
var starInputRegex$1 = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/;
var starPasteRegex$1 = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g;
var underscoreInputRegex$1 = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/;
var underscorePasteRegex$1 = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g;
var Bold = Mark.create({
	name: "bold",
	addOptions() {
		return { HTMLAttributes: {} };
	},
	parseHTML() {
		return [
			{ tag: "strong" },
			{
				tag: "b",
				getAttrs: (node) => node.style.fontWeight !== "normal" && null
			},
			{
				style: "font-weight=400",
				clearMark: (mark) => mark.type.name === this.name
			},
			{
				style: "font-weight",
				getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null
			}
		];
	},
	renderHTML({ HTMLAttributes }) {
		return /* @__PURE__ */ h("strong", {
			...mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
			children: /* @__PURE__ */ h("slot", {})
		});
	},
	markdownTokenName: "strong",
	parseMarkdown: (token, helpers) => {
		return helpers.applyMark("bold", helpers.parseInline(token.tokens || []));
	},
	markdownOptions: { htmlReopen: {
		open: "<strong>",
		close: "</strong>"
	} },
	renderMarkdown: (node, h) => {
		return `**${h.renderChildren(node)}**`;
	},
	addCommands() {
		return {
			setBold: () => ({ commands }) => {
				return commands.setMark(this.name);
			},
			toggleBold: () => ({ commands }) => {
				return commands.toggleMark(this.name);
			},
			unsetBold: () => ({ commands }) => {
				return commands.unsetMark(this.name);
			}
		};
	},
	addKeyboardShortcuts() {
		return {
			"Mod-b": () => this.editor.commands.toggleBold(),
			"Mod-B": () => this.editor.commands.toggleBold()
		};
	},
	addInputRules() {
		return [markInputRule({
			find: starInputRegex$1,
			type: this.type
		}), markInputRule({
			find: underscoreInputRegex$1,
			type: this.type
		})];
	},
	addPasteRules() {
		return [markPasteRule({
			find: starPasteRegex$1,
			type: this.type
		}), markPasteRule({
			find: underscorePasteRegex$1,
			type: this.type
		})];
	}
});
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-list@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2__@tiptap+pm@3.30.2/node_modules/@tiptap/extension-list/dist/index.js
var __defProp$4 = Object.defineProperty;
var __export = (target, all) => {
	for (var name in all) __defProp$4(target, name, {
		get: all[name],
		enumerable: true
	});
};
var ListItemName = "listItem";
var TextStyleName = "textStyle";
var bulletListInputRegex = /^\s*([-+*])\s$/;
var BulletList = Node3.create({
	name: "bulletList",
	addOptions() {
		return {
			itemTypeName: "listItem",
			HTMLAttributes: {},
			keepMarks: false,
			keepAttributes: false
		};
	},
	group: "block list",
	content() {
		return `${this.options.itemTypeName}+`;
	},
	parseHTML() {
		return [{ tag: "ul" }];
	},
	renderHTML({ HTMLAttributes }) {
		return [
			"ul",
			mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
			0
		];
	},
	markdownTokenName: "list",
	parseMarkdown: (token, helpers) => {
		if (token.type !== "list" || token.ordered) return [];
		return {
			type: "bulletList",
			content: token.items ? helpers.parseChildren(token.items) : []
		};
	},
	renderMarkdown: (node, h) => {
		if (!node.content) return "";
		return h.renderChildren(node.content, "\n");
	},
	markdownOptions: { indentsContent: true },
	addCommands() {
		return { toggleBulletList: () => ({ commands, chain }) => {
			if (this.options.keepAttributes) return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run();
			return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
		} };
	},
	addKeyboardShortcuts() {
		return { "Mod-Shift-8": () => this.editor.commands.toggleBulletList() };
	},
	addInputRules() {
		let inputRule = wrappingInputRule({
			find: bulletListInputRegex,
			type: this.type
		});
		if (this.options.keepMarks || this.options.keepAttributes) inputRule = wrappingInputRule({
			find: bulletListInputRegex,
			type: this.type,
			keepMarks: this.options.keepMarks,
			keepAttributes: this.options.keepAttributes,
			getAttributes: () => {
				return this.editor.getAttributes(TextStyleName);
			},
			editor: this.editor
		});
		return [inputRule];
	}
});
var getBranchingNestedListAtCursor = (state, itemName, wrapperNames) => {
	const { selection } = state;
	if (!selection.empty) return null;
	const { $from } = selection;
	if (!$from.parent.isTextblock) return null;
	if ($from.parentOffset !== $from.parent.content.size) return null;
	let listItemDepth = -1;
	for (let depth = $from.depth; depth > 0; depth -= 1) if ($from.node(depth).type.name === itemName) {
		listItemDepth = depth;
		break;
	}
	if (listItemDepth < 0) return null;
	const listItem = $from.node(listItemDepth);
	const indexInListItem = $from.index(listItemDepth);
	if (indexInListItem + 1 >= listItem.childCount) return null;
	const nextChild = listItem.child(indexInListItem + 1);
	if (!wrapperNames.includes(nextChild.type.name)) return null;
	const itemType = state.schema.nodes[itemName];
	let hasBranching = false;
	nextChild.forEach((child) => {
		if (child.type === itemType && child.childCount > 1) hasBranching = true;
	});
	if (!hasBranching) return null;
	const nodeAfter = state.doc.resolve($from.after()).nodeAfter;
	if (!nodeAfter || !wrapperNames.includes(nodeAfter.type.name)) return null;
	const items = [];
	nodeAfter.forEach((child) => {
		items.push(child);
	});
	if (items.length === 0) return null;
	return {
		listItemDepth,
		nestedList: nodeAfter,
		nestedListPos: $from.after(),
		insertPos: $from.after(listItemDepth),
		items
	};
};
var hoistBranchingNestedList = (state, dispatch, itemName, wrapperNames) => {
	const context = getBranchingNestedListAtCursor(state, itemName, wrapperNames);
	if (!context) return false;
	const { selection } = state;
	const { nestedList, nestedListPos, insertPos, items } = context;
	const tr = state.tr;
	tr.delete(nestedListPos, nestedListPos + nestedList.nodeSize);
	const mappedInsertPos = tr.mapping.map(insertPos);
	tr.insert(mappedInsertPos, Fragment$8.from(items));
	tr.setSelection(selection.map(tr.doc, tr.mapping));
	if (dispatch) dispatch(tr);
	return true;
};
var handleDeleteBranchingNestedList = (editor, itemName, wrapperNames) => {
	return hoistBranchingNestedList(editor.state, editor.view.dispatch, itemName, wrapperNames);
};
var createBranchingListDeleteKeymap = (itemName, wrapperNames) => {
	return Extension.create({
		name: `${itemName}BranchingDeleteKeymap`,
		priority: 101,
		addKeyboardShortcuts() {
			const handleDelete2 = () => handleDeleteBranchingNestedList(this.editor, itemName, wrapperNames);
			return {
				Delete: handleDelete2,
				"Mod-Delete": handleDelete2
			};
		}
	});
};
var ROMAN_NUMERALS = [
	[1e3, "m"],
	[900, "cm"],
	[500, "d"],
	[400, "cd"],
	[100, "c"],
	[90, "xc"],
	[50, "l"],
	[40, "xl"],
	[10, "x"],
	[9, "ix"],
	[5, "v"],
	[4, "iv"],
	[1, "i"]
];
var ALPHA_NUMERALS = "abcdefghijklmnopqrstuvwxyz";
var ORDERED_LIST_MARKER_PATTERN = String.raw`\d+|[ivxlcdmIVXLCDM]+|${"[a-zA-Z]{1,2}"}`;
function toRoman(num) {
	let remaining = num;
	let result = "";
	for (const [value, numeral] of ROMAN_NUMERALS) while (remaining >= value) {
		result += numeral;
		remaining -= value;
	}
	return result;
}
function toRomanUpper(num) {
	return toRoman(num).toUpperCase();
}
function fromRoman(roman) {
	const lower = roman.toLowerCase();
	let index = 0;
	let result = 0;
	while (index < lower.length) {
		let matched = false;
		for (const [value, numeral] of ROMAN_NUMERALS) if (lower.startsWith(numeral, index)) {
			result += value;
			index += numeral.length;
			matched = true;
			break;
		}
		if (!matched) return 0;
	}
	return result;
}
function isValidRoman(marker) {
	if (!/^[ivxlcdmIVXLCDM]+$/.test(marker)) return false;
	const value = fromRoman(marker);
	if (value <= 0) return false;
	return (marker === marker.toLowerCase() ? toRoman(value) : toRomanUpper(value)) === marker;
}
function fromAlpha(marker) {
	const lower = marker.toLowerCase();
	if (lower.length === 1) return lower.charCodeAt(0) - "a".charCodeAt(0) + 1;
	if (lower.length === 2) {
		const first = lower.charCodeAt(0) - "a".charCodeAt(0);
		const second = lower.charCodeAt(1) - "a".charCodeAt(0);
		return (first + 1) * 26 + second + 1;
	}
	return 0;
}
function toRomanAlpha(num) {
	if (num <= 26) return ALPHA_NUMERALS[num - 1];
	const first = Math.floor((num - 1) / 26) - 1;
	const second = (num - 1) % 26;
	if (first < 0) return ALPHA_NUMERALS[second];
	return ALPHA_NUMERALS[first] + ALPHA_NUMERALS[second];
}
function detectMarkerType(marker) {
	if (!marker || /^\d+$/.test(marker)) return;
	if (isValidRoman(marker)) return marker === marker.toLowerCase() ? "i" : "I";
	if (/^[a-z]{1,2}$/.test(marker)) return "a";
	if (/^[A-Z]{1,2}$/.test(marker)) return "A";
}
function markerToStart(marker) {
	if (/^\d+$/.test(marker)) return parseInt(marker, 10);
	const type = detectMarkerType(marker);
	if (type === "i" || type === "I") return fromRoman(marker);
	if (type === "a" || type === "A") {
		const start = fromAlpha(marker);
		return start > 0 ? start : 1;
	}
	const parsed = parseInt(marker, 10);
	return Number.isNaN(parsed) ? 1 : parsed;
}
function startToMarker(type, start) {
	if (type === "numeric") return String(start);
	switch (type) {
		case "a": return toRomanAlpha(start);
		case "A": return toRomanAlpha(start).toUpperCase();
		case "i": return toRoman(start);
		case "I": return toRomanUpper(start);
		default: return String(start);
	}
}
function areOrderedListMarkersSequential(markers) {
	var _a;
	if (markers.length === 0) return false;
	const firstType = (_a = detectMarkerType(markers[0])) != null ? _a : "numeric";
	const firstStart = markerToStart(markers[0]);
	if (firstStart < 1) return false;
	for (let i = 0; i < markers.length; i++) {
		const expected = startToMarker(firstType, firstStart + i);
		if (markers[i] !== expected) return false;
	}
	return true;
}
function parseListMarker(marker) {
	return {
		type: detectMarkerType(marker),
		start: markerToStart(marker)
	};
}
function buildOrderedListAttrsFromMarker(marker) {
	const { type, start } = parseListMarker(marker);
	const attrs = {};
	if (type) attrs.type = type;
	if (start !== 1) attrs.start = start;
	return attrs;
}
function getListMarker(type, index, separator = ". ") {
	const position = index + 1;
	if (!type || type === "1") return `${position}${separator}`;
	switch (type) {
		case "a": return `${toRomanAlpha(position)}${separator}`;
		case "A": return `${toRomanAlpha(position).toUpperCase()}${separator}`;
		case "i": return `${toRoman(position)}${separator}`;
		case "I": return `${toRomanUpper(position)}${separator}`;
		default: return `${position}${separator}`;
	}
}
function isSameLineOrderedListToken(token) {
	var _a, _b;
	const nestedToken = (_a = token.tokens) == null ? void 0 : _a[0];
	return Boolean(token.text && ((_b = token.tokens) == null ? void 0 : _b.length) === 1 && (nestedToken == null ? void 0 : nestedToken.type) === "list" && nestedToken.ordered && nestedToken.raw === token.text);
}
function parseSameLineOrderedListText(text, helpers) {
	if (helpers.tokenizeInline) return helpers.parseInline(helpers.tokenizeInline(text));
	return helpers.parseInline([{
		type: "text",
		raw: text,
		text
	}]);
}
var ListItem = Node3.create({
	name: "listItem",
	addOptions() {
		return {
			HTMLAttributes: {},
			bulletListTypeName: "bulletList",
			orderedListTypeName: "orderedList"
		};
	},
	content: "paragraph block*",
	defining: true,
	parseHTML() {
		return [{ tag: "li" }];
	},
	renderHTML({ HTMLAttributes }) {
		return [
			"li",
			mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
			0
		];
	},
	markdownTokenName: "list_item",
	parseMarkdown: (token, helpers) => {
		var _a;
		if (token.type !== "list_item") return [];
		const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren;
		let content = [];
		if (token.tokens && token.tokens.length > 0) {
			if (isSameLineOrderedListToken(token)) return {
				type: "listItem",
				content: [{
					type: "paragraph",
					content: parseSameLineOrderedListText(token.text || "", helpers)
				}]
			};
			if (token.tokens.some((t) => t.type === "paragraph")) content = parseBlockChildren(token.tokens);
			else {
				const firstToken = token.tokens[0];
				if (firstToken && firstToken.type === "text" && firstToken.tokens && firstToken.tokens.length > 0) {
					content = [{
						type: "paragraph",
						content: helpers.parseInline(firstToken.tokens)
					}];
					if (token.tokens.length > 1) {
						const additionalContent = parseBlockChildren(token.tokens.slice(1));
						content.push(...additionalContent);
					}
				} else content = parseBlockChildren(token.tokens);
			}
		}
		if (content.length === 0) content = [{
			type: "paragraph",
			content: []
		}];
		return {
			type: "listItem",
			content
		};
	},
	renderMarkdown: (node, h, ctx) => {
		return renderNestedMarkdownContent(node, h, (context) => {
			var _a, _b, _c, _d;
			if (context.parentType === "bulletList") return "- ";
			if (context.parentType === "orderedList") {
				const start = ((_b = (_a = context.meta) == null ? void 0 : _a.parentAttrs) == null ? void 0 : _b.start) || 1;
				return getListMarker((_d = (_c = context.meta) == null ? void 0 : _c.parentAttrs) == null ? void 0 : _d.type, start - 1 + (context.index || 0), ". ");
			}
			return "- ";
		}, ctx);
	},
	addExtensions() {
		return [createBranchingListDeleteKeymap(this.name, [this.options.bulletListTypeName, this.options.orderedListTypeName])];
	},
	addKeyboardShortcuts() {
		return {
			Enter: () => this.editor.commands.splitListItem(this.name),
			Tab: () => this.editor.commands.sinkListItem(this.name),
			"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
		};
	}
});
__export({}, {
	findListItemPos: () => findListItemPos,
	getNextListDepth: () => getNextListDepth,
	handleBackspace: () => handleBackspace,
	handleDelete: () => handleDelete,
	handleTab: () => handleTab,
	hasListBefore: () => hasListBefore,
	hasListItemAfter: () => hasListItemAfter,
	hasListItemBefore: () => hasListItemBefore,
	listItemHasSubList: () => listItemHasSubList,
	nextListIsDeeper: () => nextListIsDeeper,
	nextListIsHigher: () => nextListIsHigher
});
var findListItemPos = (typeOrName, state) => {
	const { $from } = state.selection;
	const nodeType = getNodeType(typeOrName, state.schema);
	let currentNode = null;
	let currentDepth = $from.depth;
	let currentPos = $from.pos;
	let targetDepth = null;
	while (currentDepth > 0 && targetDepth === null) {
		currentNode = $from.node(currentDepth);
		if (currentNode.type === nodeType) targetDepth = currentDepth;
		else {
			currentDepth -= 1;
			currentPos -= 1;
		}
	}
	if (targetDepth === null) return null;
	return {
		$pos: state.doc.resolve(currentPos),
		depth: targetDepth
	};
};
var getNextListDepth = (typeOrName, state) => {
	const listItemPos = findListItemPos(typeOrName, state);
	if (!listItemPos) return false;
	const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4);
	return depth;
};
var hasListBefore = (editorState, name, parentListTypes) => {
	const { $anchor } = editorState.selection;
	const previousNodePos = Math.max(0, $anchor.pos - 2);
	const previousNode = editorState.doc.resolve(previousNodePos).node();
	if (!previousNode || !parentListTypes.includes(previousNode.type.name)) return false;
	return true;
};
var handleBackspace = (editor, name, parentListTypes) => {
	if (editor.commands.undoInputRule()) return true;
	if (editor.state.selection.from !== editor.state.selection.to) return false;
	if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
		const { $anchor } = editor.state.selection;
		const $listPos = editor.state.doc.resolve($anchor.before() - 1);
		const listDescendants = [];
		$listPos.node().descendants((node, pos) => {
			if (node.type.name === name) listDescendants.push({
				node,
				pos
			});
		});
		const lastItem = listDescendants.at(-1);
		if (!lastItem) return false;
		const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
		return editor.chain().cut({
			from: $anchor.start() - 1,
			to: $anchor.end() + 1
		}, $lastItemPos.end()).joinForward().run();
	}
	if (!isNodeActive(editor.state, name)) return false;
	if (!isAtStartOfNode(editor.state)) return false;
	const { $from } = editor.state.selection;
	const itemDepth = $from.depth - 1;
	if ($from.node(itemDepth).type !== editor.schema.nodes[name] || $from.index(itemDepth) !== 0) return false;
	return editor.chain().liftListItem(name).run();
};
var nextListIsDeeper = (typeOrName, state) => {
	const listDepth = getNextListDepth(typeOrName, state);
	const listItemPos = findListItemPos(typeOrName, state);
	if (!listItemPos || !listDepth) return false;
	if (listDepth > listItemPos.depth) return true;
	return false;
};
var nextListIsHigher = (typeOrName, state) => {
	const listDepth = getNextListDepth(typeOrName, state);
	const listItemPos = findListItemPos(typeOrName, state);
	if (!listItemPos || !listDepth) return false;
	if (listDepth < listItemPos.depth) return true;
	return false;
};
var handleDelete = (editor, name) => {
	if (!isNodeActive(editor.state, name)) return false;
	if (!isAtEndOfNode(editor.state, name)) return false;
	const { selection } = editor.state;
	const { $from, $to } = selection;
	if (!selection.empty && $from.sameParent($to)) return false;
	if (nextListIsDeeper(name, editor.state)) return editor.chain().focus(editor.state.selection.from + 4).lift(name).joinBackward().run();
	if (nextListIsHigher(name, editor.state)) return editor.chain().joinForward().joinBackward().run();
	return editor.commands.joinItemForward();
};
var handleTab = (editor, name, parentListTypes) => {
	const { state } = editor;
	const { selection } = state;
	if (!selection.empty) return false;
	const { $from } = selection;
	if ($from.parentOffset !== 0) return false;
	if (!$from.parent.isTextblock) return false;
	if (isNodeActive(state, name)) return false;
	const previous = getPreviousBlockSibling($from);
	if (!previous || !parentListTypes.includes(previous.type.name)) return false;
	const lastItem = previous.lastChild;
	if (!lastItem || lastItem.type.name !== name) return false;
	const block = $from.parent;
	if (!lastItem.canReplace(lastItem.childCount, lastItem.childCount, Fragment$8.from(block))) return false;
	const blockStart = $from.before();
	const blockEnd = $from.after();
	const insideLastItemEnd = blockStart - 2;
	return editor.commands.command(({ tr, dispatch }) => {
		if (dispatch) {
			tr.delete(blockStart, blockEnd).insert(insideLastItemEnd, Fragment$8.from(block));
			tr.setSelection(TextSelection.create(tr.doc, insideLastItemEnd + 1));
			tr.scrollIntoView();
		}
		return true;
	});
};
var hasListItemAfter = (typeOrName, state) => {
	var _a;
	const { $anchor } = state.selection;
	const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2);
	if ($targetPos.index() === $targetPos.parent.childCount - 1) return false;
	if (((_a = $targetPos.nodeAfter) == null ? void 0 : _a.type.name) !== typeOrName) return false;
	return true;
};
var hasListItemBefore = (typeOrName, state) => {
	var _a;
	const { $anchor } = state.selection;
	const $targetPos = state.doc.resolve($anchor.pos - 2);
	if ($targetPos.index() === 0) return false;
	if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) return false;
	return true;
};
var listItemHasSubList = (typeOrName, state, node) => {
	if (!node) return false;
	const nodeType = getNodeType(typeOrName, state.schema);
	let hasSubList = false;
	node.descendants((child) => {
		if (child.type === nodeType) hasSubList = true;
	});
	return hasSubList;
};
var ListKeymap = Extension.create({
	name: "listKeymap",
	addOptions() {
		return { listTypes: [{
			itemName: "listItem",
			wrapperNames: ["bulletList", "orderedList"]
		}, {
			itemName: "taskItem",
			wrapperNames: ["taskList"]
		}] };
	},
	addKeyboardShortcuts() {
		return {
			Delete: ({ editor }) => {
				let handled = false;
				this.options.listTypes.forEach(({ itemName }) => {
					if (editor.state.schema.nodes[itemName] === void 0) return;
					if (handleDelete(editor, itemName)) handled = true;
				});
				return handled;
			},
			"Mod-Delete": ({ editor }) => {
				let handled = false;
				this.options.listTypes.forEach(({ itemName }) => {
					if (editor.state.schema.nodes[itemName] === void 0) return;
					if (handleDelete(editor, itemName)) handled = true;
				});
				return handled;
			},
			Backspace: ({ editor }) => {
				let handled = false;
				this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
					if (editor.state.schema.nodes[itemName] === void 0) return;
					if (handleBackspace(editor, itemName, wrapperNames)) handled = true;
				});
				return handled;
			},
			"Mod-Backspace": ({ editor }) => {
				let handled = false;
				this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
					if (editor.state.schema.nodes[itemName] === void 0) return;
					if (handleBackspace(editor, itemName, wrapperNames)) handled = true;
				});
				return handled;
			},
			Tab: ({ editor }) => {
				for (const { itemName, wrapperNames } of this.options.listTypes) {
					if (editor.state.schema.nodes[itemName] === void 0) continue;
					if (handleTab(editor, itemName, wrapperNames)) return true;
				}
				return false;
			}
		};
	}
});
var ORDERED_LIST_ITEM_REGEX = new RegExp(`^(\\s*)(${ORDERED_LIST_MARKER_PATTERN})([.)])\\s+(.*)$`);
var INDENTED_LINE_REGEX = /^\s/;
var PARAGRAPH_INTERRUPTERS = {
	heading: /^#{1,6}(?:\s|$)/,
	bulletItem: /^[-+*]\s+/,
	codeFence: /^(?:```|~~~)/,
	blockMath: /^\$\$/,
	thematicBreak: /^(?:(?:-[ \t]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})$/
};
function isOrderedListMarkerLine(line) {
	return ORDERED_LIST_ITEM_REGEX.test(line.trimStart());
}
function isBlockContentLine(line) {
	const trimmedLine = line.trimStart();
	return PARAGRAPH_INTERRUPTERS.bulletItem.test(trimmedLine) || isOrderedListMarkerLine(trimmedLine) || PARAGRAPH_INTERRUPTERS.heading.test(trimmedLine) || PARAGRAPH_INTERRUPTERS.thematicBreak.test(trimmedLine) && !trimmedLine.startsWith("-") || /^>\s?/.test(trimmedLine) || PARAGRAPH_INTERRUPTERS.codeFence.test(trimmedLine) || PARAGRAPH_INTERRUPTERS.blockMath.test(trimmedLine);
}
function interruptsLazyContinuation(line) {
	return Object.values(PARAGRAPH_INTERRUPTERS).some((pattern) => pattern.test(line));
}
function splitItemContent(contentLines) {
	const paragraphLines = [];
	const blockLines = [];
	let reachedBlockBoundary = false;
	contentLines.forEach((line) => {
		if (reachedBlockBoundary) {
			blockLines.push(line);
			return;
		}
		if (line.trim() === "") {
			reachedBlockBoundary = true;
			blockLines.push(line);
			return;
		}
		if (paragraphLines.length > 0 && isBlockContentLine(line)) {
			reachedBlockBoundary = true;
			blockLines.push(line);
			return;
		}
		paragraphLines.push(line);
	});
	return {
		paragraphLines,
		blockLines
	};
}
function collectOrderedListItems(lines) {
	const listItems = [];
	let currentLineIndex = 0;
	let consumed = 0;
	while (currentLineIndex < lines.length) {
		const line = lines[currentLineIndex];
		const match = line.match(ORDERED_LIST_ITEM_REGEX);
		if (!match) break;
		const [, indent, marker, _separator, content] = match;
		const indentLevel = indent.length;
		const number = parseInt(marker, 10);
		const markerType = isNaN(number) ? detectMarkerType(marker) : void 0;
		const itemNumber = isNaN(number) ? markerToStart(marker) : number;
		const itemContentLines = [content];
		let nextLineIndex = currentLineIndex + 1;
		const itemLines = [line];
		let sawBlankLine = false;
		while (nextLineIndex < lines.length) {
			const nextLine = lines[nextLineIndex];
			if (nextLine.match(ORDERED_LIST_ITEM_REGEX)) break;
			if (nextLine.trim() === "") {
				itemLines.push(nextLine);
				itemContentLines.push("");
				sawBlankLine = true;
				nextLineIndex += 1;
			} else if (nextLine.match(INDENTED_LINE_REGEX)) {
				const leadingWhitespace = nextLine.length - nextLine.trimStart().length;
				const contentIndent = indentLevel + marker.length + 1;
				itemLines.push(nextLine);
				itemContentLines.push(nextLine.slice(Math.min(leadingWhitespace, contentIndent)));
				nextLineIndex += 1;
			} else {
				if (sawBlankLine || interruptsLazyContinuation(nextLine)) break;
				itemLines.push(nextLine);
				itemContentLines.push(nextLine);
				nextLineIndex += 1;
			}
		}
		listItems.push({
			indent: indentLevel,
			number: itemNumber,
			type: markerType,
			content: itemContentLines.join("\n").trim(),
			contentLines: itemContentLines,
			raw: itemLines.join("\n")
		});
		consumed = nextLineIndex;
		currentLineIndex = nextLineIndex;
	}
	return [listItems, consumed];
}
var PLAIN_TEXT_ORDERED_LIST_LINE_REGEX = new RegExp(`^(${ORDERED_LIST_MARKER_PATTERN})([.)])\\s+(.+)$`);
function parsePlainTextOrderedListPaste(text) {
	const lines = text.split("\n").filter((l) => l.trim().length > 0);
	if (lines.length === 0) return null;
	const parsedItems = [];
	for (const line of lines) {
		const match = line.trim().match(PLAIN_TEXT_ORDERED_LIST_LINE_REGEX);
		if (!match) return null;
		parsedItems.push({
			marker: match[1],
			content: match[3]
		});
	}
	if (!areOrderedListMarkersSequential(parsedItems.map((item) => item.marker))) return null;
	return {
		type: "orderedList",
		attrs: buildOrderedListAttrsFromMarker(parsedItems[0].marker),
		content: parsedItems.map((item) => ({
			type: "listItem",
			content: [{
				type: "paragraph",
				content: [{
					type: "text",
					text: item.content
				}]
			}]
		}))
	};
}
function buildNestedStructure(items, baseIndent, lexer) {
	const result = [];
	let currentIndex = 0;
	while (currentIndex < items.length) {
		const item = items[currentIndex];
		if (item.indent === baseIndent) {
			const { paragraphLines, blockLines } = splitItemContent(item.contentLines);
			const mainText = paragraphLines.join("\n").trim();
			const tokens = [];
			if (mainText) tokens.push({
				type: "paragraph",
				raw: mainText,
				tokens: lexer.inlineTokens(mainText)
			});
			const additionalContent = blockLines.join("\n").trim();
			if (additionalContent) {
				const blockTokens = lexer.blockTokens(additionalContent);
				tokens.push(...blockTokens);
			}
			let lookAheadIndex = currentIndex + 1;
			const nestedItems = [];
			while (lookAheadIndex < items.length && items[lookAheadIndex].indent > baseIndent) {
				nestedItems.push(items[lookAheadIndex]);
				lookAheadIndex += 1;
			}
			if (nestedItems.length > 0) {
				const nestedListItems = buildNestedStructure(nestedItems, Math.min(...nestedItems.map((nestedItem) => nestedItem.indent)), lexer);
				tokens.push({
					type: "list",
					ordered: true,
					start: nestedItems[0].number,
					typeMarker: nestedItems[0].type,
					items: nestedListItems,
					raw: nestedItems.map((nestedItem) => nestedItem.raw).join("\n")
				});
			}
			result.push({
				type: "list_item",
				raw: item.raw,
				tokens
			});
			currentIndex = lookAheadIndex;
		} else currentIndex += 1;
	}
	return result;
}
function parseListItems(items, helpers) {
	return items.map((item) => {
		if (item.type !== "list_item") return helpers.parseChildren([item])[0];
		const content = [];
		if (item.tokens && item.tokens.length > 0) item.tokens.forEach((itemToken) => {
			if (itemToken.type === "paragraph" || itemToken.type === "list" || itemToken.type === "blockquote" || itemToken.type === "code") content.push(...helpers.parseChildren([itemToken]));
			else if (itemToken.type === "text" && itemToken.tokens) {
				const inlineContent = helpers.parseChildren([itemToken]);
				content.push({
					type: "paragraph",
					content: inlineContent
				});
			} else {
				const parsed = helpers.parseChildren([itemToken]);
				if (parsed.length > 0) content.push(...parsed);
			}
		});
		return {
			type: "listItem",
			content
		};
	});
}
var ListItemName2 = "listItem";
var TextStyleName2 = "textStyle";
var orderedListInputRegex = /^(\d+)\.\s$/;
function cssListStyleTypeToHtmlType(style) {
	const match = style.match(/list-style-type\s*:\s*([^;]+)/i);
	if (!match) return null;
	switch (match[1].trim().toLowerCase()) {
		case "upper-roman": return "I";
		case "lower-roman": return "i";
		case "upper-alpha":
		case "upper-latin": return "A";
		case "lower-alpha":
		case "lower-latin": return "a";
		default: return null;
	}
}
var OrderedList = Node3.create({
	name: "orderedList",
	addOptions() {
		return {
			itemTypeName: "listItem",
			HTMLAttributes: {},
			keepMarks: false,
			keepAttributes: false
		};
	},
	group: "block list",
	content() {
		return `${this.options.itemTypeName}+`;
	},
	addAttributes() {
		return {
			start: {
				default: 1,
				parseHTML: (element) => {
					return element.hasAttribute("start") ? parseInt(element.getAttribute("start") || "", 10) : 1;
				}
			},
			type: {
				default: null,
				parseHTML: (element) => {
					const htmlType = element.getAttribute("type");
					if (htmlType) return htmlType;
					const style = element.getAttribute("style");
					if (style) {
						const mappedFromOl = cssListStyleTypeToHtmlType(style);
						if (mappedFromOl) return mappedFromOl;
					}
					const firstLi = element.querySelector("li");
					if (firstLi) {
						const liStyle = firstLi.getAttribute("style");
						if (liStyle) {
							const mappedFromLi = cssListStyleTypeToHtmlType(liStyle);
							if (mappedFromLi) return mappedFromLi;
						}
					}
					return null;
				}
			}
		};
	},
	parseHTML() {
		return [{ tag: "ol" }];
	},
	renderHTML({ HTMLAttributes }) {
		const { start, type, ...attributesWithoutType } = HTMLAttributes;
		const attrs = mergeAttributes(this.options.HTMLAttributes, attributesWithoutType);
		if (start !== 1) attrs.start = start;
		if (type && type !== "1") attrs.type = type;
		return [
			"ol",
			attrs,
			0
		];
	},
	markdownTokenName: "list",
	parseMarkdown: (token, helpers) => {
		if (token.type !== "list" || !token.ordered) return [];
		const startValue = token.start || 1;
		const typeValue = token.typeMarker;
		const content = token.items ? parseListItems(token.items, helpers) : [];
		const attrs = {};
		if (startValue !== 1) attrs.start = startValue;
		if (typeValue) attrs.type = typeValue;
		if (Object.keys(attrs).length > 0) return {
			type: "orderedList",
			attrs,
			content
		};
		return {
			type: "orderedList",
			content
		};
	},
	renderMarkdown: (node, h) => {
		if (!node.content) return "";
		return h.renderChildren(node.content, "\n");
	},
	markdownTokenizer: {
		name: "orderedList",
		level: "block",
		start: () => -1,
		tokenize: (src, _tokens, lexer) => {
			var _a, _b;
			const lines = src.split("\n");
			const [listItems, consumed] = collectOrderedListItems(lines);
			if (listItems.length === 0) return;
			const items = buildNestedStructure(listItems, listItems[0].indent, lexer);
			if (items.length === 0) return;
			return {
				type: "list",
				ordered: true,
				start: ((_a = listItems[0]) == null ? void 0 : _a.number) || 1,
				typeMarker: (_b = listItems[0]) == null ? void 0 : _b.type,
				items,
				raw: lines.slice(0, consumed).join("\n")
			};
		}
	},
	markdownOptions: { indentsContent: true },
	addCommands() {
		return { toggleOrderedList: () => ({ commands, chain }) => {
			if (this.options.keepAttributes) return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName2, this.editor.getAttributes(TextStyleName2)).run();
			return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
		} };
	},
	addKeyboardShortcuts() {
		return { "Mod-Shift-7": () => this.editor.commands.toggleOrderedList() };
	},
	addProseMirrorPlugins() {
		return [new Plugin({ props: { handlePaste: (view, event) => {
			var _a, _b;
			const html = (_a = event.clipboardData) == null ? void 0 : _a.getData("text/html");
			if (html == null ? void 0 : html.trim()) return false;
			const text = (_b = event.clipboardData) == null ? void 0 : _b.getData("text/plain");
			if (!text) return false;
			const orderedListContent = parsePlainTextOrderedListPaste(text);
			if (!orderedListContent) return false;
			try {
				const orderedListNode = view.state.schema.nodeFromJSON(orderedListContent);
				const tr = view.state.tr.replaceSelectionWith(orderedListNode);
				view.dispatch(tr);
				return true;
			} catch {
				return false;
			}
		} } })];
	},
	addInputRules() {
		const joinPredicate = (match, node) => {
			return (!node.attrs.type || node.attrs.type === "1") && node.childCount + node.attrs.start === +match[1];
		};
		let inputRule = wrappingInputRule({
			find: orderedListInputRegex,
			type: this.type,
			getAttributes: (match) => ({ start: +match[1] }),
			joinPredicate
		});
		if (this.options.keepMarks || this.options.keepAttributes) inputRule = wrappingInputRule({
			find: orderedListInputRegex,
			type: this.type,
			keepMarks: this.options.keepMarks,
			keepAttributes: this.options.keepAttributes,
			getAttributes: (match) => ({
				start: +match[1],
				...this.editor.getAttributes(TextStyleName2)
			}),
			joinPredicate,
			editor: this.editor
		});
		return [inputRule];
	}
});
var inputRegex$1 = /^\s*(\[([( |x])?\])\s$/;
var visuallyHiddenStyle = "position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0";
var getCheckboxLabel = (node, checked, a11y) => {
	var _a;
	return ((_a = a11y == null ? void 0 : a11y.checkboxLabel) == null ? void 0 : _a.call(a11y, node, checked)) || `Task item checkbox for ${node.textContent || "empty task item"}`;
};
var TaskItem = Node3.create({
	name: "taskItem",
	addOptions() {
		return {
			nested: false,
			HTMLAttributes: {},
			taskListTypeName: "taskList",
			a11y: void 0
		};
	},
	content() {
		return this.options.nested ? "paragraph block*" : "paragraph+";
	},
	defining: true,
	addAttributes() {
		return { checked: {
			default: false,
			keepOnSplit: false,
			parseHTML: (element) => {
				const dataChecked = element.getAttribute("data-checked");
				return dataChecked === "" || dataChecked === "true";
			},
			renderHTML: (attributes) => ({ "data-checked": attributes.checked })
		} };
	},
	parseHTML() {
		return [{
			tag: `li[data-type="${this.name}"]`,
			priority: 51,
			contentElement: (element) => {
				var _a;
				return (_a = element.querySelector("div")) != null ? _a : element;
			}
		}];
	},
	renderHTML({ node, HTMLAttributes }) {
		return [
			"li",
			mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }),
			[
				"label",
				["input", {
					type: "checkbox",
					checked: node.attrs.checked ? "checked" : null
				}],
				["span"]
			],
			["div", 0]
		];
	},
	parseMarkdown: (token, h) => {
		const content = [];
		if (token.tokens && token.tokens.length > 0) content.push(h.createNode("paragraph", {}, h.parseInline(token.tokens)));
		else if (token.text) content.push(h.createNode("paragraph", {}, [h.createNode("text", { text: token.text })]));
		else content.push(h.createNode("paragraph", {}, []));
		if (token.nestedTokens && token.nestedTokens.length > 0) {
			const nestedContent = h.parseChildren(token.nestedTokens);
			content.push(...nestedContent);
		}
		return h.createNode("taskItem", { checked: token.checked || false }, content);
	},
	renderMarkdown: (node, h) => {
		var _a;
		return renderNestedMarkdownContent(node, h, `- [${((_a = node.attrs) == null ? void 0 : _a.checked) ? "x" : " "}] `);
	},
	addExtensions() {
		if (!this.options.nested) return [];
		return [createBranchingListDeleteKeymap(this.name, [this.options.taskListTypeName])];
	},
	addKeyboardShortcuts() {
		const shortcuts = {
			Enter: () => this.editor.commands.splitListItem(this.name),
			"Shift-Tab": () => this.editor.commands.liftListItem(this.name)
		};
		if (!this.options.nested) return shortcuts;
		return {
			...shortcuts,
			Tab: () => this.editor.commands.sinkListItem(this.name)
		};
	},
	addNodeView() {
		return ({ node, HTMLAttributes, getPos, editor }) => {
			const listItem = document.createElement("li");
			const checkboxWrapper = document.createElement("label");
			const checkboxStyler = document.createElement("span");
			const checkbox = document.createElement("input");
			const content = document.createElement("div");
			checkboxStyler.style.cssText = visuallyHiddenStyle;
			const updateA11Y = (currentNode) => {
				const label = getCheckboxLabel(currentNode, currentNode.attrs.checked, this.options.a11y);
				checkbox.setAttribute("aria-label", label);
				checkboxStyler.textContent = label;
			};
			updateA11Y(node);
			checkboxWrapper.contentEditable = "false";
			checkbox.type = "checkbox";
			checkbox.addEventListener("mousedown", (event) => event.preventDefault());
			checkbox.addEventListener("change", (event) => {
				if (!editor.isEditable && !this.options.onReadOnlyChecked) {
					checkbox.checked = !checkbox.checked;
					return;
				}
				const { checked } = event.target;
				if (editor.isEditable && typeof getPos === "function") editor.chain().focus(void 0, { scrollIntoView: false }).command(({ tr }) => {
					const position = getPos();
					if (typeof position !== "number") return false;
					const currentNode = tr.doc.nodeAt(position);
					tr.setNodeMarkup(position, void 0, {
						...currentNode == null ? void 0 : currentNode.attrs,
						checked
					});
					return true;
				}).run();
				if (!editor.isEditable && this.options.onReadOnlyChecked) {
					if (!this.options.onReadOnlyChecked(node, checked)) checkbox.checked = !checkbox.checked;
				}
			});
			Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
				listItem.setAttribute(key, value);
			});
			listItem.dataset.checked = node.attrs.checked;
			checkbox.checked = node.attrs.checked;
			checkboxWrapper.append(checkbox, checkboxStyler);
			listItem.append(checkboxWrapper, content);
			Object.entries(HTMLAttributes).forEach(([key, value]) => {
				listItem.setAttribute(key, value);
			});
			let prevRenderedAttributeKeys = new Set(Object.keys(HTMLAttributes));
			return {
				dom: listItem,
				contentDOM: content,
				update: (updatedNode) => {
					if (updatedNode.type !== this.type) return false;
					listItem.dataset.checked = updatedNode.attrs.checked;
					checkbox.checked = updatedNode.attrs.checked;
					updateA11Y(updatedNode);
					const extensionAttributes = editor.extensionManager.attributes;
					const newHTMLAttributes = getRenderedAttributes(updatedNode, extensionAttributes);
					const newKeys = new Set(Object.keys(newHTMLAttributes));
					const staticAttrs = this.options.HTMLAttributes;
					prevRenderedAttributeKeys.forEach((key) => {
						if (!newKeys.has(key)) {
							if (key in staticAttrs) listItem.setAttribute(key, staticAttrs[key]);
							else listItem.removeAttribute(key);
						}
					});
					Object.entries(newHTMLAttributes).forEach(([key, value]) => {
						if (value === null || value === void 0) {
							if (key in staticAttrs) listItem.setAttribute(key, staticAttrs[key]);
							else listItem.removeAttribute(key);
						} else listItem.setAttribute(key, value);
					});
					prevRenderedAttributeKeys = newKeys;
					return true;
				}
			};
		};
	},
	addInputRules() {
		return [wrappingInputRule({
			find: inputRegex$1,
			type: this.type,
			getAttributes: (match) => ({ checked: match[match.length - 1] === "x" })
		})];
	}
});
var TaskList = Node3.create({
	name: "taskList",
	addOptions() {
		return {
			itemTypeName: "taskItem",
			HTMLAttributes: {}
		};
	},
	group: "block list",
	content() {
		return `${this.options.itemTypeName}+`;
	},
	parseHTML() {
		return [{
			tag: `ul[data-type="${this.name}"]`,
			priority: 51
		}];
	},
	renderHTML({ HTMLAttributes }) {
		return [
			"ul",
			mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }),
			0
		];
	},
	parseMarkdown: (token, h) => {
		return h.createNode("taskList", {}, h.parseChildren(token.items || []));
	},
	renderMarkdown: (node, h) => {
		if (!node.content) return "";
		return h.renderChildren(node.content, "\n");
	},
	markdownTokenizer: {
		name: "taskList",
		level: "block",
		start(src) {
			var _a;
			const index = (_a = src.match(/^\s*[-+*]\s+\[([ xX])\]\s+/)) == null ? void 0 : _a.index;
			return index !== void 0 ? index : -1;
		},
		tokenize(src, tokens, lexer) {
			const parseTaskListContent = (content) => {
				const nestedResult = parseIndentedBlocks(content, {
					itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
					extractItemData: (match) => ({
						indentLevel: match[1].length,
						mainContent: match[4],
						checked: match[3].toLowerCase() === "x"
					}),
					createToken: (data, nestedTokens) => ({
						type: "taskItem",
						raw: "",
						mainContent: data.mainContent,
						indentLevel: data.indentLevel,
						checked: data.checked,
						text: data.mainContent,
						tokens: lexer.inlineTokens(data.mainContent),
						nestedTokens
					}),
					customNestedParser: parseTaskListContent
				}, lexer);
				if (nestedResult) {
					const taskListToken = {
						type: "taskList",
						raw: nestedResult.raw,
						items: nestedResult.items
					};
					const remainder = content.slice(nestedResult.raw.length);
					if (remainder.trim()) return [taskListToken, ...lexer.blockTokens(remainder)];
					return [taskListToken];
				}
				return lexer.blockTokens(content);
			};
			const result = parseIndentedBlocks(src, {
				itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,
				extractItemData: (match) => ({
					indentLevel: match[1].length,
					mainContent: match[4],
					checked: match[3].toLowerCase() === "x"
				}),
				createToken: (data, nestedTokens) => ({
					type: "taskItem",
					raw: "",
					mainContent: data.mainContent,
					indentLevel: data.indentLevel,
					checked: data.checked,
					text: data.mainContent,
					tokens: lexer.inlineTokens(data.mainContent),
					nestedTokens
				}),
				customNestedParser: parseTaskListContent
			}, lexer);
			if (!result) return;
			return {
				type: "taskList",
				raw: result.raw,
				items: result.items
			};
		}
	},
	markdownOptions: { indentsContent: true },
	addCommands() {
		return { toggleTaskList: () => ({ commands }) => {
			return commands.toggleList(this.name, this.options.itemTypeName);
		} };
	},
	addKeyboardShortcuts() {
		return { "Mod-Shift-9": () => this.editor.commands.toggleTaskList() };
	}
});
Extension.create({
	name: "listKit",
	addExtensions() {
		const extensions = [];
		if (this.options.bulletList !== false) extensions.push(BulletList.configure(this.options.bulletList));
		if (this.options.listItem !== false) extensions.push(ListItem.configure(this.options.listItem));
		if (this.options.listKeymap !== false) extensions.push(ListKeymap.configure(this.options.listKeymap));
		if (this.options.orderedList !== false) extensions.push(OrderedList.configure(this.options.orderedList));
		if (this.options.taskItem !== false) extensions.push(TaskItem.configure(this.options.taskItem));
		if (this.options.taskList !== false) extensions.push(TaskList.configure(this.options.taskList));
		return extensions;
	}
});
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-document@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2_/node_modules/@tiptap/extension-document/dist/index.js
var Document = Node3.create({
	name: "doc",
	topNode: true,
	content: "block+",
	renderMarkdown: (node, h) => {
		if (!node.content) return "";
		return h.renderChildren(node.content, "\n\n");
	}
});
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-heading@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2_/node_modules/@tiptap/extension-heading/dist/index.js
var Heading = Node3.create({
	name: "heading",
	addOptions() {
		return {
			levels: [
				1,
				2,
				3,
				4,
				5,
				6
			],
			HTMLAttributes: {}
		};
	},
	content: "inline*",
	group: "block",
	defining: true,
	addAttributes() {
		return { level: {
			default: 1,
			rendered: false
		} };
	},
	parseHTML() {
		return this.options.levels.map((level) => ({
			tag: `h${level}`,
			attrs: { level }
		}));
	},
	renderHTML({ node, HTMLAttributes }) {
		return [
			`h${this.options.levels.includes(node.attrs.level) ? node.attrs.level : this.options.levels[0]}`,
			mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
			0
		];
	},
	parseMarkdown: (token, helpers) => {
		return helpers.createNode("heading", { level: token.depth || 1 }, helpers.parseInline(token.tokens || []));
	},
	renderMarkdown: (node, h) => {
		var _a;
		const level = ((_a = node.attrs) == null ? void 0 : _a.level) ? parseInt(node.attrs.level, 10) : 1;
		const headingChars = "#".repeat(level);
		if (!node.content) return "";
		return `${headingChars} ${h.renderChildren(node.content)}`;
	},
	addCommands() {
		return {
			setHeading: (attributes) => ({ commands }) => {
				if (!this.options.levels.includes(attributes.level)) return false;
				return commands.setNode(this.name, attributes);
			},
			toggleHeading: (attributes) => ({ commands }) => {
				if (!this.options.levels.includes(attributes.level)) return false;
				return commands.toggleNode(this.name, "paragraph", attributes);
			}
		};
	},
	addKeyboardShortcuts() {
		return this.options.levels.reduce((items, level) => ({
			...items,
			[`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level })
		}), {});
	},
	addInputRules() {
		return this.options.levels.map((level) => {
			return textblockTypeInputRule({
				find: new RegExp(`^(#{${Math.min(...this.options.levels)},${level}})\\s$`),
				type: this.type,
				getAttributes: { level }
			});
		});
	}
});
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-dropcursor@1.8.2/node_modules/prosemirror-dropcursor/dist/index.js
/**
Create a plugin that, when added to a ProseMirror instance,
causes a decoration to show up at the drop position when something
is dragged over the editor.

Nodes may add a `disableDropCursor` property to their spec to
control the showing of a drop cursor inside them. This may be a
boolean or a function, which will be called with a view and a
position, and should return a boolean.
*/
function dropCursor(options = {}) {
	return new Plugin({ view(editorView) {
		return new DropCursorView(editorView, options);
	} });
}
var DropCursorView = class {
	constructor(editorView, options) {
		var _a;
		this.editorView = editorView;
		this.cursorPos = null;
		this.element = null;
		this.timeout = -1;
		this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1;
		this.color = options.color === false ? void 0 : options.color || "black";
		this.class = options.class;
		this.handlers = [
			"dragover",
			"dragend",
			"drop",
			"dragleave"
		].map((name) => {
			let handler = (e) => {
				this[name](e);
			};
			editorView.dom.addEventListener(name, handler);
			return {
				name,
				handler
			};
		});
	}
	destroy() {
		this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler));
	}
	update(editorView, prevState) {
		if (this.cursorPos != null && prevState.doc != editorView.state.doc) {
			if (this.cursorPos > editorView.state.doc.content.size) this.setCursor(null);
			else this.updateOverlay();
		}
	}
	setCursor(pos) {
		if (pos == this.cursorPos) return;
		this.cursorPos = pos;
		if (pos == null) {
			this.element.parentNode.removeChild(this.element);
			this.element = null;
		} else this.updateOverlay();
	}
	updateOverlay() {
		let $pos = this.editorView.state.doc.resolve(this.cursorPos);
		let isBlock = !$pos.parent.inlineContent, rect;
		let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect();
		let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight;
		if (isBlock) {
			let before = $pos.nodeBefore, after = $pos.nodeAfter;
			if (before || after) {
				let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0));
				if (node) {
					let nodeRect = node.getBoundingClientRect();
					let top = before ? nodeRect.bottom : nodeRect.top;
					if (before && after) top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2;
					let halfWidth = this.width / 2 * scaleY;
					rect = {
						left: nodeRect.left,
						right: nodeRect.right,
						top: top - halfWidth,
						bottom: top + halfWidth
					};
				}
			}
		}
		if (!rect) {
			let coords = this.editorView.coordsAtPos(this.cursorPos);
			let halfWidth = this.width / 2 * scaleX;
			rect = {
				left: coords.left - halfWidth,
				right: coords.left + halfWidth,
				top: coords.top,
				bottom: coords.bottom
			};
		}
		let parent = this.editorView.dom.offsetParent;
		if (!this.element) {
			this.element = parent.appendChild(document.createElement("div"));
			if (this.class) this.element.className = this.class;
			this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;";
			if (this.color) this.element.style.backgroundColor = this.color;
		}
		this.element.classList.toggle("prosemirror-dropcursor-block", isBlock);
		this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock);
		let parentLeft, parentTop;
		if (!parent || parent == document.body && getComputedStyle(parent).position == "static") {
			parentLeft = -pageXOffset;
			parentTop = -pageYOffset;
		} else {
			let rect = parent.getBoundingClientRect();
			let parentScaleX = rect.width / parent.offsetWidth, parentScaleY = rect.height / parent.offsetHeight;
			parentLeft = rect.left - parent.scrollLeft * parentScaleX;
			parentTop = rect.top - parent.scrollTop * parentScaleY;
		}
		this.element.style.left = (rect.left - parentLeft) / scaleX + "px";
		this.element.style.top = (rect.top - parentTop) / scaleY + "px";
		this.element.style.width = (rect.right - rect.left) / scaleX + "px";
		this.element.style.height = (rect.bottom - rect.top) / scaleY + "px";
	}
	scheduleRemoval(timeout) {
		clearTimeout(this.timeout);
		this.timeout = setTimeout(() => this.setCursor(null), timeout);
	}
	dragover(event) {
		if (!this.editorView.editable) return;
		let pos = this.editorView.posAtCoords({
			left: event.clientX,
			top: event.clientY
		});
		let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside);
		let disableDropCursor = node && node.type.spec.disableDropCursor;
		let disabled = typeof disableDropCursor == "function" ? disableDropCursor(this.editorView, pos, event) : disableDropCursor;
		if (pos && !disabled) {
			let target = pos.pos;
			if (this.editorView.dragging && this.editorView.dragging.slice) {
				let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice);
				if (point != null) target = point;
			}
			this.setCursor(target);
			this.scheduleRemoval(5e3);
		}
	}
	dragend() {
		this.scheduleRemoval(20);
	}
	drop() {
		this.scheduleRemoval(20);
	}
	dragleave(event) {
		if (!this.editorView.dom.contains(event.relatedTarget)) this.setCursor(null);
	}
};
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-gapcursor@1.4.1/node_modules/prosemirror-gapcursor/dist/index.js
/**
Gap cursor selections are represented using this class. Its
`$anchor` and `$head` properties both point at the cursor position.
*/
var GapCursor = class GapCursor extends Selection$1 {
	/**
	Create a gap cursor.
	*/
	constructor($pos) {
		super($pos, $pos);
	}
	map(doc, mapping) {
		let $pos = doc.resolve(mapping.map(this.head));
		return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$1.near($pos);
	}
	content() {
		return Slice.empty;
	}
	eq(other) {
		return other instanceof GapCursor && other.head == this.head;
	}
	toJSON() {
		return {
			type: "gapcursor",
			pos: this.head
		};
	}
	/**
	@internal
	*/
	static fromJSON(doc, json) {
		if (typeof json.pos != "number") throw new RangeError("Invalid input for GapCursor.fromJSON");
		return new GapCursor(doc.resolve(json.pos));
	}
	/**
	@internal
	*/
	getBookmark() {
		return new GapBookmark(this.anchor);
	}
	/**
	@internal
	*/
	static valid($pos) {
		let parent = $pos.parent;
		if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos)) return false;
		let override = parent.type.spec.allowGapCursor;
		if (override != null) return override;
		let deflt = parent.contentMatchAt($pos.index()).defaultType;
		return deflt && deflt.isTextblock;
	}
	/**
	@internal
	*/
	static findGapCursorFrom($pos, dir, mustMove = false) {
		search: for (;;) {
			if (!mustMove && GapCursor.valid($pos)) return $pos;
			let pos = $pos.pos, next = null;
			for (let d = $pos.depth;; d--) {
				let parent = $pos.node(d);
				if (dir > 0 ? $pos.indexAfter(d) < parent.childCount : $pos.index(d) > 0) {
					next = parent.child(dir > 0 ? $pos.indexAfter(d) : $pos.index(d) - 1);
					break;
				} else if (d == 0) return null;
				pos += dir;
				let $cur = $pos.doc.resolve(pos);
				if (GapCursor.valid($cur)) return $cur;
			}
			for (;;) {
				let inside = dir > 0 ? next.firstChild : next.lastChild;
				if (!inside) {
					if (next.isAtom && !next.isText && !NodeSelection.isSelectable(next)) {
						$pos = $pos.doc.resolve(pos + next.nodeSize * dir);
						mustMove = false;
						continue search;
					}
					break;
				}
				next = inside;
				pos += dir;
				let $cur = $pos.doc.resolve(pos);
				if (GapCursor.valid($cur)) return $cur;
			}
			return null;
		}
	}
};
GapCursor.prototype.visible = false;
GapCursor.findFrom = GapCursor.findGapCursorFrom;
Selection$1.jsonID("gapcursor", GapCursor);
var GapBookmark = class GapBookmark {
	constructor(pos) {
		this.pos = pos;
	}
	map(mapping) {
		return new GapBookmark(mapping.map(this.pos));
	}
	resolve(doc) {
		let $pos = doc.resolve(this.pos);
		return GapCursor.valid($pos) ? new GapCursor($pos) : Selection$1.near($pos);
	}
};
function needsGap(type) {
	return type.isAtom || type.spec.isolating || type.spec.createGapCursor;
}
function closedBefore($pos) {
	for (let d = $pos.depth; d >= 0; d--) {
		let index = $pos.index(d), parent = $pos.node(d);
		if (index == 0) {
			if (parent.type.spec.isolating) return true;
			continue;
		}
		for (let before = parent.child(index - 1);; before = before.lastChild) {
			if (before.childCount == 0 && !before.inlineContent || needsGap(before.type)) return true;
			if (before.inlineContent) return false;
		}
	}
	return true;
}
function closedAfter($pos) {
	for (let d = $pos.depth; d >= 0; d--) {
		let index = $pos.indexAfter(d), parent = $pos.node(d);
		if (index == parent.childCount) {
			if (parent.type.spec.isolating) return true;
			continue;
		}
		for (let after = parent.child(index);; after = after.firstChild) {
			if (after.childCount == 0 && !after.inlineContent || needsGap(after.type)) return true;
			if (after.inlineContent) return false;
		}
	}
	return true;
}
/**
Create a gap cursor plugin. When enabled, this will capture clicks
near and arrow-key-motion past places that don't have a normally
selectable position nearby, and create a gap cursor selection for
them. The cursor is drawn as an element with class
`ProseMirror-gapcursor`. You can either include
`style/gapcursor.css` from the package's directory or add your own
styles to make it visible.
*/
function gapCursor() {
	return new Plugin({ props: {
		decorations: drawGapCursor,
		createSelectionBetween(_view, $anchor, $head) {
			return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null;
		},
		handleClick,
		handleKeyDown,
		handleDOMEvents: { beforeinput }
	} });
}
var handleKeyDown = keydownHandler({
	"ArrowLeft": arrow("horiz", -1),
	"ArrowRight": arrow("horiz", 1),
	"ArrowUp": arrow("vert", -1),
	"ArrowDown": arrow("vert", 1)
});
function arrow(axis, dir) {
	const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left";
	return function(state, dispatch, view) {
		let sel = state.selection;
		let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty;
		if (sel instanceof TextSelection) {
			if (!view.endOfTextblock(dirStr) || $start.depth == 0) return false;
			mustMove = false;
			$start = state.doc.resolve(dir > 0 ? $start.after() : $start.before());
		}
		let $found = GapCursor.findGapCursorFrom($start, dir, mustMove);
		if (!$found) return false;
		if (dispatch) dispatch(state.tr.setSelection(new GapCursor($found)));
		return true;
	};
}
function handleClick(view, pos, event) {
	if (!view || !view.editable) return false;
	let $pos = view.state.doc.resolve(pos);
	if (!GapCursor.valid($pos)) return false;
	let clickPos = view.posAtCoords({
		left: event.clientX,
		top: event.clientY
	});
	if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside))) return false;
	view.dispatch(view.state.tr.setSelection(new GapCursor($pos)));
	return true;
}
function beforeinput(view, event) {
	if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor)) return false;
	let { $from } = view.state.selection;
	let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text);
	if (!insert) return false;
	let frag = Fragment$8.empty;
	for (let i = insert.length - 1; i >= 0; i--) frag = Fragment$8.from(insert[i].createAndFill(null, frag));
	let tr = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0));
	tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + 1)));
	view.dispatch(tr);
	return false;
}
function drawGapCursor(state) {
	if (!(state.selection instanceof GapCursor)) return null;
	let node = document.createElement("div");
	node.className = "ProseMirror-gapcursor";
	return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]);
}
//#endregion
//#region ../../node_modules/.pnpm/rope-sequence@1.3.4/node_modules/rope-sequence/dist/index.js
var GOOD_LEAF_SIZE = 200;
var RopeSequence = function RopeSequence() {};
RopeSequence.prototype.append = function append(other) {
	if (!other.length) return this;
	other = RopeSequence.from(other);
	return !this.length && other || other.length < GOOD_LEAF_SIZE && this.leafAppend(other) || this.length < GOOD_LEAF_SIZE && other.leafPrepend(this) || this.appendInner(other);
};
RopeSequence.prototype.prepend = function prepend(other) {
	if (!other.length) return this;
	return RopeSequence.from(other).append(this);
};
RopeSequence.prototype.appendInner = function appendInner(other) {
	return new Append(this, other);
};
RopeSequence.prototype.slice = function slice(from, to) {
	if (from === void 0) from = 0;
	if (to === void 0) to = this.length;
	if (from >= to) return RopeSequence.empty;
	return this.sliceInner(Math.max(0, from), Math.min(this.length, to));
};
RopeSequence.prototype.get = function get(i) {
	if (i < 0 || i >= this.length) return;
	return this.getInner(i);
};
RopeSequence.prototype.forEach = function forEach(f, from, to) {
	if (from === void 0) from = 0;
	if (to === void 0) to = this.length;
	if (from <= to) this.forEachInner(f, from, to, 0);
	else this.forEachInvertedInner(f, from, to, 0);
};
RopeSequence.prototype.map = function map(f, from, to) {
	if (from === void 0) from = 0;
	if (to === void 0) to = this.length;
	var result = [];
	this.forEach(function(elt, i) {
		return result.push(f(elt, i));
	}, from, to);
	return result;
};
RopeSequence.from = function from(values) {
	if (values instanceof RopeSequence) return values;
	return values && values.length ? new Leaf(values) : RopeSequence.empty;
};
var Leaf = /* @__PURE__ */ function(RopeSequence) {
	function Leaf(values) {
		RopeSequence.call(this);
		this.values = values;
	}
	if (RopeSequence) Leaf.__proto__ = RopeSequence;
	Leaf.prototype = Object.create(RopeSequence && RopeSequence.prototype);
	Leaf.prototype.constructor = Leaf;
	var prototypeAccessors = {
		length: { configurable: true },
		depth: { configurable: true }
	};
	Leaf.prototype.flatten = function flatten() {
		return this.values;
	};
	Leaf.prototype.sliceInner = function sliceInner(from, to) {
		if (from == 0 && to == this.length) return this;
		return new Leaf(this.values.slice(from, to));
	};
	Leaf.prototype.getInner = function getInner(i) {
		return this.values[i];
	};
	Leaf.prototype.forEachInner = function forEachInner(f, from, to, start) {
		for (var i = from; i < to; i++) if (f(this.values[i], start + i) === false) return false;
	};
	Leaf.prototype.forEachInvertedInner = function forEachInvertedInner(f, from, to, start) {
		for (var i = from - 1; i >= to; i--) if (f(this.values[i], start + i) === false) return false;
	};
	Leaf.prototype.leafAppend = function leafAppend(other) {
		if (this.length + other.length <= GOOD_LEAF_SIZE) return new Leaf(this.values.concat(other.flatten()));
	};
	Leaf.prototype.leafPrepend = function leafPrepend(other) {
		if (this.length + other.length <= GOOD_LEAF_SIZE) return new Leaf(other.flatten().concat(this.values));
	};
	prototypeAccessors.length.get = function() {
		return this.values.length;
	};
	prototypeAccessors.depth.get = function() {
		return 0;
	};
	Object.defineProperties(Leaf.prototype, prototypeAccessors);
	return Leaf;
}(RopeSequence);
RopeSequence.empty = new Leaf([]);
var Append = /* @__PURE__ */ function(RopeSequence) {
	function Append(left, right) {
		RopeSequence.call(this);
		this.left = left;
		this.right = right;
		this.length = left.length + right.length;
		this.depth = Math.max(left.depth, right.depth) + 1;
	}
	if (RopeSequence) Append.__proto__ = RopeSequence;
	Append.prototype = Object.create(RopeSequence && RopeSequence.prototype);
	Append.prototype.constructor = Append;
	Append.prototype.flatten = function flatten() {
		return this.left.flatten().concat(this.right.flatten());
	};
	Append.prototype.getInner = function getInner(i) {
		return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length);
	};
	Append.prototype.forEachInner = function forEachInner(f, from, to, start) {
		var leftLen = this.left.length;
		if (from < leftLen && this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false) return false;
		if (to > leftLen && this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false) return false;
	};
	Append.prototype.forEachInvertedInner = function forEachInvertedInner(f, from, to, start) {
		var leftLen = this.left.length;
		if (from > leftLen && this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false) return false;
		if (to < leftLen && this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false) return false;
	};
	Append.prototype.sliceInner = function sliceInner(from, to) {
		if (from == 0 && to == this.length) return this;
		var leftLen = this.left.length;
		if (to <= leftLen) return this.left.slice(from, to);
		if (from >= leftLen) return this.right.slice(from - leftLen, to - leftLen);
		return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen));
	};
	Append.prototype.leafAppend = function leafAppend(other) {
		var inner = this.right.leafAppend(other);
		if (inner) return new Append(this.left, inner);
	};
	Append.prototype.leafPrepend = function leafPrepend(other) {
		var inner = this.left.leafPrepend(other);
		if (inner) return new Append(inner, this.right);
	};
	Append.prototype.appendInner = function appendInner(other) {
		if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1) return new Append(this.left, new Append(this.right, other));
		return new Append(this, other);
	};
	return Append;
}(RopeSequence);
//#endregion
//#region ../../node_modules/.pnpm/prosemirror-history@1.5.0/node_modules/prosemirror-history/dist/index.js
var max_empty_items = 500;
var Branch = class Branch {
	constructor(items, eventCount) {
		this.items = items;
		this.eventCount = eventCount;
	}
	popEvent(state, preserveItems) {
		if (this.eventCount == 0) return null;
		let end = this.items.length;
		for (;; end--) if (this.items.get(end - 1).selection) {
			--end;
			break;
		}
		let remap, mapFrom;
		if (preserveItems) {
			remap = this.remapping(end, this.items.length);
			mapFrom = remap.maps.length;
		}
		let transform = state.tr;
		let selection, remaining;
		let addAfter = [], addBefore = [];
		this.items.forEach((item, i) => {
			if (!item.step) {
				if (!remap) {
					remap = this.remapping(end, i + 1);
					mapFrom = remap.maps.length;
				}
				mapFrom--;
				addBefore.push(item);
				return;
			}
			if (remap) {
				addBefore.push(new Item(item.map));
				let step = item.step.map(remap.slice(mapFrom)), map;
				if (step && transform.maybeStep(step).doc) {
					map = transform.mapping.maps[transform.mapping.maps.length - 1];
					addAfter.push(new Item(map, void 0, void 0, addAfter.length + addBefore.length));
				}
				mapFrom--;
				if (map) remap.appendMap(map, mapFrom);
			} else transform.maybeStep(item.step);
			if (item.selection) {
				selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
				remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
				return false;
			}
		}, this.items.length, 0);
		return {
			remaining,
			transform,
			selection
		};
	}
	addTransform(transform, selection, histOptions, preserveItems) {
		let newItems = [], eventCount = this.eventCount;
		let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
		for (let i = 0; i < transform.steps.length; i++) {
			let step = transform.steps[i].invert(transform.docs[i]);
			let item = new Item(transform.mapping.maps[i], step, selection), merged;
			if (merged = lastItem && lastItem.merge(item)) {
				item = merged;
				if (i) newItems.pop();
				else oldItems = oldItems.slice(0, oldItems.length - 1);
			}
			newItems.push(item);
			if (selection) {
				eventCount++;
				selection = void 0;
			}
			if (!preserveItems) lastItem = item;
		}
		let overflow = eventCount - histOptions.depth;
		if (overflow > DEPTH_OVERFLOW) {
			oldItems = cutOffEvents(oldItems, overflow);
			eventCount -= overflow;
		}
		return new Branch(oldItems.append(newItems), eventCount);
	}
	remapping(from, to) {
		let maps = new Mapping();
		this.items.forEach((item, i) => {
			let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from ? maps.maps.length - item.mirrorOffset : void 0;
			maps.appendMap(item.map, mirrorPos);
		}, from, to);
		return maps;
	}
	addMaps(array) {
		if (this.eventCount == 0) return this;
		return new Branch(this.items.append(array.map((map) => new Item(map))), this.eventCount);
	}
	rebased(rebasedTransform, rebasedCount) {
		if (!this.eventCount) return this;
		let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount);
		let mapping = rebasedTransform.mapping;
		let newUntil = rebasedTransform.steps.length;
		let eventCount = this.eventCount;
		this.items.forEach((item) => {
			if (item.selection) eventCount--;
		}, start);
		let iRebased = rebasedCount;
		this.items.forEach((item) => {
			let pos = mapping.getMirror(--iRebased);
			if (pos == null) return;
			newUntil = Math.min(newUntil, pos);
			let map = mapping.maps[pos];
			if (item.step) {
				let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
				let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
				if (selection) eventCount++;
				rebasedItems.push(new Item(map, step, selection));
			} else rebasedItems.push(new Item(map));
		}, start);
		let newMaps = [];
		for (let i = rebasedCount; i < newUntil; i++) newMaps.push(new Item(mapping.maps[i]));
		let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
		let branch = new Branch(items, eventCount);
		if (branch.emptyItemCount() > max_empty_items) branch = branch.compress(this.items.length - rebasedItems.length);
		return branch;
	}
	emptyItemCount() {
		let count = 0;
		this.items.forEach((item) => {
			if (!item.step) count++;
		});
		return count;
	}
	compress(upto = this.items.length) {
		let remap = this.remapping(0, upto), mapFrom = remap.maps.length;
		let items = [], events = 0;
		this.items.forEach((item, i) => {
			if (i >= upto) {
				items.push(item);
				if (item.selection) events++;
			} else if (item.step) {
				let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap();
				mapFrom--;
				if (map) remap.appendMap(map, mapFrom);
				if (step) {
					let selection = item.selection && item.selection.map(remap.slice(mapFrom));
					if (selection) events++;
					let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;
					if (merged = items.length && items[last].merge(newItem)) items[last] = merged;
					else items.push(newItem);
				}
			} else if (item.map) mapFrom--;
		}, this.items.length, 0);
		return new Branch(RopeSequence.from(items.reverse()), events);
	}
};
Branch.empty = new Branch(RopeSequence.empty, 0);
function cutOffEvents(items, n) {
	let cutPoint;
	items.forEach((item, i) => {
		if (item.selection && n-- == 0) {
			cutPoint = i;
			return false;
		}
	});
	return items.slice(cutPoint);
}
var Item = class Item {
	constructor(map, step, selection, mirrorOffset) {
		this.map = map;
		this.step = step;
		this.selection = selection;
		this.mirrorOffset = mirrorOffset;
	}
	merge(other) {
		if (this.step && other.step && !other.selection) {
			let step = other.step.merge(this.step);
			if (step) return new Item(step.getMap().invert(), step, this.selection);
		}
	}
};
var HistoryState = class {
	constructor(done, undone, prevRanges, prevTime, prevComposition) {
		this.done = done;
		this.undone = undone;
		this.prevRanges = prevRanges;
		this.prevTime = prevTime;
		this.prevComposition = prevComposition;
	}
};
var DEPTH_OVERFLOW = 20;
function applyTransaction(history, state, tr, options) {
	let historyTr = tr.getMeta(historyKey), rebased;
	if (historyTr) return historyTr.historyState;
	if (tr.getMeta(closeHistoryKey)) history = new HistoryState(history.done, history.undone, null, 0, -1);
	let appended = tr.getMeta("appendedTransaction");
	if (tr.steps.length == 0) return history;
	else if (appended && appended.getMeta(historyKey)) {
		if (appended.getMeta(historyKey).redo) return new HistoryState(history.done.addTransform(tr, void 0, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps), history.prevTime, history.prevComposition);
		else return new HistoryState(history.done, history.undone.addTransform(tr, void 0, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
	} else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
		let composition = tr.getMeta("composition");
		let newGroup = history.prevTime == 0 || !appended && history.prevComposition != composition && (history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges));
		let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);
		return new HistoryState(history.done.addTransform(tr, newGroup ? state.selection.getBookmark() : void 0, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition);
	} else if (rebased = tr.getMeta("rebased")) return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
	else return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
}
function isAdjacentTo(transform, prevRanges) {
	if (!prevRanges) return false;
	if (!transform.docChanged) return true;
	let adjacent = false;
	transform.mapping.maps[0].forEach((start, end) => {
		for (let i = 0; i < prevRanges.length; i += 2) if (start <= prevRanges[i + 1] && end >= prevRanges[i]) adjacent = true;
	});
	return adjacent;
}
function rangesFor(maps) {
	let result = [];
	for (let i = maps.length - 1; i >= 0 && result.length == 0; i--) maps[i].forEach((_from, _to, from, to) => result.push(from, to));
	return result;
}
function mapRanges(ranges, mapping) {
	if (!ranges) return null;
	let result = [];
	for (let i = 0; i < ranges.length; i += 2) {
		let from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1);
		if (from <= to) result.push(from, to);
	}
	return result;
}
function histTransaction(history, state, redo) {
	let preserveItems = mustPreserveItems(state);
	let histOptions = historyKey.get(state).spec.config;
	let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
	if (!pop) return null;
	let selection = pop.selection.resolve(pop.transform.doc);
	let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
	let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
	return pop.transform.setSelection(selection).setMeta(historyKey, {
		redo,
		historyState: newHist
	});
}
var cachedPreserveItems = false;
var cachedPreserveItemsPlugins = null;
function mustPreserveItems(state) {
	let plugins = state.plugins;
	if (cachedPreserveItemsPlugins != plugins) {
		cachedPreserveItems = false;
		cachedPreserveItemsPlugins = plugins;
		for (let i = 0; i < plugins.length; i++) if (plugins[i].spec.historyPreserveItems) {
			cachedPreserveItems = true;
			break;
		}
	}
	return cachedPreserveItems;
}
var historyKey = new PluginKey("history");
var closeHistoryKey = new PluginKey("closeHistory");
/**
Returns a plugin that enables the undo history for an editor. The
plugin will track undo and redo stacks, which can be used with the
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.

You can set an `"addToHistory"` [metadata
property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
to prevent it from being rolled back by undo.
*/
function history(config = {}) {
	config = {
		depth: config.depth || 100,
		newGroupDelay: config.newGroupDelay || 500
	};
	return new Plugin({
		key: historyKey,
		state: {
			init() {
				return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
			},
			apply(tr, hist, state) {
				return applyTransaction(hist, state, tr, config);
			}
		},
		config,
		props: { handleDOMEvents: { beforeinput(view, e) {
			let inputType = e.inputType;
			let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
			if (!command || !view.editable) return false;
			e.preventDefault();
			return command(view.state, view.dispatch);
		} } }
	});
}
function buildCommand(redo, scroll) {
	return (state, dispatch) => {
		let hist = historyKey.getState(state);
		if (!hist || (redo ? hist.undone : hist.done).eventCount == 0) return false;
		if (dispatch) {
			let tr = histTransaction(hist, state, redo);
			if (tr) dispatch(scroll ? tr.scrollIntoView() : tr);
		}
		return true;
	};
}
/**
A command function that undoes the last change, if any.
*/
var undo = buildCommand(false, true);
/**
A command function that redoes the last undone change, if any.
*/
var redo = buildCommand(true, true);
Extension.create({
	name: "characterCount",
	addOptions() {
		return {
			limit: null,
			autoTrim: true,
			mode: "textSize",
			textCounter: (text) => text.length,
			wordCounter: (text) => text.split(" ").filter((word) => word !== "").length
		};
	},
	addStorage() {
		return {
			characters: () => 0,
			words: () => 0
		};
	},
	onBeforeCreate() {
		this.storage.characters = (options) => {
			const node = (options == null ? void 0 : options.node) || this.editor.state.doc;
			if (((options == null ? void 0 : options.mode) || this.options.mode) === "textSize") {
				const text = node.textBetween(0, node.content.size, void 0, " ");
				return this.options.textCounter(text);
			}
			return node.nodeSize;
		};
		this.storage.words = (options) => {
			const node = (options == null ? void 0 : options.node) || this.editor.state.doc;
			const text = node.textBetween(0, node.content.size, " ", " ");
			return this.options.wordCounter(text);
		};
	},
	addProseMirrorPlugins() {
		let initialEvaluationDone = false;
		return [new Plugin({
			key: new PluginKey("characterCount"),
			appendTransaction: (transactions, oldState, newState) => {
				if (initialEvaluationDone) return;
				const limit = this.options.limit;
				const autoTrim = this.options.autoTrim;
				if (limit === null || limit === void 0 || limit === 0 || autoTrim === false) {
					initialEvaluationDone = true;
					return;
				}
				const initialContentSize = this.storage.characters({ node: newState.doc });
				if (initialContentSize > limit) {
					const over = initialContentSize - limit;
					const from = 0;
					const to = over;
					console.warn(`[CharacterCount] Initial content exceeded limit of ${limit} characters. Content was automatically trimmed.`);
					const tr = newState.tr.deleteRange(from, to);
					initialEvaluationDone = true;
					return tr;
				}
				initialEvaluationDone = true;
			},
			filterTransaction: (transaction, state) => {
				const limit = this.options.limit;
				if (!transaction.docChanged || limit === 0 || limit === null || limit === void 0) return true;
				const oldSize = this.storage.characters({ node: state.doc });
				const newSize = this.storage.characters({ node: transaction.doc });
				if (newSize <= limit) return true;
				if (oldSize > limit && newSize > limit && newSize <= oldSize) return true;
				if (oldSize > limit && newSize > limit && newSize > oldSize) return false;
				if (!transaction.getMeta("paste")) return false;
				const pos = transaction.selection.$head.pos;
				const from = pos - (newSize - limit);
				const to = pos;
				transaction.deleteRange(from, to);
				if (this.storage.characters({ node: transaction.doc }) > limit) return false;
				return true;
			}
		})];
	}
});
Extension.create({
	name: "dropCursor",
	addOptions() {
		return {
			color: "currentColor",
			width: 1,
			class: void 0
		};
	},
	addProseMirrorPlugins() {
		return [dropCursor(this.options)];
	}
});
Extension.create({
	name: "focus",
	addOptions() {
		return {
			className: "has-focus",
			mode: "all"
		};
	},
	addProseMirrorPlugins() {
		return [new Plugin({
			key: new PluginKey("focus"),
			props: { decorations: ({ doc, selection }) => {
				const { isEditable, isFocused } = this.editor;
				const { anchor } = selection;
				const decorations = [];
				if (!isEditable || !isFocused) return DecorationSet.create(doc, []);
				let maxLevels = 0;
				if (this.options.mode === "deepest") doc.descendants((node, pos) => {
					if (node.isText) return;
					if (!(anchor >= pos && anchor <= pos + node.nodeSize - 1)) return false;
					maxLevels += 1;
				});
				let currentLevel = 0;
				doc.descendants((node, pos) => {
					if (node.isText) return false;
					if (!(anchor >= pos && anchor <= pos + node.nodeSize - 1)) return false;
					currentLevel += 1;
					if (this.options.mode === "deepest" && maxLevels - currentLevel > 0 || this.options.mode === "shallowest" && currentLevel > 1) return this.options.mode === "deepest";
					decorations.push(Decoration.node(pos, pos + node.nodeSize, { class: this.options.className }));
				});
				return DecorationSet.create(doc, decorations);
			} }
		})];
	}
});
Extension.create({
	name: "gapCursor",
	addProseMirrorPlugins() {
		return [gapCursor()];
	},
	extendNodeSchema(extension) {
		var _a;
		return { allowGapCursor: (_a = callOrReturn(getExtensionField(extension, "allowGapCursor", {
			name: extension.name,
			options: extension.options,
			storage: extension.storage
		}))) != null ? _a : null };
	}
});
var DEFAULT_DATA_ATTRIBUTE = "placeholder";
var PLUGIN_KEY = new PluginKey("tiptap__placeholder");
function createPlaceholderDecoration(options) {
	const { editor, placeholder, dataAttribute, pos, node, isEmptyDoc, hasAnchor, classes: { emptyNode, emptyEditor } } = options;
	const classes = [emptyNode];
	if (isEmptyDoc) classes.push(emptyEditor);
	return Decoration.node(pos, pos + node.nodeSize, {
		class: classes.join(" "),
		[dataAttribute]: typeof placeholder === "function" ? placeholder({
			editor,
			node,
			pos,
			hasAnchor
		}) : placeholder
	});
}
function resolveEmptyNodeClass(emptyNodeClass, props) {
	return typeof emptyNodeClass === "function" ? emptyNodeClass(props) : emptyNodeClass;
}
function scanRangeForDecorations({ editor, options, dataAttribute, doc, selection, from, to }) {
	const { anchor } = selection;
	const decorations = [];
	const isEmptyDoc = editor.isEmpty;
	doc.nodesBetween(from, to, (node, pos) => {
		const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
		const isEmpty = !node.isLeaf && isNodeEmpty(node);
		if (!node.type.isTextblock) return options.includeChildren;
		if ((hasAnchor || !options.showOnlyCurrent) && isEmpty) decorations.push(createPlaceholderDecoration({
			editor,
			isEmptyDoc,
			dataAttribute,
			hasAnchor,
			placeholder: options.placeholder,
			classes: {
				emptyEditor: options.emptyEditorClass,
				emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, {
					editor,
					node,
					pos,
					hasAnchor
				})
			},
			node,
			pos
		}));
		return options.includeChildren;
	});
	return decorations;
}
function buildPlaceholderDecorations({ editor, options, dataAttribute, doc, selection }) {
	if (!(editor.isEditable || !options.showOnlyWhenEditable)) return null;
	const { anchor } = selection;
	const decorations = [];
	const isEmptyDoc = editor.isEmpty;
	if (options.showOnlyCurrent && !options.includeChildren) {
		const resolved = doc.resolve(anchor);
		const node = resolved.depth > 0 ? resolved.node(1) : resolved.nodeAfter;
		const nodeStart = resolved.depth > 0 ? resolved.before(1) : anchor;
		if (node && node.type.isTextblock && isNodeEmpty(node)) {
			const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize;
			decorations.push(createPlaceholderDecoration({
				editor,
				isEmptyDoc,
				dataAttribute,
				hasAnchor,
				placeholder: options.placeholder,
				classes: {
					emptyEditor: options.emptyEditorClass,
					emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, {
						editor,
						node,
						pos: nodeStart,
						hasAnchor
					})
				},
				node,
				pos: nodeStart
			}));
		}
	} else decorations.push(...scanRangeForDecorations({
		editor,
		options,
		dataAttribute,
		doc,
		selection,
		from: 0,
		to: doc.content.size
	}));
	return DecorationSet.create(doc, decorations);
}
function resolveTopLevelRange(doc, pos) {
	var _a;
	const resolved = doc.resolve(pos);
	if (resolved.depth === 0) {
		const node2 = (_a = resolved.nodeAfter) != null ? _a : resolved.nodeBefore;
		if (!node2) return {
			from: pos,
			to: pos
		};
		const nodePos = resolved.nodeAfter ? pos : pos - node2.nodeSize;
		return {
			from: nodePos,
			to: nodePos + node2.nodeSize
		};
	}
	const topLevelPos = resolved.before(1);
	return {
		from: topLevelPos,
		to: topLevelPos + resolved.node(1).nodeSize
	};
}
function toContentRelativeRange(doc, range) {
	return {
		from: Math.max(0, range.from - 1),
		to: Math.min(doc.content.size, range.to - 1)
	};
}
function getTopLevelBlocksInRange(doc, from, to) {
	const ranges = [];
	doc.forEach((node, offset) => {
		const nodeStart = offset;
		const nodeEnd = nodeStart + node.nodeSize;
		const absNodeStart = nodeStart + 1;
		const absNodeEnd = nodeEnd + 1;
		if (absNodeStart < to && absNodeEnd > from) ranges.push({
			from: nodeStart,
			to: nodeEnd
		});
	});
	return ranges;
}
function mergeRanges(ranges) {
	if (ranges.length === 0) return [];
	const sorted = [...ranges].sort((a, b) => a.from - b.from);
	const merged = [{ ...sorted[0] }];
	for (let i = 1; i < sorted.length; i += 1) {
		const last = merged[merged.length - 1];
		const current = sorted[i];
		if (current.from <= last.to) last.to = Math.max(last.to, current.to);
		else merged.push({ ...current });
	}
	return merged;
}
function collectBlocksForChange(doc, change) {
	const ranges = getTopLevelBlocksInRange(doc, change.from, change.to);
	ranges.push(toContentRelativeRange(doc, resolveTopLevelRange(doc, change.from)));
	if (change.to > change.from) ranges.push(toContentRelativeRange(doc, resolveTopLevelRange(doc, Math.min(change.to, doc.content.size + 1) - 1)));
	else if (change.from < doc.content.size + 1) ranges.push(toContentRelativeRange(doc, resolveTopLevelRange(doc, Math.min(change.from + 1, doc.content.size))));
	return ranges;
}
function collectRescanRanges(tr, oldState, newState) {
	const ranges = [];
	if (tr.docChanged) {
		const changes = getChangedRanges(tr);
		for (const change of changes) ranges.push(...collectBlocksForChange(newState.doc, change.newRange));
	}
	if (tr.selectionSet) {
		ranges.push(toContentRelativeRange(newState.doc, resolveTopLevelRange(newState.doc, tr.mapping.map(oldState.selection.anchor))));
		ranges.push(toContentRelativeRange(newState.doc, resolveTopLevelRange(newState.doc, newState.selection.anchor)));
	}
	return mergeRanges(ranges);
}
function clampRange(from, to, doc) {
	const clampedFrom = Math.max(0, Math.min(from, doc.content.size));
	return {
		from: clampedFrom,
		to: Math.max(clampedFrom, Math.min(to, doc.content.size))
	};
}
function updateDecorationsInRanges({ decorations, ranges, editor, options, dataAttribute, doc, selection }) {
	let next = decorations;
	for (const range of ranges) {
		const { from, to } = clampRange(range.from, range.to, doc);
		const existing = next.find(from, to).filter((decoration) => decoration.from >= from && decoration.to <= to);
		if (existing.length) next = next.remove(existing);
		const newDecos = scanRangeForDecorations({
			editor,
			options,
			dataAttribute,
			doc,
			selection,
			from,
			to
		});
		if (newDecos.length) next = next.add(doc, newDecos);
	}
	return next;
}
function createPlaceholderStateField({ editor, options, dataAttribute }) {
	return {
		init(_config, state) {
			const decorations = buildPlaceholderDecorations({
				editor,
				options,
				dataAttribute,
				doc: state.doc,
				selection: state.selection
			});
			return decorations != null ? decorations : DecorationSet.empty;
		},
		apply(tr, prev, oldState, newState) {
			if (!tr.docChanged && !tr.selectionSet) return prev;
			return updateDecorationsInRanges({
				decorations: prev.map(tr.mapping, tr.doc),
				ranges: collectRescanRanges(tr, oldState, newState),
				editor,
				options,
				dataAttribute,
				doc: newState.doc,
				selection: newState.selection
			});
		}
	};
}
function preparePlaceholderAttribute(attr) {
	return attr.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9-]/g, "").replace(/^[0-9-]+/, "").replace(/^-+/, "").toLowerCase();
}
function createPlaceholderPlugin({ editor, options }) {
	const dataAttribute = options.dataAttribute ? `data-${preparePlaceholderAttribute(options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`;
	const useResolvedPath = options.showOnlyCurrent && !options.includeChildren;
	return new Plugin({
		key: PLUGIN_KEY,
		...useResolvedPath ? {} : { state: createPlaceholderStateField({
			editor,
			options,
			dataAttribute
		}) },
		props: { decorations: useResolvedPath ? ({ doc, selection }) => buildPlaceholderDecorations({
			editor,
			options,
			dataAttribute,
			doc,
			selection
		}) : (state) => {
			var _a;
			if (options.showOnlyWhenEditable && !editor.isEditable) return DecorationSet.empty;
			return (_a = PLUGIN_KEY.getState(state)) != null ? _a : DecorationSet.empty;
		} }
	});
}
Extension.create({
	name: "placeholder",
	addOptions() {
		return {
			emptyEditorClass: "is-editor-empty",
			emptyNodeClass: "is-empty",
			dataAttribute: DEFAULT_DATA_ATTRIBUTE,
			placeholder: "Write something …",
			showOnlyWhenEditable: true,
			showOnlyCurrent: true,
			includeChildren: false
		};
	},
	addProseMirrorPlugins() {
		return [createPlaceholderPlugin({
			editor: this.editor,
			options: this.options
		})];
	}
});
function shouldSyncDomSelection(state, editor) {
	return !state.selection.empty && !isNodeSelection(state.selection) && editor.isEditable;
}
function shouldPreserveSelection(state, editor) {
	return shouldSyncDomSelection(state, editor) && !editor.isFocused && !editor.view.dragging;
}
function clearDomSelection() {
	var _a;
	(_a = window.getSelection()) == null || _a.removeAllRanges();
}
function restoreDomSelection(view) {
	view.focus();
}
Extension.create({
	name: "selection",
	addOptions() {
		return { className: "selection" };
	},
	addProseMirrorPlugins() {
		const { editor, options } = this;
		return [new Plugin({
			key: new PluginKey("selection"),
			props: {
				decorations(state) {
					if (!shouldPreserveSelection(state, editor)) return null;
					return DecorationSet.create(state.doc, [Decoration.inline(state.selection.from, state.selection.to, { class: options.className })]);
				},
				handleDOMEvents: {
					blur(view) {
						if (!shouldSyncDomSelection(view.state, editor)) return false;
						clearDomSelection();
						return false;
					},
					focus(view) {
						if (!shouldSyncDomSelection(view.state, editor)) return false;
						requestAnimationFrame(() => {
							if (!editor.isDestroyed && view.hasFocus()) restoreDomSelection(view);
						});
						return false;
					}
				}
			}
		})];
	}
});
function nodeEqualsType({ types, node }) {
	return node && Array.isArray(types) && types.includes(node.type) || (node == null ? void 0 : node.type) === types;
}
Extension.create({
	name: "trailingNode",
	addOptions() {
		return {
			node: void 0,
			notAfter: []
		};
	},
	addProseMirrorPlugins() {
		var _a;
		const plugin = new PluginKey(this.name);
		const defaultNode = this.options.node || ((_a = this.editor.schema.topNodeType.contentMatch.defaultType) == null ? void 0 : _a.name) || "paragraph";
		const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => (this.options.notAfter || []).concat(defaultNode).includes(node.name));
		return [new Plugin({
			key: plugin,
			appendTransaction: (transactions, __, state) => {
				const { doc, tr, schema } = state;
				const shouldInsertNodeAtEnd = plugin.getState(state);
				const endPosition = doc.content.size;
				const type = schema.nodes[defaultNode];
				if (transactions.some((transaction) => transaction.getMeta("skipTrailingNode"))) return;
				if (!shouldInsertNodeAtEnd) return;
				return tr.insert(endPosition, type.create());
			},
			state: {
				init: (_, state) => {
					const lastNode = state.tr.doc.lastChild;
					return !nodeEqualsType({
						node: lastNode,
						types: disabledNodes
					});
				},
				apply: (tr, value) => {
					if (!tr.docChanged) return value;
					if (tr.getMeta("__uniqueIDTransaction")) return value;
					const lastNode = tr.doc.lastChild;
					return !nodeEqualsType({
						node: lastNode,
						types: disabledNodes
					});
				}
			}
		})];
	}
});
var UndoRedo = Extension.create({
	name: "undoRedo",
	addOptions() {
		return {
			depth: 100,
			newGroupDelay: 500
		};
	},
	addCommands() {
		return {
			undo: () => ({ state, dispatch }) => {
				return undo(state, dispatch);
			},
			redo: () => ({ state, dispatch }) => {
				return redo(state, dispatch);
			}
		};
	},
	addProseMirrorPlugins() {
		return [history(this.options)];
	},
	addKeyboardShortcuts() {
		return {
			"Mod-z": () => this.editor.commands.undo(),
			"Shift-Mod-z": () => this.editor.commands.redo(),
			"Mod-y": () => this.editor.commands.redo(),
			"Mod-я": () => this.editor.commands.undo(),
			"Shift-Mod-я": () => this.editor.commands.redo()
		};
	}
});
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-italic@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2_/node_modules/@tiptap/extension-italic/dist/index.js
var starInputRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/;
var starPasteRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g;
var underscoreInputRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/;
var underscorePasteRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g;
var Italic = Mark.create({
	name: "italic",
	addOptions() {
		return { HTMLAttributes: {} };
	},
	parseHTML() {
		return [
			{ tag: "em" },
			{
				tag: "i",
				getAttrs: (node) => node.style.fontStyle !== "normal" && null
			},
			{
				style: "font-style=normal",
				clearMark: (mark) => mark.type.name === this.name
			},
			{ style: "font-style=italic" }
		];
	},
	renderHTML({ HTMLAttributes }) {
		return [
			"em",
			mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
			0
		];
	},
	addCommands() {
		return {
			setItalic: () => ({ commands }) => {
				return commands.setMark(this.name);
			},
			toggleItalic: () => ({ commands }) => {
				return commands.toggleMark(this.name);
			},
			unsetItalic: () => ({ commands }) => {
				return commands.unsetMark(this.name);
			}
		};
	},
	markdownTokenName: "em",
	parseMarkdown: (token, helpers) => {
		return helpers.applyMark("italic", helpers.parseInline(token.tokens || []));
	},
	markdownOptions: { htmlReopen: {
		open: "<em>",
		close: "</em>"
	} },
	renderMarkdown: (node, h) => {
		return `*${h.renderChildren(node)}*`;
	},
	addKeyboardShortcuts() {
		return {
			"Mod-i": () => this.editor.commands.toggleItalic(),
			"Mod-I": () => this.editor.commands.toggleItalic()
		};
	},
	addInputRules() {
		return [markInputRule({
			find: starInputRegex,
			type: this.type
		}), markInputRule({
			find: underscoreInputRegex,
			type: this.type
		})];
	},
	addPasteRules() {
		return [markPasteRule({
			find: starPasteRegex,
			type: this.type
		}), markPasteRule({
			find: underscorePasteRegex,
			type: this.type
		})];
	}
});
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-paragraph@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2_/node_modules/@tiptap/extension-paragraph/dist/index.js
var EMPTY_PARAGRAPH_MARKDOWN = "&nbsp;";
var NBSP_CHAR = "\xA0";
var Paragraph = Node3.create({
	name: "paragraph",
	priority: 1e3,
	addOptions() {
		return { HTMLAttributes: {} };
	},
	group: "block",
	content: "inline*",
	parseHTML() {
		return [{ tag: "p" }];
	},
	renderHTML({ HTMLAttributes }) {
		return [
			"p",
			mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
			0
		];
	},
	parseMarkdown: (token, helpers) => {
		const tokens = token.tokens || [];
		if (tokens.length === 1 && tokens[0].type === "image") return helpers.parseChildren([tokens[0]]);
		const content = helpers.parseInline(tokens);
		if (tokens.length === 1 && tokens[0].type === "text" && (tokens[0].raw === EMPTY_PARAGRAPH_MARKDOWN || tokens[0].text === EMPTY_PARAGRAPH_MARKDOWN || tokens[0].raw === NBSP_CHAR || tokens[0].text === NBSP_CHAR) && content.length === 1 && content[0].type === "text" && (content[0].text === EMPTY_PARAGRAPH_MARKDOWN || content[0].text === NBSP_CHAR)) return helpers.createNode("paragraph", void 0, []);
		return helpers.createNode("paragraph", void 0, content);
	},
	renderMarkdown: (node, h, ctx) => {
		var _a, _b;
		if (!node) return "";
		const content = Array.isArray(node.content) ? node.content : [];
		if (content.length === 0) {
			const previousContent = Array.isArray((_a = ctx == null ? void 0 : ctx.previousNode) == null ? void 0 : _a.content) ? ctx.previousNode.content : [];
			return ((_b = ctx == null ? void 0 : ctx.previousNode) == null ? void 0 : _b.type) === "paragraph" && previousContent.length === 0 ? EMPTY_PARAGRAPH_MARKDOWN : "";
		}
		return h.renderChildren(content);
	},
	addCommands() {
		return { setParagraph: () => ({ commands }) => {
			return commands.setNode(this.name);
		} };
	},
	addKeyboardShortcuts() {
		return { "Mod-Alt-0": () => this.editor.commands.setParagraph() };
	}
});
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-text@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2_/node_modules/@tiptap/extension-text/dist/index.js
var Text = Node3.create({
	name: "text",
	group: "inline",
	parseMarkdown: (token) => {
		return {
			type: "text",
			text: token.text || ""
		};
	},
	renderMarkdown: (node) => node.text || ""
});
//#endregion
//#region ../../node_modules/.pnpm/tiptap-text-direction@0.5.0_@tiptap+core@3.30.2_@tiptap+pm@3.30.2__@tiptap+pm@3.30.2/node_modules/tiptap-text-direction/dist/index.mjs
/**
* Unicode character ranges commonly associated with RTL scripts.
*
* Includes Hebrew, Arabic, Syriac, Thaana, and related presentation forms.
* Used for content-based direction detection.
*/
var RTL_CHAR_RANGE = "֑-߿יִ-﷽ﹰ-ﻼ";
/**
* Unicode character ranges commonly associated with LTR scripts.
*
* Includes Latin, extended Latin, and a variety of other non-RTL ranges.
* Used for content-based direction detection.
*/
var LTR_CHAR_RANGE = "A-Za-zÀ-ÖØ-öø-ʸ̀-֐ࠀ-῿‎Ⰰ-﬜︀-﹯﻽-";
/**
* Regex that detects whether a string contains an RTL character before any strong LTR character.
*/
var RTL_REGEX = /* @__PURE__ */ new RegExp(`^[^${LTR_CHAR_RANGE}]*[${RTL_CHAR_RANGE}]`);
/**
* Regex that detects whether a string contains an LTR character before any strong RTL character.
*/
var LTR_REGEX = /* @__PURE__ */ new RegExp(`^[^${RTL_CHAR_RANGE}]*[${LTR_CHAR_RANGE}]`);
/**
* All supported direction values.
*/
var DIRECTIONS = [
	"ltr",
	"rtl",
	"auto"
];
/**
* Detect the text direction of a string based on its content.
*
* @param text - The text to analyze
* @returns `"rtl"` if the text starts with a RTL character,
*          `"ltr"` if the text starts with a LTR character,
*          `null` if direction cannot be determined (e.g. empty string)
*/
function getTextDirection(text) {
	if (text.length === 0) return null;
	if (RTL_REGEX.test(text)) return "rtl";
	if (LTR_REGEX.test(text)) return "ltr";
	return null;
}
/**
* ProseMirror plugin that automatically applies a `dir` attribute to configured node types when their content changes.
*
* @param options - Plugin configuration
* @param options.types - Node type names that should receive direction updates
*/
function TextDirectionPlugin({ types }) {
	return new Plugin({
		key: new PluginKey("tiptapTextDirection"),
		appendTransaction: (transactions, oldState, newState) => {
			if (!transactions.some((transaction) => transaction.docChanged)) return;
			let modified = false;
			const { tr } = newState;
			const changes = getChangedRanges(combineTransactionSteps(oldState.doc, transactions));
			tr.setMeta("addToHistory", false);
			for (const { newRange } of changes) {
				const nodes = findChildrenInRange(newState.doc, newRange, (node) => {
					return types.includes(node.type.name);
				});
				for (const { node, pos } of nodes) {
					var _tr$storedMarks;
					if (node.attrs.dir !== null && node.textContent.length > 0) continue;
					const newTextDirection = getTextDirection(node.textContent);
					if (node.attrs.dir === newTextDirection) continue;
					const marks = (_tr$storedMarks = tr.storedMarks) !== null && _tr$storedMarks !== void 0 ? _tr$storedMarks : [];
					tr.setNodeAttribute(pos, "dir", newTextDirection);
					for (const mark of marks) tr.addStoredMark(mark);
					modified = true;
				}
			}
			return modified ? tr : null;
		}
	});
}
/**
* Tiptap extension that automatically detects and applies explicit text direction (`dir="ltr"` / `dir="rtl"`) to nodes.
*
* Unlike Tiptap’s built-in RTL support, this extension:
* - Uses JavaScript-based language detection
* - Avoids `dir="auto"`
*/
var TextDirection = Extension.create({
	name: "tiptapTextDirection",
	addOptions() {
		return {
			types: [],
			defaultDirection: null
		};
	},
	addGlobalAttributes() {
		return [{
			types: this.options.types,
			attributes: { dir: {
				default: null,
				parseHTML: (element) => {
					const dir = element.getAttribute("dir");
					if (DIRECTIONS.includes(dir)) return dir;
					return this.options.defaultDirection;
				},
				renderHTML: (attributes) => {
					if (!attributes.dir || attributes.dir === this.options.defaultDirection) return {};
					return { dir: attributes.dir };
				}
			} }
		}];
	},
	addCommands() {
		return {
			setTextDirection: (direction, position) => {
				return ({ tr, state, dispatch }) => {
					const { selection } = state;
					let from;
					let to;
					if (typeof position === "number") {
						from = position;
						to = position;
					} else if (position && "from" in position && "to" in position) {
						from = position.from;
						to = position.to;
					} else {
						from = selection.from;
						to = selection.to;
					}
					if (dispatch) {
						const nodes = findChildrenInRange(tr.doc, {
							from,
							to
						}, (node) => {
							return this.options.types.includes(node.type.name);
						});
						for (const { node, pos } of nodes) tr.setNodeMarkup(pos, void 0, {
							...node.attrs,
							dir: direction
						});
					}
					return true;
				};
			},
			unsetTextDirection: (position) => {
				return ({ tr, state, dispatch }) => {
					const { selection } = state;
					let from;
					let to;
					if (typeof position === "number") {
						from = position;
						to = position;
					} else if (position && "from" in position && "to" in position) {
						from = position.from;
						to = position.to;
					} else {
						from = selection.from;
						to = selection.to;
					}
					if (dispatch) {
						const nodes = findChildrenInRange(tr.doc, {
							from,
							to
						}, (node) => {
							return this.options.types.includes(node.type.name);
						});
						for (const { node, pos } of nodes) {
							const newAttrs = { ...node.attrs };
							delete newAttrs.dir;
							tr.setNodeMarkup(pos, void 0, newAttrs);
						}
					}
					return true;
				};
			}
		};
	},
	addKeyboardShortcuts() {
		return {
			"Mod-Alt-l": () => this.editor.commands.setTextDirection("ltr"),
			"Mod-Alt-r": () => this.editor.commands.setTextDirection("rtl")
		};
	},
	addProseMirrorPlugins() {
		return [TextDirectionPlugin({ types: this.options.types })];
	}
});
//#endregion
//#region ../../packages/ui-editor/dist/index.js
var btnStyle = {
	border: "1px solid #ccc",
	background: "transparent",
	borderRadius: 4,
	padding: "2px 8px",
	cursor: "pointer"
};
function ToolbarButton({ label, pressed, onClick, children }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
		type: "button",
		"aria-label": label,
		"aria-pressed": pressed,
		onClick,
		style: btnStyle,
		children
	});
}
/** Default Bold / Italic / H2 / Bullet-list toolbar. */
function DefaultToolbar({ editor, isBold, isItalic, isH2, isBullet }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		role: "toolbar",
		"aria-label": "Formatting",
		style: {
			display: "flex",
			gap: 4,
			marginBottom: 4
		},
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolbarButton, {
				label: "Bold",
				pressed: isBold,
				onClick: () => {
					if (editor?.can().toggleBold()) editor.chain().focus().toggleBold().run();
				},
				children: "B"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolbarButton, {
				label: "Italic",
				pressed: isItalic,
				onClick: () => {
					if (editor?.can().toggleItalic()) editor.chain().focus().toggleItalic().run();
				},
				children: "I"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolbarButton, {
				label: "Heading 2",
				pressed: isH2,
				onClick: () => {
					if (editor?.can().toggleHeading({ level: 2 })) editor.chain().focus().toggleHeading({ level: 2 }).run();
				},
				children: "H2"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolbarButton, {
				label: "Bullet list",
				pressed: isBullet,
				onClick: () => {
					if (editor?.can().toggleBulletList()) editor.chain().focus().toggleBulletList().run();
				},
				children: "•"
			})
		]
	});
}
/** Production-proven default set (no StarterKit). */
function createDefaultExtensions() {
	return [
		Document,
		Paragraph,
		Text,
		UndoRedo,
		Bold,
		Italic,
		Heading.configure({ levels: [1, 2] }),
		BulletList,
		ListItem,
		TextDirection.configure({ types: ["heading", "paragraph"] })
	];
}
function useToolbarState(editor) {
	const [, rerender] = (0, import_react.useReducer)((n) => n + 1, 0);
	(0, import_react.useEffect)(() => {
		if (!editor) return;
		const update = () => rerender();
		editor.on("selectionUpdate", update);
		editor.on("transaction", update);
		return () => {
			editor.off("selectionUpdate", update);
			editor.off("transaction", update);
		};
	}, [editor]);
	return {
		editor,
		isBold: editor?.isActive("bold") ?? false,
		isItalic: editor?.isActive("italic") ?? false,
		isH2: editor?.isActive("heading", { level: 2 }) ?? false,
		isBullet: editor?.isActive("bulletList") ?? false
	};
}
function sameOptionValue$1(left, right, seen = /* @__PURE__ */ new WeakMap()) {
	if (Object.is(left, right)) return true;
	if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
	if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) return false;
	if (seen.get(left) === right) return true;
	seen.set(left, right);
	const leftKeys = Object.keys(left);
	const rightKeys = Object.keys(right);
	if (leftKeys.length !== rightKeys.length) return false;
	return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && sameOptionValue$1(left[key], right[key], seen));
}
function sameExtensionImplementation$1(left, right) {
	const leftKeys = Object.keys(left);
	const rightKeys = Object.keys(right);
	if (leftKeys.length !== rightKeys.length) return false;
	return leftKeys.every((key) => {
		if (!Object.prototype.hasOwnProperty.call(right, key)) return false;
		const leftValue = Reflect.get(left, key);
		const rightValue = Reflect.get(right, key);
		if (typeof leftValue === "function" || typeof rightValue === "function") return typeof leftValue === "function" && typeof rightValue === "function" && Function.prototype.toString.call(leftValue) === Function.prototype.toString.call(rightValue);
		return sameOptionValue$1(leftValue, rightValue);
	});
}
function sameExtensionConfig$1(left, right) {
	if (left === right) return true;
	if (!left || !right || left.extensions.length !== right.extensions.length) return false;
	return left.extensions.every((extension, index) => {
		const candidate = right.extensions[index];
		return candidate !== void 0 && extension.name === candidate.name && sameOptionValue$1(extension.options, candidate.options) && sameExtensionImplementation$1(extension.config, candidate.config);
	});
}
function useStableExtensionConfig$1(config) {
	const stable = (0, import_react.useRef)(config);
	if (!sameExtensionConfig$1(stable.current, config)) stable.current = config;
	return stable.current;
}
function RichTextEditor({ value, onChange, dir = "ltr", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, extensions, readOnly = false, className, renderToolbar }) {
	const stableExtensions = useStableExtensionConfig$1(extensions);
	const resolvedExtensions = (0, import_react.useMemo)(() => stableExtensions?.extensions ?? createDefaultExtensions(), [stableExtensions]);
	const onChangeRef = (0, import_react.useRef)(onChange);
	const synchronizingRef = (0, import_react.useRef)(false);
	const lastEmittedRef = (0, import_react.useRef)(null);
	const previousValueRef = (0, import_react.useRef)(value);
	const [documentRevision, resetDocumentState] = (0, import_react.useReducer)((revision) => revision + 1, 0);
	onChangeRef.current = onChange;
	const editor = useEditor({
		extensions: resolvedExtensions,
		content: value,
		editable: !readOnly,
		immediatelyRender: false,
		onUpdate: ({ editor: ed }) => {
			if (synchronizingRef.current) return;
			const nextHtml = ed.getHTML();
			lastEmittedRef.current = nextHtml;
			onChangeRef.current(nextHtml);
		},
		editorProps: { attributes: {
			dir,
			role: "textbox",
			"aria-multiline": "true",
			"aria-label": ariaLabel,
			...ariaDescribedBy ? { "aria-describedby": ariaDescribedBy } : {},
			"aria-readonly": String(readOnly)
		} }
	}, [resolvedExtensions, documentRevision]);
	(0, import_react.useEffect)(() => {
		if (!editor) return;
		const lastEmitted = lastEmittedRef.current;
		const propChanged = value !== previousValueRef.current;
		const acceptedUserEcho = lastEmitted !== null && value === lastEmitted && value === editor.getHTML();
		previousValueRef.current = value;
		if (acceptedUserEcho) {
			lastEmittedRef.current = null;
			return;
		}
		if (lastEmitted === null && !propChanged) return;
		lastEmittedRef.current = null;
		synchronizingRef.current = true;
		try {
			editor.chain().setMeta("addToHistory", false).setContent(value, { emitUpdate: false }).run();
		} finally {
			synchronizingRef.current = false;
		}
		resetDocumentState();
	});
	(0, import_react.useEffect)(() => {
		if (!editor) return;
		editor.setEditable(!readOnly, false);
	}, [editor, readOnly]);
	(0, import_react.useEffect)(() => {
		if (!editor) return;
		const root = editor.view.dom;
		root.setAttribute("dir", dir);
		root.setAttribute("aria-label", ariaLabel);
		root.setAttribute("aria-readonly", String(readOnly));
		if (ariaDescribedBy) root.setAttribute("aria-describedby", ariaDescribedBy);
		else root.removeAttribute("aria-describedby");
	}, [
		editor,
		dir,
		ariaLabel,
		ariaDescribedBy,
		readOnly
	]);
	const toolbarState = useToolbarState(editor);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className,
		children: [renderToolbar ? renderToolbar(toolbarState) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DefaultToolbar, { ...toolbarState }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorContent, { editor })]
	});
}
//#endregion
//#region ../../packages/ui-primitives/dist/Table.js
var tableClass = "w-full border-collapse text-fg text-sm";
var headClass = "border-b border-border bg-surface-raised";
var rowClass = "border-b border-border";
var cellClass = "px-3 py-2 text-left align-middle";
var thClass = cn(cellClass, "font-semibold text-fg");
var sortButtonClass = "inline-flex w-full items-center gap-1 bg-transparent text-inherit font-semibold focus-visible:outline focus-visible:outline-accent rounded-sm";
function TableRoot({ caption, children, className }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", {
		className: cn(tableClass, className),
		children: [caption ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("caption", {
			className: "px-3 py-2 text-left text-sm font-semibold text-fg",
			children: caption
		}) : null, children]
	});
}
function TableHead({ children, className, ...props }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", {
		className: cn(headClass, className),
		...props,
		children
	});
}
function TableBody({ children, className, ...props }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", {
		className,
		...props,
		children
	});
}
function TableRow({ children, className, ...props }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", {
		className: cn(rowClass, className),
		...props,
		children
	});
}
function TableTh({ scope = "col", sort, onSort, children, className, ...props }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
		scope,
		"aria-sort": sort === "asc" ? "ascending" : sort === "desc" ? "descending" : sort === "none" ? "none" : void 0,
		className: cn(thClass, className),
		...props,
		children: sort !== void 0 && onSort ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
			type: "button",
			className: sortButtonClass,
			onClick: onSort,
			children
		}) : children
	});
}
function TableTd({ children, className, ...props }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
		className: cn(cellClass, className),
		...props,
		children
	});
}
var Table = Object.assign(TableRoot, {
	Head: TableHead,
	Body: TableBody,
	Row: TableRow,
	Th: TableTh,
	Td: TableTd
});
//#endregion
//#region ../../node_modules/.pnpm/@radix-ui+react-checkbox@1.3.11_@types+react-dom@19.2.4_@types+react@19.2.18__@types+re_0286ed76b9cb6d4ff2f5578d2fdf0779/node_modules/@radix-ui/react-checkbox/dist/index.mjs
var __defProp$3 = Object.defineProperty;
var __name$3 = (target, value) => __defProp$3(target, "name", {
	value,
	configurable: true
});
var CHECKBOX_NAME = "Checkbox";
var [createCheckboxContext, createCheckboxScope] = createContextScope(CHECKBOX_NAME);
var [CheckboxProviderImpl, useCheckboxContext] = createCheckboxContext(CHECKBOX_NAME);
function CheckboxProvider(props) {
	const { __scopeCheckbox, checked: checkedProp, children, defaultChecked, disabled, form, name, onCheckedChange, required, value = "on", internal_do_not_use_render } = props;
	const [checked, setChecked] = useControllableState$1({
		prop: checkedProp,
		defaultProp: defaultChecked ?? false,
		onChange: onCheckedChange,
		caller: CHECKBOX_NAME
	});
	const [control, setControl] = import_react.useState(null);
	const [bubbleInput, setBubbleInput] = import_react.useState(null);
	const hasConsumerStoppedPropagationRef = import_react.useRef(false);
	const [userInteractionCount, onUserInteraction] = import_react.useReducer((count) => count + 1, 0);
	const isFormControl = control ? !!form || !!control.closest("form") : true;
	const context = {
		checked,
		disabled,
		setChecked,
		control,
		setControl,
		name,
		form,
		value,
		hasConsumerStoppedPropagationRef,
		userInteractionCount,
		onUserInteraction,
		required,
		defaultChecked: isIndeterminate(defaultChecked) ? false : defaultChecked,
		isFormControl,
		bubbleInput,
		setBubbleInput
	};
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxProviderImpl, {
		scope: __scopeCheckbox,
		...context,
		children: isFunction$2(internal_do_not_use_render) ? internal_do_not_use_render(context) : children
	});
}
__name$3(CheckboxProvider, "CheckboxProvider");
var TRIGGER_NAME$2 = "CheckboxTrigger";
var CheckboxTrigger = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$3(function CheckboxTrigger2({ __scopeCheckbox, onKeyDown, onClick, ...checkboxProps }, forwardedRef) {
	const { control, value, disabled, checked, required, setControl, setChecked, hasConsumerStoppedPropagationRef, onUserInteraction, isFormControl, bubbleInput } = useCheckboxContext(TRIGGER_NAME$2, __scopeCheckbox);
	const composedRefs = useComposedRefs(forwardedRef, setControl);
	const initialCheckedStateRef = import_react.useRef(checked);
	import_react.useEffect(() => {
		const form = control?.form;
		if (form) {
			const reset = /* @__PURE__ */ __name$3(() => setChecked(initialCheckedStateRef.current), "reset");
			form.addEventListener("reset", reset);
			return () => form.removeEventListener("reset", reset);
		}
	}, [control, setChecked]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.button, {
		type: "button",
		role: "checkbox",
		"aria-checked": isIndeterminate(checked) ? "mixed" : checked,
		"aria-required": required,
		"data-state": getState$2(checked),
		"data-disabled": disabled ? "" : void 0,
		disabled,
		value,
		...checkboxProps,
		ref: composedRefs,
		onKeyDown: composeEventHandlers(onKeyDown, (event) => {
			if (event.key === "Enter") event.preventDefault();
		}),
		onClick: composeEventHandlers(onClick, (event) => {
			onUserInteraction();
			setChecked((prevChecked) => isIndeterminate(prevChecked) ? true : !prevChecked);
			if (bubbleInput && isFormControl) {
				hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
				if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
			}
		})
	});
}, "CheckboxTrigger"));
var Checkbox$1 = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$3(function Checkbox2(props, forwardedRef) {
	const { __scopeCheckbox, name, checked, defaultChecked, required, disabled, value, onCheckedChange, form, ...checkboxProps } = props;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxProvider, {
		__scopeCheckbox,
		checked,
		defaultChecked,
		disabled,
		required,
		onCheckedChange,
		name,
		form,
		value,
		internal_do_not_use_render: ({ isFormControl }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxTrigger, {
			...checkboxProps,
			ref: forwardedRef,
			__scopeCheckbox
		}), isFormControl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxBubbleInput, { __scopeCheckbox })] })
	});
}, "Checkbox"));
var INDICATOR_NAME$1 = "CheckboxIndicator";
var CheckboxIndicator = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$3(function CheckboxIndicator2(props, forwardedRef) {
	const { __scopeCheckbox, forceMount, ...indicatorProps } = props;
	const context = useCheckboxContext(INDICATOR_NAME$1, __scopeCheckbox);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Presence, {
		present: forceMount || isIndeterminate(context.checked) || context.checked === true,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.span, {
			"data-state": getState$2(context.checked),
			"data-disabled": context.disabled ? "" : void 0,
			...indicatorProps,
			ref: forwardedRef,
			style: {
				pointerEvents: "none",
				...props.style
			}
		})
	});
}, "CheckboxIndicator"));
var BUBBLE_INPUT_NAME$2 = "CheckboxBubbleInput";
var CheckboxBubbleInput = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$3(function CheckboxBubbleInput2({ __scopeCheckbox, onClick, ...props }, forwardedRef) {
	const { control, hasConsumerStoppedPropagationRef, userInteractionCount, checked, defaultChecked, required, disabled, name, value, form, bubbleInput, setBubbleInput } = useCheckboxContext(BUBBLE_INPUT_NAME$2, __scopeCheckbox);
	const composedRefs = useComposedRefs(forwardedRef, setBubbleInput);
	const controlSize = useSize(control);
	const shouldStopClickPropagationRef = import_react.useRef(false);
	const prevCheckedRef = import_react.useRef(checked);
	const prevUserInteractionCountRef = import_react.useRef(userInteractionCount);
	import_react.useEffect(() => {
		const input = bubbleInput;
		if (!input) return;
		const inputProto = window.HTMLInputElement.prototype;
		const setChecked = Object.getOwnPropertyDescriptor(inputProto, "checked").set;
		const isUserInteraction = userInteractionCount !== prevUserInteractionCountRef.current;
		prevUserInteractionCountRef.current = userInteractionCount;
		const checkedChanged = prevCheckedRef.current !== checked;
		prevCheckedRef.current = checked;
		const bubbles = !(isUserInteraction && hasConsumerStoppedPropagationRef.current);
		if (checkedChanged && setChecked) {
			shouldStopClickPropagationRef.current = !isUserInteraction;
			const event = new Event("click", { bubbles });
			input.indeterminate = isIndeterminate(checked);
			setChecked.call(input, isIndeterminate(checked) ? false : checked);
			input.dispatchEvent(event);
			shouldStopClickPropagationRef.current = false;
		}
	}, [
		bubbleInput,
		checked,
		hasConsumerStoppedPropagationRef,
		userInteractionCount
	]);
	const defaultCheckedRef = import_react.useRef(isIndeterminate(checked) ? false : checked);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.input, {
		type: "checkbox",
		"aria-hidden": true,
		defaultChecked: defaultChecked ?? defaultCheckedRef.current,
		required,
		disabled,
		name,
		value,
		form,
		...props,
		tabIndex: -1,
		ref: composedRefs,
		onClick: composeEventHandlers(onClick, (event) => {
			if (shouldStopClickPropagationRef.current) event.stopPropagation();
		}),
		style: {
			...props.style,
			...controlSize,
			position: "absolute",
			pointerEvents: "none",
			opacity: 0,
			margin: 0,
			transform: "translateX(-100%)"
		}
	});
}, "CheckboxBubbleInput"));
function isFunction$2(value) {
	return typeof value === "function";
}
__name$3(isFunction$2, "isFunction");
function isIndeterminate(checked) {
	return checked === "indeterminate";
}
__name$3(isIndeterminate, "isIndeterminate");
function getState$2(checked) {
	return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
}
__name$3(getState$2, "getState");
//#endregion
//#region ../../packages/ui-primitives/dist/Checkbox.js
var Checkbox = import_react.forwardRef(({ id, className, ...props }, ref) => {
	const field = useFieldControl();
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Checkbox$1, {
		ref,
		id: id ?? field?.id,
		"aria-describedby": props["aria-describedby"] ?? field?.describedBy,
		className: cn("inline-flex h-[var(--mod-touch-min)] w-[var(--mod-touch-min)] items-center justify-center rounded-sm border border-border bg-surface text-[var(--mod-color-accent-contrast)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)] disabled:cursor-not-allowed disabled:opacity-[var(--mod-opacity-disabled)] data-[state=checked]:border-[var(--mod-color-accent-9)] data-[state=checked]:bg-[var(--mod-color-accent-9)] data-[state=checked]:hover:bg-[var(--mod-color-accent-10)] data-[state=checked]:active:bg-[var(--mod-color-accent-11)] data-[state=indeterminate]:border-[var(--mod-color-accent-9)] data-[state=indeterminate]:bg-[var(--mod-color-accent-9)]", className),
		...props,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
			viewBox: "0 0 16 16",
			className: "h-3 w-3",
			"aria-hidden": "true",
			fill: "none",
			stroke: "currentColor",
			strokeWidth: "2",
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 8l3.5 3.5L13 4" })
		}) })
	});
});
Checkbox.displayName = "Checkbox";
//#endregion
//#region ../../node_modules/.pnpm/@radix-ui+react-radio-group@1.4.7_@types+react-dom@19.2.4_@types+react@19.2.18__@types+_b823322bc0df4d21822582cd4f126928/node_modules/@radix-ui/react-radio-group/dist/index.mjs
var __defProp$2 = Object.defineProperty;
var __name$2 = (target, value) => __defProp$2(target, "name", {
	value,
	configurable: true
});
var RADIO_NAME = "Radio";
var [createRadioContext, createRadioScope] = createContextScope(RADIO_NAME);
var [RadioProviderImpl, useRadioContext] = createRadioContext(RADIO_NAME);
function RadioProvider(props) {
	const { __scopeRadio, checked = false, children, disabled, form, name, onCheck, required, value = "on", internal_do_not_use_render } = props;
	const [control, setControl] = import_react.useState(null);
	const [bubbleInput, setBubbleInput] = import_react.useState(null);
	const hasConsumerStoppedPropagationRef = import_react.useRef(false);
	const [userInteractionCount, onUserInteraction] = import_react.useReducer((count) => count + 1, 0);
	const context = {
		checked,
		disabled,
		required,
		name,
		form,
		value,
		control,
		setControl,
		hasConsumerStoppedPropagationRef,
		userInteractionCount,
		onUserInteraction,
		isFormControl: control ? !!form || !!control.closest("form") : true,
		bubbleInput,
		setBubbleInput,
		onCheck: /* @__PURE__ */ __name$2(() => onCheck?.(), "onCheck")
	};
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioProviderImpl, {
		scope: __scopeRadio,
		...context,
		children: isFunction$1(internal_do_not_use_render) ? internal_do_not_use_render(context) : children
	});
}
__name$2(RadioProvider, "RadioProvider");
var TRIGGER_NAME$1 = "RadioTrigger";
var RadioTrigger = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioTrigger2({ __scopeRadio, onClick, ...radioProps }, forwardedRef) {
	const { checked, disabled, value, setControl, onCheck, hasConsumerStoppedPropagationRef, onUserInteraction, isFormControl, bubbleInput } = useRadioContext(TRIGGER_NAME$1, __scopeRadio);
	const composedRefs = useComposedRefs(forwardedRef, setControl);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.button, {
		type: "button",
		role: "radio",
		"aria-checked": checked,
		"data-state": getState$1(checked),
		"data-disabled": disabled ? "" : void 0,
		disabled,
		value,
		...radioProps,
		ref: composedRefs,
		onClick: composeEventHandlers(onClick, (event) => {
			if (!checked) {
				onUserInteraction();
				onCheck();
			}
			if (bubbleInput && isFormControl) {
				hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
				if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
			}
		})
	});
}, "RadioTrigger"));
var INDICATOR_NAME = "RadioIndicator";
var RadioIndicator = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioIndicator2(props, forwardedRef) {
	const { __scopeRadio, forceMount, ...indicatorProps } = props;
	const context = useRadioContext(INDICATOR_NAME, __scopeRadio);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Presence, {
		present: forceMount || context.checked,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.span, {
			"data-state": getState$1(context.checked),
			"data-disabled": context.disabled ? "" : void 0,
			...indicatorProps,
			ref: forwardedRef
		})
	});
}, "RadioIndicator"));
var BUBBLE_INPUT_NAME$1 = "RadioBubbleInput";
var RadioBubbleInput = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioBubbleInput2({ __scopeRadio, onClick, ...props }, forwardedRef) {
	const { control, checked, required, disabled, name, value, form, bubbleInput, setBubbleInput, hasConsumerStoppedPropagationRef, userInteractionCount } = useRadioContext(BUBBLE_INPUT_NAME$1, __scopeRadio);
	const composedRefs = useComposedRefs(forwardedRef, setBubbleInput);
	const controlSize = useSize(control);
	const shouldStopClickPropagationRef = import_react.useRef(false);
	const prevCheckedRef = import_react.useRef(checked);
	const prevUserInteractionCountRef = import_react.useRef(userInteractionCount);
	import_react.useEffect(() => {
		const input = bubbleInput;
		if (!input) return;
		const inputProto = window.HTMLInputElement.prototype;
		const setChecked = Object.getOwnPropertyDescriptor(inputProto, "checked").set;
		const isUserInteraction = userInteractionCount !== prevUserInteractionCountRef.current;
		prevUserInteractionCountRef.current = userInteractionCount;
		const checkedChanged = prevCheckedRef.current !== checked;
		prevCheckedRef.current = checked;
		const bubbles = !(isUserInteraction && hasConsumerStoppedPropagationRef.current);
		if (checkedChanged && setChecked) {
			shouldStopClickPropagationRef.current = !isUserInteraction;
			const event = new Event("click", { bubbles });
			setChecked.call(input, checked);
			input.dispatchEvent(event);
			shouldStopClickPropagationRef.current = false;
		}
	}, [
		bubbleInput,
		checked,
		hasConsumerStoppedPropagationRef,
		userInteractionCount
	]);
	const defaultCheckedRef = import_react.useRef(checked);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.input, {
		type: "radio",
		"aria-hidden": true,
		defaultChecked: defaultCheckedRef.current,
		required,
		disabled,
		name,
		value,
		form,
		...props,
		tabIndex: -1,
		ref: composedRefs,
		onClick: composeEventHandlers(onClick, (event) => {
			if (shouldStopClickPropagationRef.current) event.stopPropagation();
		}),
		style: {
			...props.style,
			...controlSize,
			position: "absolute",
			pointerEvents: "none",
			opacity: 0,
			margin: 0,
			transform: "translateX(-100%)"
		}
	});
}, "RadioBubbleInput"));
function isFunction$1(value) {
	return typeof value === "function";
}
__name$2(isFunction$1, "isFunction");
function getState$1(checked) {
	return checked ? "checked" : "unchecked";
}
__name$2(getState$1, "getState");
var ARROW_KEYS = [
	"ArrowUp",
	"ArrowDown",
	"ArrowLeft",
	"ArrowRight"
];
var RADIO_GROUP_NAME = "RadioGroup";
var [createRadioGroupContext, createRadioGroupScope] = createContextScope(RADIO_GROUP_NAME, [createRovingFocusGroupScope, createRadioScope]);
var useRovingFocusGroupScope = createRovingFocusGroupScope();
var useRadioScope = createRadioScope();
var [RadioGroupProvider, useRadioGroupContext] = createRadioGroupContext(RADIO_GROUP_NAME);
var RadioGroup$1 = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioGroup2(props, forwardedRef) {
	const { __scopeRadioGroup, name, form, defaultValue, value: valueProp, required = false, disabled = false, orientation, dir, loop = true, onValueChange, ...groupProps } = props;
	const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeRadioGroup);
	const direction = useDirection(dir);
	const [value, setValue] = useControllableState$1({
		prop: valueProp,
		defaultProp: defaultValue ?? null,
		onChange: onValueChange,
		caller: RADIO_GROUP_NAME
	});
	const [control, setControl] = import_react.useState(null);
	const composedRefs = useComposedRefs(forwardedRef, setControl);
	const initialValueRef = import_react.useRef(value);
	import_react.useEffect(() => {
		const associatedForm = form ? control?.ownerDocument.getElementById(form) : control?.closest("form");
		if (associatedForm instanceof HTMLFormElement) {
			const reset = /* @__PURE__ */ __name$2(() => setValue(initialValueRef.current), "reset");
			associatedForm.addEventListener("reset", reset);
			return () => associatedForm.removeEventListener("reset", reset);
		}
	}, [
		control,
		form,
		setValue
	]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupProvider, {
		scope: __scopeRadioGroup,
		name,
		form,
		required,
		disabled,
		value,
		onValueChange: setValue,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root$1, {
			asChild: true,
			...rovingFocusGroupScope,
			orientation,
			dir: direction,
			loop,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.div, {
				role: "radiogroup",
				"aria-required": required,
				"aria-orientation": orientation,
				"data-disabled": disabled ? "" : void 0,
				dir: direction,
				...groupProps,
				ref: composedRefs
			})
		})
	});
}, "RadioGroup"));
var ITEM_PROVIDER_NAME = "RadioGroupItemProvider";
var ITEM_TRIGGER_NAME = "RadioGroupItemTrigger";
function RadioGroupItemProvider(props) {
	const { __scopeRadioGroup, value, disabled, children, internal_do_not_use_render } = props;
	const context = useRadioGroupContext(ITEM_PROVIDER_NAME, __scopeRadioGroup);
	const radioScope = useRadioScope(__scopeRadioGroup);
	const isDisabled = context.disabled || disabled;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioProvider, {
		...radioScope,
		checked: context.value === value,
		disabled: isDisabled,
		required: context.required,
		name: context.name,
		form: context.form,
		value,
		onCheck: () => context.onValueChange(value),
		internal_do_not_use_render,
		children
	});
}
__name$2(RadioGroupItemProvider, "RadioGroupItemProvider");
var RadioGroupItemTrigger = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioGroupItemTrigger2(props, forwardedRef) {
	const { __scopeRadioGroup, ...triggerProps } = props;
	const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeRadioGroup);
	const radioScope = useRadioScope(__scopeRadioGroup);
	const { checked, disabled } = useRadioContext(ITEM_TRIGGER_NAME, radioScope.__scopeRadio);
	const ref = import_react.useRef(null);
	const composedRefs = useComposedRefs(forwardedRef, ref);
	const isArrowKeyPressedRef = import_react.useRef(false);
	import_react.useEffect(() => {
		const handleKeyDown = /* @__PURE__ */ __name$2((event) => {
			if (ARROW_KEYS.includes(event.key)) isArrowKeyPressedRef.current = true;
		}, "handleKeyDown");
		const handleKeyUp = /* @__PURE__ */ __name$2(() => isArrowKeyPressedRef.current = false, "handleKeyUp");
		document.addEventListener("keydown", handleKeyDown);
		document.addEventListener("keyup", handleKeyUp);
		return () => {
			document.removeEventListener("keydown", handleKeyDown);
			document.removeEventListener("keyup", handleKeyUp);
		};
	}, []);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Item$1, {
		asChild: true,
		...rovingFocusGroupScope,
		focusable: !disabled,
		active: checked,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioTrigger, {
			...radioScope,
			...triggerProps,
			ref: composedRefs,
			onKeyDown: composeEventHandlers(triggerProps.onKeyDown, (event) => {
				if (event.key === "Enter") event.preventDefault();
			}),
			onFocus: composeEventHandlers(triggerProps.onFocus, () => {
				if (isArrowKeyPressedRef.current) ref.current?.click();
			})
		})
	});
}, "RadioGroupItemTrigger"));
var RadioGroupItem = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioGroupItem2(props, forwardedRef) {
	const { __scopeRadioGroup, value, disabled, ...itemProps } = props;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupItemProvider, {
		__scopeRadioGroup,
		value,
		disabled,
		internal_do_not_use_render: ({ isFormControl }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupItemTrigger, {
			...itemProps,
			ref: forwardedRef,
			__scopeRadioGroup
		}), isFormControl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupItemBubbleInput, { __scopeRadioGroup })] })
	});
}, "RadioGroupItem"));
var RadioGroupItemBubbleInput = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioGroupItemBubbleInput2(props, forwardedRef) {
	const { __scopeRadioGroup, ...bubbleProps } = props;
	const radioScope = useRadioScope(__scopeRadioGroup);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioBubbleInput, {
		...radioScope,
		...bubbleProps,
		ref: forwardedRef
	});
}, "RadioGroupItemBubbleInput"));
var RadioGroupIndicator = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$2(function RadioGroupIndicator2(props, forwardedRef) {
	const { __scopeRadioGroup, ...indicatorProps } = props;
	const radioScope = useRadioScope(__scopeRadioGroup);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioIndicator, {
		...radioScope,
		...indicatorProps,
		ref: forwardedRef
	});
}, "RadioGroupIndicator"));
//#endregion
//#region ../../packages/ui-primitives/dist/RadioGroup.js
function RadioGroup({ className, children, ...props }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroup$1, {
		className: cn("flex flex-col gap-2", className),
		...props,
		children
	});
}
var Radio = import_react.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupItem, {
	ref,
	className: cn("h-4 w-4 rounded-full border border-border bg-surface focus-visible:outline focus-visible:outline-accent disabled:opacity-50 disabled:cursor-not-allowed data-[state=checked]:border-accent", className),
	...props,
	children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupIndicator, { className: "flex h-full w-full items-center justify-center after:block after:h-2 after:w-2 after:rounded-full after:bg-accent" })
}));
Radio.displayName = "Radio";
//#endregion
//#region ../../packages/ui-primitives/dist/Skeleton.js
var variantClasses = {
	heading: "h-8 w-3/5 rounded",
	block: "h-48 w-full rounded",
	text: "h-4 w-full rounded",
	circle: "h-8 w-8 rounded-full"
};
function Skeleton({ variant = "text", className }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		role: "presentation",
		"aria-hidden": "true",
		className: cn("animate-pulse bg-surface", variantClasses[variant], className)
	});
}
//#endregion
//#region ../../node_modules/.pnpm/@radix-ui+react-switch@1.3.7_@types+react-dom@19.2.4_@types+react@19.2.18__@types+react_b402d7a5418ef2472f6ea07812019d6f/node_modules/@radix-ui/react-switch/dist/index.mjs
var __defProp$1 = Object.defineProperty;
var __name$1 = (target, value) => __defProp$1(target, "name", {
	value,
	configurable: true
});
var SWITCH_NAME = "Switch";
var [createSwitchContext, createSwitchScope] = createContextScope(SWITCH_NAME);
var [SwitchProviderImpl, useSwitchContext] = createSwitchContext(SWITCH_NAME);
function SwitchProvider(props) {
	const { __scopeSwitch, checked: checkedProp, children, defaultChecked, disabled, form, name, onCheckedChange, required, value = "on", internal_do_not_use_render } = props;
	const [checked, setChecked] = useControllableState$1({
		prop: checkedProp,
		defaultProp: defaultChecked ?? false,
		onChange: onCheckedChange,
		caller: SWITCH_NAME
	});
	const [control, setControl] = import_react.useState(null);
	const [bubbleInput, setBubbleInput] = import_react.useState(null);
	const hasConsumerStoppedPropagationRef = import_react.useRef(false);
	const [userInteractionCount, onUserInteraction] = import_react.useReducer((count) => count + 1, 0);
	const context = {
		checked,
		setChecked,
		disabled,
		control,
		setControl,
		name,
		form,
		value,
		hasConsumerStoppedPropagationRef,
		userInteractionCount,
		onUserInteraction,
		required,
		defaultChecked,
		isFormControl: control ? !!form || !!control.closest("form") : true,
		bubbleInput,
		setBubbleInput
	};
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchProviderImpl, {
		scope: __scopeSwitch,
		...context,
		children: isFunction(internal_do_not_use_render) ? internal_do_not_use_render(context) : children
	});
}
__name$1(SwitchProvider, "SwitchProvider");
var TRIGGER_NAME = "SwitchTrigger";
var SwitchTrigger = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$1(function SwitchTrigger2({ __scopeSwitch, onClick, ...switchProps }, forwardedRef) {
	const { control, form, value, disabled, checked, required, setControl, setChecked, hasConsumerStoppedPropagationRef, onUserInteraction, isFormControl, bubbleInput } = useSwitchContext(TRIGGER_NAME, __scopeSwitch);
	const composedRefs = useComposedRefs(forwardedRef, setControl);
	const initialCheckedStateRef = import_react.useRef(checked);
	import_react.useEffect(() => {
		const associatedForm = form ? control?.ownerDocument.getElementById(form) : control?.form;
		if (associatedForm instanceof HTMLFormElement) {
			const reset = /* @__PURE__ */ __name$1(() => setChecked(initialCheckedStateRef.current), "reset");
			associatedForm.addEventListener("reset", reset);
			return () => associatedForm.removeEventListener("reset", reset);
		}
	}, [
		control,
		form,
		setChecked
	]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.button, {
		type: "button",
		role: "switch",
		"aria-checked": checked,
		"aria-required": required,
		"data-state": getState(checked),
		"data-disabled": disabled ? "" : void 0,
		disabled,
		value,
		...switchProps,
		ref: composedRefs,
		onClick: composeEventHandlers(onClick, (event) => {
			onUserInteraction();
			setChecked((prevChecked) => !prevChecked);
			if (bubbleInput && isFormControl) {
				hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
				if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
			}
		})
	});
}, "SwitchTrigger"));
var Switch$1 = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$1(function Switch2(props, forwardedRef) {
	const { __scopeSwitch, name, checked, defaultChecked, required, disabled, value, onCheckedChange, form, ...switchProps } = props;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchProvider, {
		__scopeSwitch,
		checked,
		defaultChecked,
		disabled,
		required,
		onCheckedChange,
		name,
		form,
		value,
		internal_do_not_use_render: ({ isFormControl }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchTrigger, {
			...switchProps,
			ref: forwardedRef,
			__scopeSwitch
		}), isFormControl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchBubbleInput, { __scopeSwitch })] })
	});
}, "Switch"));
var THUMB_NAME = "SwitchThumb";
var SwitchThumb = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$1(function SwitchThumb2(props, forwardedRef) {
	const { __scopeSwitch, ...thumbProps } = props;
	const context = useSwitchContext(THUMB_NAME, __scopeSwitch);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.span, {
		"data-state": getState(context.checked),
		"data-disabled": context.disabled ? "" : void 0,
		...thumbProps,
		ref: forwardedRef
	});
}, "SwitchThumb"));
var BUBBLE_INPUT_NAME = "SwitchBubbleInput";
var SwitchBubbleInput = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name$1(function SwitchBubbleInput2({ __scopeSwitch, onClick, ...props }, forwardedRef) {
	const { control, hasConsumerStoppedPropagationRef, userInteractionCount, checked, defaultChecked, required, disabled, name, value, form, bubbleInput, setBubbleInput } = useSwitchContext(BUBBLE_INPUT_NAME, __scopeSwitch);
	const composedRefs = useComposedRefs(forwardedRef, setBubbleInput);
	const controlSize = useSize(control);
	const shouldStopClickPropagationRef = import_react.useRef(false);
	const prevCheckedRef = import_react.useRef(checked);
	const prevUserInteractionCountRef = import_react.useRef(userInteractionCount);
	import_react.useEffect(() => {
		const input = bubbleInput;
		if (!input) return;
		const inputProto = window.HTMLInputElement.prototype;
		const setChecked = Object.getOwnPropertyDescriptor(inputProto, "checked").set;
		const isUserInteraction = userInteractionCount !== prevUserInteractionCountRef.current;
		prevUserInteractionCountRef.current = userInteractionCount;
		const checkedChanged = prevCheckedRef.current !== checked;
		prevCheckedRef.current = checked;
		const bubbles = !(isUserInteraction && hasConsumerStoppedPropagationRef.current);
		if (checkedChanged && setChecked) {
			shouldStopClickPropagationRef.current = !isUserInteraction;
			const event = new Event("click", { bubbles });
			setChecked.call(input, checked);
			input.dispatchEvent(event);
			shouldStopClickPropagationRef.current = false;
		}
	}, [
		bubbleInput,
		checked,
		hasConsumerStoppedPropagationRef,
		userInteractionCount
	]);
	const defaultCheckedRef = import_react.useRef(checked);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.input, {
		type: "checkbox",
		"aria-hidden": true,
		defaultChecked: defaultChecked ?? defaultCheckedRef.current,
		required,
		disabled,
		name,
		value,
		form,
		...props,
		tabIndex: -1,
		ref: composedRefs,
		onClick: composeEventHandlers(onClick, (event) => {
			if (shouldStopClickPropagationRef.current) event.stopPropagation();
		}),
		style: {
			...props.style,
			...controlSize,
			position: "absolute",
			pointerEvents: "none",
			opacity: 0,
			margin: 0,
			transform: "translateX(-100%)"
		}
	});
}, "SwitchBubbleInput"));
function isFunction(value) {
	return typeof value === "function";
}
__name$1(isFunction, "isFunction");
function getState(checked) {
	return checked ? "checked" : "unchecked";
}
__name$1(getState, "getState");
//#endregion
//#region ../../packages/ui-primitives/dist/Switch.js
var Switch = import_react.forwardRef(({ id, className, ...props }, ref) => {
	const field = useFieldControl();
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch$1, {
		ref,
		id: id ?? field?.id,
		"aria-describedby": props["aria-describedby"] ?? field?.describedBy,
		className: cn("inline-flex h-5 w-9 items-center rounded-full border border-border bg-surface px-0.5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed data-[state=checked]:bg-accent", className),
		...props,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SwitchThumb, { className: "block h-4 w-4 rounded-full bg-fg transition-transform data-[state=checked]:translate-x-4" })
	});
});
Switch.displayName = "Switch";
//#endregion
//#region ../../packages/ui-primitives/dist/Pagination.js
var btn = "rounded-md border border-border bg-surface px-2 py-1 text-sm text-fg disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline focus-visible:outline-accent";
function Pagination({ page, pageCount, onPageChange, label = "Pagination", className }) {
	const canPrev = page > 1;
	const canNext = page < pageCount;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("nav", {
		"aria-label": label,
		className: cn("flex items-center gap-2", className),
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				className: btn,
				disabled: !canPrev,
				onClick: () => canPrev && onPageChange(page - 1),
				children: "Previous"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
				"aria-current": "page",
				className: "text-sm text-fg",
				children: [
					page,
					" / ",
					pageCount
				]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				className: btn,
				disabled: !canNext,
				onClick: () => canNext && onPageChange(page + 1),
				children: "Next"
			})
		]
	});
}
//#endregion
//#region ../../packages/ui-primitives/dist/DataTable.js
function withSorting(options = {}) {
	return {
		kind: "sorting",
		options
	};
}
function withSearch(options = {}) {
	return {
		kind: "search",
		options
	};
}
function withPagination(options) {
	return {
		kind: "pagination",
		options
	};
}
var MIN_WIDTH_DEFAULT = 48;
var KEYBOARD_RESIZE_STEP = 16;
function useControllableState(controlled, defaultValue, onChange) {
	const [internal, setInternal] = import_react.useState(defaultValue);
	return [controlled !== void 0 ? controlled : internal, import_react.useCallback((next) => {
		if (controlled === void 0) setInternal(next);
		onChange?.(next);
	}, [controlled, onChange])];
}
function pickCapability(capabilities, kind) {
	if (!capabilities) return void 0;
	for (let i = capabilities.length - 1; i >= 0; i--) {
		const capability = capabilities[i];
		if (capability?.kind === kind && "options" in capability) return capability.options;
	}
}
function accessorValue(row, column) {
	return row[column.id];
}
function defaultCell(row, column) {
	const value = accessorValue(row, column);
	return value === null || value === void 0 ? "" : String(value);
}
function sortKey(row, column) {
	if (column.sortValue) return column.sortValue(row);
	const value = accessorValue(row, column);
	if (value === null || value === void 0) return null;
	return typeof value === "number" ? value : String(value);
}
function searchKey(row, column) {
	if (column.searchValue) return column.searchValue(row);
	const value = accessorValue(row, column);
	return value === null || value === void 0 ? "" : String(value);
}
function compareKeys(a, b) {
	if (typeof a === "number" && typeof b === "number") return a - b;
	return String(a).localeCompare(String(b));
}
function ResizeHandle({ columnLabel, width, minWidth, onResize }) {
	const dragOrigin = import_react.useRef(null);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
		role: "separator",
		"aria-orientation": "vertical",
		"aria-label": `Resize ${columnLabel} column`,
		"aria-valuenow": Math.round(width),
		"aria-valuemin": minWidth,
		tabIndex: 0,
		className: "absolute inset-y-0 right-0 w-2 cursor-col-resize touch-none select-none focus-visible:outline focus-visible:outline-accent",
		onKeyDown: (event) => {
			if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
				event.preventDefault();
				const delta = event.key === "ArrowRight" ? KEYBOARD_RESIZE_STEP : -16;
				onResize(Math.max(minWidth, width + delta));
			}
		},
		onPointerDown: (event) => {
			event.preventDefault();
			dragOrigin.current = {
				pointerX: event.clientX,
				startWidth: width
			};
			event.currentTarget.setPointerCapture(event.pointerId);
		},
		onPointerMove: (event) => {
			if (!dragOrigin.current) return;
			const next = dragOrigin.current.startWidth + (event.clientX - dragOrigin.current.pointerX);
			onResize(Math.max(minWidth, next));
		},
		onPointerUp: (event) => {
			dragOrigin.current = null;
			event.currentTarget.releasePointerCapture(event.pointerId);
		}
	});
}
function DataTable({ caption, columns, rows, getRowId, capabilities, loading = false, error = null, onRetry, emptyState = "No results.", className }) {
	const searchId = import_react.useId();
	const sorting = pickCapability(capabilities, "sorting");
	const search = pickCapability(capabilities, "search");
	const resizing = pickCapability(capabilities, "resizing");
	const pagination = pickCapability(capabilities, "pagination");
	const [sort, setSort] = useControllableState(sorting?.sort, sorting?.defaultSort ?? null, sorting?.onSortChange);
	const [query, setQuery] = useControllableState(search?.query, search?.defaultQuery ?? "", search?.onQueryChange);
	const [page, setPage] = useControllableState(pagination?.page, pagination?.defaultPage ?? 1, pagination?.onPageChange);
	const [widths, setWidths] = useControllableState(resizing?.widths, resizing?.defaultWidths ?? {}, resizing?.onWidthsChange);
	const filtered = import_react.useMemo(() => {
		if (!search || search.manual || query.trim() === "") return rows;
		const needle = query.trim().toLowerCase();
		return rows.filter((row) => columns.some((column) => searchKey(row, column).toLowerCase().includes(needle)));
	}, [
		rows,
		columns,
		query,
		search
	]);
	const sorted = import_react.useMemo(() => {
		if (!sorting || sorting.manual || !sort) return filtered;
		const column = columns.find((c) => c.id === sort.columnId);
		if (!column) return filtered;
		const direction = sort.direction === "asc" ? 1 : -1;
		return filtered.map((row, index) => ({
			row,
			index
		})).sort((a, b) => {
			const keyA = sortKey(a.row, column);
			const keyB = sortKey(b.row, column);
			if (keyA === null || keyB === null) {
				if (keyA === null && keyB === null) return a.index - b.index;
				return keyA === null ? 1 : -1;
			}
			const order = compareKeys(keyA, keyB);
			return order !== 0 ? order * direction : a.index - b.index;
		}).map((entry) => entry.row);
	}, [
		filtered,
		columns,
		sort,
		sorting
	]);
	const clientPaginated = pagination !== void 0 && !pagination.manual && pagination.pageSize !== void 0;
	const pageCount = pagination?.manual ? pagination.pageCount : clientPaginated && pagination?.pageSize !== void 0 ? Math.max(1, Math.ceil(sorted.length / pagination.pageSize)) : 1;
	const effectivePage = clientPaginated ? Math.min(page, pageCount) : page;
	const paginated = import_react.useMemo(() => {
		if (!clientPaginated || pagination?.pageSize === void 0) return sorted;
		return sorted.slice((effectivePage - 1) * pagination.pageSize, effectivePage * pagination.pageSize);
	}, [
		sorted,
		effectivePage,
		clientPaginated,
		pagination?.pageSize
	]);
	const showPagination = pagination !== void 0 && (pagination.manual === true || pageCount > 1);
	function resetToFirstPage() {
		if (clientPaginated) setPage(1);
	}
	function cycleSort(columnId) {
		if (!sort || sort.columnId !== columnId) setSort({
			columnId,
			direction: "asc"
		});
		else setSort(sort.direction === "asc" ? {
			columnId,
			direction: "desc"
		} : null);
		resetToFirstPage();
	}
	function updateQuery(next) {
		setQuery(next);
		resetToFirstPage();
	}
	const anyWidth = resizing !== void 0 && columns.some((column) => widths[column.id] !== void 0 || column.width !== void 0);
	function columnLabel(column) {
		return typeof column.header === "string" ? column.header : column.id;
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: cn("flex flex-col gap-3", className),
		"aria-busy": loading || void 0,
		children: [
			search ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex flex-col gap-1",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
					htmlFor: searchId,
					className: "text-sm font-semibold text-fg",
					children: search.label ?? "Search"
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
					id: searchId,
					type: "search",
					size: "sm",
					value: query,
					onChange: (event) => updateQuery(event.currentTarget.value)
				})]
			}) : null,
			search ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				role: "status",
				"aria-live": "polite",
				className: "sr-only",
				children: loading || error ? "" : `${sorted.length} results`
			}) : null,
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
				variant: "inline",
				title: "Data couldn't load",
				message: error,
				action: onRetry ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					radius: "sm",
					size: "sm",
					type: "button",
					onClick: onRetry,
					children: "Try again"
				}) : void 0
			}) : loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex flex-col gap-2",
				"aria-hidden": "true",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
			}) : paginated.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "text-sm text-fg-muted",
				children: emptyState
			}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "overflow-x-auto",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
					caption,
					className: anyWidth ? "table-fixed" : void 0,
					children: [
						anyWidth ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("colgroup", { children: columns.map((column) => {
							const width = widths[column.id] ?? column.width;
							return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("col", { style: width !== void 0 ? { width: `${width}px` } : void 0 }, column.id);
						}) }) : null,
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Row, { children: columns.map((column) => {
							const sortEnabled = sorting !== void 0 && column.sortable === true;
							const isSorted = sort?.columnId === column.id;
							const resizeEnabled = resizing !== void 0 && column.resizable === true;
							const width = widths[column.id] ?? column.width ?? 0;
							return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Th, {
								scope: "col",
								className: resizeEnabled ? "relative" : void 0,
								sort: sortEnabled ? isSorted && sort ? sort.direction : "none" : void 0,
								onSort: sortEnabled ? () => cycleSort(column.id) : void 0,
								children: [column.header, resizeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ResizeHandle, {
									columnLabel: columnLabel(column),
									width: width || (column.minWidth ?? MIN_WIDTH_DEFAULT),
									minWidth: column.minWidth ?? MIN_WIDTH_DEFAULT,
									onResize: (next) => setWidths({
										...widths,
										[column.id]: next
									})
								}) : null]
							}, column.id);
						}) }) }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: paginated.map((row) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Row, { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: column.cell ? column.cell(row) : defaultCell(row, column) }, column.id)) }, getRowId(row))) })
					]
				})
			}),
			!error && !loading && showPagination ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pagination, {
				page: effectivePage,
				pageCount,
				onPageChange: setPage,
				label: pagination?.label ?? `${caption} pagination`
			}) : null
		]
	});
}
//#endregion
//#region ../../packages/ui-primitives/dist/DashboardShell.js
var DASHBOARD_MAIN_ID = "dashboard-main";
var DASHBOARD_SIDEBAR_ID = "dashboard-sidebar";
function DashboardShell({ sidebar, topbar, children, sidebarCollapsed = false, onSidebarToggle }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex min-h-screen flex-col bg-bg text-fg md:flex-row",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				href: `#${DASHBOARD_MAIN_ID}`,
				className: "sr-only focus:not-sr-only focus:absolute focus:left-0 focus:top-0 focus:z-50 focus:bg-surface focus:text-fg focus:outline focus:outline-accent focus:p-2",
				children: "Skip to main content"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("nav", {
				id: DASHBOARD_SIDEBAR_ID,
				"aria-label": "Sidebar",
				className: cn("border-b border-border bg-surface md:border-b-0 md:border-r", sidebarCollapsed ? "hidden md:block" : "block"),
				children: [onSidebarToggle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
					type: "button",
					className: "w-full border-b border-border bg-surface-raised px-3 py-2 text-left text-sm font-medium text-fg focus-visible:outline focus-visible:outline-accent md:hidden",
					"aria-expanded": !sidebarCollapsed,
					"aria-controls": DASHBOARD_SIDEBAR_ID,
					onClick: onSidebarToggle,
					children: "Toggle sidebar"
				}) : null, sidebar]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex min-w-0 flex-1 flex-col",
				children: [topbar ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", {
					role: "banner",
					children: topbar
				}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("main", {
					id: DASHBOARD_MAIN_ID,
					className: "flex-1 p-4",
					children
				})]
			})
		]
	});
}
//#endregion
//#region ../../node_modules/.pnpm/@radix-ui+react-toast@1.2.23_@types+react-dom@19.2.4_@types+react@19.2.18__@types+react_389fefb98ea202e36086ffa04eb2bec2/node_modules/@radix-ui/react-toast/dist/index.mjs
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", {
	value,
	configurable: true
});
var PROVIDER_NAME = "ToastProvider";
var [Collection, useCollection, createCollectionScope] = createCollection("Toast");
var [createToastContext, createToastScope] = createContextScope("Toast", [createCollectionScope]);
var [ToastProviderProvider, useToastProviderContext] = createToastContext(PROVIDER_NAME);
var ToastProvider$1 = /* @__PURE__ */ __name((props) => {
	const { __scopeToast, label = "Notification", duration = 5e3, swipeDirection = "right", swipeThreshold = 50, announcerContainer, children } = props;
	const [viewport, setViewport] = import_react.useState(null);
	const [toastCount, setToastCount] = import_react.useState(0);
	const isClosePausedRef = import_react.useRef(false);
	if (!label.trim()) console.error(`Invalid prop \`label\` supplied to \`${PROVIDER_NAME}\`. Expected non-empty \`string\`.`);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Provider, {
		scope: __scopeToast,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastProviderProvider, {
			scope: __scopeToast,
			label,
			duration,
			swipeDirection,
			swipeThreshold,
			toastCount,
			viewport,
			onViewportChange: setViewport,
			onToastAdd: import_react.useCallback(() => setToastCount((prevCount) => prevCount + 1), []),
			onToastRemove: import_react.useCallback(() => setToastCount((prevCount) => prevCount - 1), []),
			isClosePausedRef,
			announcerContainer,
			children
		})
	});
}, "ToastProvider");
var VIEWPORT_NAME = "ToastViewport";
var VIEWPORT_DEFAULT_HOTKEY = ["F8"];
var VIEWPORT_PAUSE = "toast.viewportPause";
var VIEWPORT_RESUME = "toast.viewportResume";
var ToastViewport = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function ToastViewport2(props, forwardedRef) {
	const { __scopeToast, hotkey = VIEWPORT_DEFAULT_HOTKEY, label = "Notifications ({hotkey})", ...viewportProps } = props;
	const context = useToastProviderContext(VIEWPORT_NAME, __scopeToast);
	const getItems = useCollection(__scopeToast);
	const wrapperRef = import_react.useRef(null);
	const headFocusProxyRef = import_react.useRef(null);
	const tailFocusProxyRef = import_react.useRef(null);
	const ref = import_react.useRef(null);
	const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange);
	const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
	const hasToasts = context.toastCount > 0;
	import_react.useEffect(() => {
		const handleKeyDown = /* @__PURE__ */ __name((event) => {
			if (hotkey.length !== 0 && hotkey.every((key) => event[key] || event.code === key)) ref.current?.focus();
		}, "handleKeyDown");
		document.addEventListener("keydown", handleKeyDown);
		return () => document.removeEventListener("keydown", handleKeyDown);
	}, [hotkey]);
	import_react.useEffect(() => {
		const wrapper = wrapperRef.current;
		const viewport = ref.current;
		if (hasToasts && wrapper && viewport) {
			const handlePause = /* @__PURE__ */ __name(() => {
				if (!context.isClosePausedRef.current) {
					const pauseEvent = new CustomEvent(VIEWPORT_PAUSE);
					viewport.dispatchEvent(pauseEvent);
					context.isClosePausedRef.current = true;
				}
			}, "handlePause");
			const handleResume = /* @__PURE__ */ __name(() => {
				if (context.isClosePausedRef.current) {
					const resumeEvent = new CustomEvent(VIEWPORT_RESUME);
					viewport.dispatchEvent(resumeEvent);
					context.isClosePausedRef.current = false;
				}
			}, "handleResume");
			const handleFocusOutResume = /* @__PURE__ */ __name((event) => {
				if (!wrapper.contains(event.relatedTarget)) handleResume();
			}, "handleFocusOutResume");
			const handlePointerLeaveResume = /* @__PURE__ */ __name(() => {
				if (!wrapper.contains(document.activeElement)) handleResume();
			}, "handlePointerLeaveResume");
			wrapper.addEventListener("focusin", handlePause);
			wrapper.addEventListener("focusout", handleFocusOutResume);
			wrapper.addEventListener("pointermove", handlePause);
			wrapper.addEventListener("pointerleave", handlePointerLeaveResume);
			window.addEventListener("blur", handlePause);
			window.addEventListener("focus", handleResume);
			return () => {
				wrapper.removeEventListener("focusin", handlePause);
				wrapper.removeEventListener("focusout", handleFocusOutResume);
				wrapper.removeEventListener("pointermove", handlePause);
				wrapper.removeEventListener("pointerleave", handlePointerLeaveResume);
				window.removeEventListener("blur", handlePause);
				window.removeEventListener("focus", handleResume);
			};
		}
	}, [hasToasts, context.isClosePausedRef]);
	const getSortedTabbableCandidates = import_react.useCallback(({ tabbingDirection }) => {
		const tabbableCandidates = getItems().map((toastItem) => {
			const toastNode = toastItem.ref.current;
			const toastTabbableCandidates = [toastNode, ...getTabbableCandidates(toastNode)];
			return tabbingDirection === "forwards" ? toastTabbableCandidates : toastTabbableCandidates.reverse();
		});
		return (tabbingDirection === "forwards" ? tabbableCandidates.reverse() : tabbableCandidates).flat();
	}, [getItems]);
	import_react.useEffect(() => {
		const viewport = ref.current;
		if (viewport) {
			const handleKeyDown = /* @__PURE__ */ __name((event) => {
				const isMetaKey = event.altKey || event.ctrlKey || event.metaKey;
				if (event.key === "Tab" && !isMetaKey) {
					const focusedElement = document.activeElement;
					const isTabbingBackwards = event.shiftKey;
					if (event.target === viewport && isTabbingBackwards) {
						headFocusProxyRef.current?.focus();
						return;
					}
					const sortedCandidates = getSortedTabbableCandidates({ tabbingDirection: isTabbingBackwards ? "backwards" : "forwards" });
					const index = sortedCandidates.findIndex((candidate) => candidate === focusedElement);
					if (focusFirst(sortedCandidates.slice(index + 1))) event.preventDefault();
					else isTabbingBackwards ? headFocusProxyRef.current?.focus() : tailFocusProxyRef.current?.focus();
				}
			}, "handleKeyDown");
			viewport.addEventListener("keydown", handleKeyDown);
			return () => viewport.removeEventListener("keydown", handleKeyDown);
		}
	}, [getItems, getSortedTabbableCandidates]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Branch$1, {
		ref: wrapperRef,
		role: "region",
		"aria-label": label.replace("{hotkey}", hotkeyLabel),
		tabIndex: -1,
		style: { pointerEvents: hasToasts ? void 0 : "none" },
		children: [
			hasToasts && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FocusProxy, {
				ref: headFocusProxyRef,
				onFocusFromOutsideViewport: () => {
					focusFirst(getSortedTabbableCandidates({ tabbingDirection: "forwards" }));
				}
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.Slot, {
				scope: __scopeToast,
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.ol, {
					tabIndex: -1,
					...viewportProps,
					ref: composedRefs
				})
			}),
			hasToasts && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FocusProxy, {
				ref: tailFocusProxyRef,
				onFocusFromOutsideViewport: () => {
					focusFirst(getSortedTabbableCandidates({ tabbingDirection: "backwards" }));
				}
			})
		]
	});
}, "ToastViewport"));
var FOCUS_PROXY_NAME = "ToastFocusProxy";
var FocusProxy = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function ToastFocusProxy(props, forwardedRef) {
	const { __scopeToast, onFocusFromOutsideViewport, ...proxyProps } = props;
	const context = useToastProviderContext(FOCUS_PROXY_NAME, __scopeToast);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VisuallyHidden, {
		tabIndex: 0,
		...proxyProps,
		ref: forwardedRef,
		style: { position: "fixed" },
		onFocus: (event) => {
			const prevFocusedElement = event.relatedTarget;
			if (!context.viewport?.contains(prevFocusedElement)) onFocusFromOutsideViewport();
		}
	});
}, "ToastFocusProxy"));
var TOAST_NAME = "Toast";
var TOAST_SWIPE_START = "toast.swipeStart";
var TOAST_SWIPE_MOVE = "toast.swipeMove";
var TOAST_SWIPE_CANCEL = "toast.swipeCancel";
var TOAST_SWIPE_END = "toast.swipeEnd";
var Toast = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function Toast2(props, forwardedRef) {
	const { forceMount, open: openProp, defaultOpen, onOpenChange, ...toastProps } = props;
	const [open, setOpen] = useControllableState$1({
		prop: openProp,
		defaultProp: defaultOpen ?? true,
		onChange: onOpenChange,
		caller: TOAST_NAME
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Presence, {
		present: forceMount || open,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastImpl, {
			open,
			...toastProps,
			ref: forwardedRef,
			onClose: () => setOpen(false),
			onPause: useCallbackRef(props.onPause),
			onResume: useCallbackRef(props.onResume),
			onSwipeStart: composeEventHandlers(props.onSwipeStart, (event) => {
				event.currentTarget.setAttribute("data-swipe", "start");
			}),
			onSwipeMove: composeEventHandlers(props.onSwipeMove, (event) => {
				const { x, y } = event.detail.delta;
				event.currentTarget.setAttribute("data-swipe", "move");
				event.currentTarget.style.setProperty("--radix-toast-swipe-move-x", `${x}px`);
				event.currentTarget.style.setProperty("--radix-toast-swipe-move-y", `${y}px`);
			}),
			onSwipeCancel: composeEventHandlers(props.onSwipeCancel, (event) => {
				event.currentTarget.setAttribute("data-swipe", "cancel");
				event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
				event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
				event.currentTarget.style.removeProperty("--radix-toast-swipe-end-x");
				event.currentTarget.style.removeProperty("--radix-toast-swipe-end-y");
			}),
			onSwipeEnd: composeEventHandlers(props.onSwipeEnd, (event) => {
				const { x, y } = event.detail.delta;
				event.currentTarget.setAttribute("data-swipe", "end");
				event.currentTarget.style.removeProperty("--radix-toast-swipe-move-x");
				event.currentTarget.style.removeProperty("--radix-toast-swipe-move-y");
				event.currentTarget.style.setProperty("--radix-toast-swipe-end-x", `${x}px`);
				event.currentTarget.style.setProperty("--radix-toast-swipe-end-y", `${y}px`);
				setOpen(false);
			})
		})
	});
}, "Toast"));
var [ToastInteractiveProvider, useToastInteractiveContext] = createToastContext(TOAST_NAME, { onClose() {} });
var ToastImpl = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function ToastImpl2(props, forwardedRef) {
	const { __scopeToast, type = "foreground", duration: durationProp, open, onClose, onEscapeKeyDown, onPause, onResume, onSwipeStart, onSwipeMove, onSwipeCancel, onSwipeEnd, ...toastProps } = props;
	const context = useToastProviderContext(TOAST_NAME, __scopeToast);
	const getItems = useCollection(__scopeToast);
	const [node, setNode] = import_react.useState(null);
	const composedRefs = useComposedRefs(forwardedRef, setNode);
	const pointerStartRef = import_react.useRef(null);
	const swipeDeltaRef = import_react.useRef(null);
	const duration = durationProp || context.duration;
	const closeTimerStartTimeRef = import_react.useRef(0);
	const closeTimerRemainingTimeRef = import_react.useRef(duration);
	const closeTimerRef = import_react.useRef(0);
	const { onToastAdd, onToastRemove } = context;
	const handleClose = useCallbackRef(() => {
		if (node?.contains(document.activeElement)) context.viewport?.focus();
		onClose();
	});
	const startTimer = import_react.useCallback((duration2) => {
		if (!duration2 || duration2 === Infinity) return;
		window.clearTimeout(closeTimerRef.current);
		closeTimerStartTimeRef.current = (/* @__PURE__ */ new Date()).getTime();
		closeTimerRef.current = window.setTimeout(handleClose, duration2);
	}, [handleClose]);
	import_react.useEffect(() => {
		const viewport = context.viewport;
		if (viewport) {
			const handleResume = /* @__PURE__ */ __name(() => {
				startTimer(closeTimerRemainingTimeRef.current);
				onResume?.();
			}, "handleResume");
			const handlePause = /* @__PURE__ */ __name(() => {
				const elapsedTime = (/* @__PURE__ */ new Date()).getTime() - closeTimerStartTimeRef.current;
				closeTimerRemainingTimeRef.current = closeTimerRemainingTimeRef.current - elapsedTime;
				window.clearTimeout(closeTimerRef.current);
				onPause?.();
			}, "handlePause");
			viewport.addEventListener(VIEWPORT_PAUSE, handlePause);
			viewport.addEventListener(VIEWPORT_RESUME, handleResume);
			return () => {
				viewport.removeEventListener(VIEWPORT_PAUSE, handlePause);
				viewport.removeEventListener(VIEWPORT_RESUME, handleResume);
			};
		}
	}, [
		context.viewport,
		duration,
		onPause,
		onResume,
		startTimer
	]);
	import_react.useEffect(() => {
		if (open && !context.isClosePausedRef.current) startTimer(duration);
	}, [
		open,
		duration,
		context.isClosePausedRef,
		startTimer
	]);
	import_react.useEffect(() => {
		return () => {
			window.clearTimeout(closeTimerRef.current);
		};
	}, []);
	import_react.useEffect(() => {
		onToastAdd();
		return () => onToastRemove();
	}, [onToastAdd, onToastRemove]);
	const announceTextContent = import_react.useMemo(() => {
		return node ? getAnnounceTextContent(node) : null;
	}, [node]);
	if (!context.viewport) return null;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [announceTextContent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastAnnounce, {
		__scopeToast,
		role: "status",
		"aria-live": type === "foreground" ? "assertive" : "polite",
		children: announceTextContent
	}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastInteractiveProvider, {
		scope: __scopeToast,
		onClose: handleClose,
		children: import_react_dom.createPortal(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collection.ItemSlot, {
			scope: __scopeToast,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root$2, {
				asChild: true,
				onEscapeKeyDown: composeEventHandlers(onEscapeKeyDown, (event) => {
					if (!getItems().some((item) => item.ref.current?.contains(event.target))) handleClose();
				}),
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.li, {
					tabIndex: 0,
					"data-state": open ? "open" : "closed",
					"data-swipe-direction": context.swipeDirection,
					...toastProps,
					ref: composedRefs,
					style: {
						userSelect: "none",
						touchAction: "none",
						...props.style
					},
					onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
						if (event.key !== "Escape") return;
						onEscapeKeyDown?.(event.nativeEvent);
						if (!event.nativeEvent.defaultPrevented) handleClose();
					}),
					onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
						if (event.button !== 0) return;
						pointerStartRef.current = {
							x: event.clientX,
							y: event.clientY
						};
					}),
					onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
						if (!pointerStartRef.current) return;
						const x = event.clientX - pointerStartRef.current.x;
						const y = event.clientY - pointerStartRef.current.y;
						const hasSwipeMoveStarted = Boolean(swipeDeltaRef.current);
						const isHorizontalSwipe = ["left", "right"].includes(context.swipeDirection);
						const clamp = ["left", "up"].includes(context.swipeDirection) ? Math.min : Math.max;
						const clampedX = isHorizontalSwipe ? clamp(0, x) : 0;
						const clampedY = !isHorizontalSwipe ? clamp(0, y) : 0;
						const moveStartBuffer = event.pointerType === "touch" ? 10 : 2;
						const delta = {
							x: clampedX,
							y: clampedY
						};
						const eventDetail = {
							originalEvent: event,
							delta
						};
						if (hasSwipeMoveStarted) {
							swipeDeltaRef.current = delta;
							handleAndDispatchCustomEvent(TOAST_SWIPE_MOVE, onSwipeMove, eventDetail, { discrete: false });
						} else if (isDeltaInDirection(delta, context.swipeDirection, moveStartBuffer)) {
							swipeDeltaRef.current = delta;
							handleAndDispatchCustomEvent(TOAST_SWIPE_START, onSwipeStart, eventDetail, { discrete: false });
							event.target.setPointerCapture(event.pointerId);
						} else if (Math.abs(x) > moveStartBuffer || Math.abs(y) > moveStartBuffer) pointerStartRef.current = null;
					}),
					onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
						const delta = swipeDeltaRef.current;
						const target = event.target;
						if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
						swipeDeltaRef.current = null;
						pointerStartRef.current = null;
						if (delta) {
							const toast = event.currentTarget;
							const eventDetail = {
								originalEvent: event,
								delta
							};
							if (isDeltaInDirection(delta, context.swipeDirection, context.swipeThreshold)) handleAndDispatchCustomEvent(TOAST_SWIPE_END, onSwipeEnd, eventDetail, { discrete: true });
							else handleAndDispatchCustomEvent(TOAST_SWIPE_CANCEL, onSwipeCancel, eventDetail, { discrete: true });
							toast.addEventListener("click", (event2) => event2.preventDefault(), { once: true });
						}
					})
				})
			})
		}), context.viewport)
	})] });
}, "ToastImpl"));
var ToastAnnounce = /* @__PURE__ */ __name((props) => {
	const { __scopeToast, children, ...announceProps } = props;
	const context = useToastProviderContext(TOAST_NAME, __scopeToast);
	const [renderAnnounceText, setRenderAnnounceText] = import_react.useState(false);
	const [isAnnounced, setIsAnnounced] = import_react.useState(false);
	useNextFrame(() => setRenderAnnounceText(true));
	import_react.useEffect(() => {
		const timer = window.setTimeout(() => setIsAnnounced(true), 1e3);
		return () => window.clearTimeout(timer);
	}, []);
	return isAnnounced ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal, {
		asChild: true,
		container: context.announcerContainer || void 0,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VisuallyHidden, {
			...announceProps,
			children: renderAnnounceText && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
				context.label,
				" ",
				children
			] })
		})
	});
}, "ToastAnnounce");
var ToastTitle = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function ToastTitle2(props, forwardedRef) {
	const { __scopeToast, ...titleProps } = props;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.div, {
		...titleProps,
		ref: forwardedRef
	});
}, "ToastTitle"));
var ToastDescription = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function ToastDescription2(props, forwardedRef) {
	const { __scopeToast, ...descriptionProps } = props;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.div, {
		...descriptionProps,
		ref: forwardedRef
	});
}, "ToastDescription"));
var CLOSE_NAME = "ToastClose";
var ToastClose = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function ToastClose2(props, forwardedRef) {
	const { __scopeToast, ...closeProps } = props;
	const interactiveContext = useToastInteractiveContext(CLOSE_NAME, __scopeToast);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastAnnounceExclude, {
		asChild: true,
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.button, {
			type: "button",
			...closeProps,
			ref: forwardedRef,
			onClick: composeEventHandlers(props.onClick, interactiveContext.onClose)
		})
	});
}, "ToastClose"));
var ToastAnnounceExclude = /* @__PURE__ */ import_react.forwardRef(/* @__PURE__ */ __name(function ToastAnnounceExclude2(props, forwardedRef) {
	const { __scopeToast, altText, ...announceExcludeProps } = props;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Primitive.div, {
		"data-radix-toast-announce-exclude": "",
		"data-radix-toast-announce-alt": altText || void 0,
		...announceExcludeProps,
		ref: forwardedRef
	});
}, "ToastAnnounceExclude"));
function getAnnounceTextContent(container) {
	const textContent = [];
	Array.from(container.childNodes).forEach((node) => {
		if (node.nodeType === node.TEXT_NODE && node.textContent) textContent.push(node.textContent);
		if (isHTMLElement(node)) {
			const isHidden = node.ariaHidden || node.hidden || node.style.display === "none";
			const isExcluded = node.dataset.radixToastAnnounceExclude === "";
			if (!isHidden) {
				if (isExcluded) {
					const altText = node.dataset.radixToastAnnounceAlt;
					if (altText) textContent.push(altText);
				} else textContent.push(...getAnnounceTextContent(node));
			}
		}
	});
	return textContent;
}
__name(getAnnounceTextContent, "getAnnounceTextContent");
function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
	const currentTarget = detail.originalEvent.currentTarget;
	const event = new CustomEvent(name, {
		bubbles: true,
		cancelable: true,
		detail
	});
	if (handler) currentTarget.addEventListener(name, handler, { once: true });
	if (discrete) dispatchDiscreteCustomEvent(currentTarget, event);
	else currentTarget.dispatchEvent(event);
}
__name(handleAndDispatchCustomEvent, "handleAndDispatchCustomEvent");
var isDeltaInDirection = /* @__PURE__ */ __name((delta, direction, threshold = 0) => {
	const deltaX = Math.abs(delta.x);
	const deltaY = Math.abs(delta.y);
	const isDeltaX = deltaX > deltaY;
	if (direction === "left" || direction === "right") return isDeltaX && deltaX > threshold;
	else return !isDeltaX && deltaY > threshold;
}, "isDeltaInDirection");
function useNextFrame(callback = () => {}) {
	const fn = useCallbackRef(callback);
	useLayoutEffect2(() => {
		let raf1 = 0;
		let raf2 = 0;
		raf1 = window.requestAnimationFrame(() => raf2 = window.requestAnimationFrame(fn));
		return () => {
			window.cancelAnimationFrame(raf1);
			window.cancelAnimationFrame(raf2);
		};
	}, [fn]);
}
__name(useNextFrame, "useNextFrame");
function isHTMLElement(node) {
	return node.nodeType === node.ELEMENT_NODE;
}
__name(isHTMLElement, "isHTMLElement");
function getTabbableCandidates(container) {
	const nodes = [];
	const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, { acceptNode: /* @__PURE__ */ __name((node) => {
		const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
		if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
		return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
	}, "acceptNode") });
	while (walker.nextNode()) nodes.push(walker.currentNode);
	return nodes;
}
__name(getTabbableCandidates, "getTabbableCandidates");
function focusFirst(candidates) {
	const previouslyFocusedElement = document.activeElement;
	return candidates.some((candidate) => {
		if (candidate === previouslyFocusedElement) return true;
		candidate.focus();
		return document.activeElement !== previouslyFocusedElement;
	});
}
__name(focusFirst, "focusFirst");
var Provider = ToastProvider$1;
var Viewport = ToastViewport;
var Root2 = Toast;
var Title = ToastTitle;
var Description = ToastDescription;
var Close = ToastClose;
//#endregion
//#region ../../packages/ui-primitives/dist/Toast.js
var ToastContext = import_react.createContext(null);
var toastVariants = cva("pointer-events-auto flex w-full max-w-sm flex-col gap-1 rounded-md border border-border p-4 shadow-[var(--mod-shadow-sm)]", {
	variants: { tone: {
		neutral: "bg-surface text-fg",
		success: "bg-success text-success-fg",
		warning: "bg-warning text-warning-fg",
		danger: "bg-danger text-danger-fg"
	} },
	defaultVariants: { tone: "neutral" }
});
function nextToastId() {
	return globalThis.crypto?.randomUUID?.() ?? `toast-${Math.random().toString(36).slice(2)}`;
}
function ToastProvider({ children }) {
	const [toasts, setToasts] = import_react.useState([]);
	const dismiss = import_react.useCallback((id) => {
		setToasts((current) => id ? current.map((toast) => toast.id === id ? {
			...toast,
			open: false
		} : toast) : current.map((toast) => ({
			...toast,
			open: false
		})));
	}, []);
	const toast = import_react.useCallback((options) => {
		const id = nextToastId();
		setToasts((current) => [...current, {
			...options,
			id,
			open: true
		}]);
	}, []);
	const handleOpenChange = import_react.useCallback((id, open) => {
		if (!open) setToasts((current) => current.filter((item) => item.id !== id));
	}, []);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastContext.Provider, {
		value: {
			toast,
			dismiss
		},
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Provider, {
			swipeDirection: "right",
			children: [
				children,
				toasts.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastItem, {
					item,
					onOpenChange: handleOpenChange
				}, item.id)),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Viewport, { className: "fixed bottom-0 right-0 z-50 flex max-h-screen w-full flex-col-reverse gap-2 p-4 sm:max-w-sm" })
			]
		})
	});
}
function ToastItem({ item, onOpenChange }) {
	const tone = item.tone ?? "neutral";
	const type = tone === "danger" ? "foreground" : "background";
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Root2, {
		open: item.open,
		type,
		duration: item.durationMs,
		className: cn(toastVariants({ tone })),
		onOpenChange: (open) => onOpenChange(item.id, open),
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Title, {
				className: "text-sm font-semibold",
				children: item.title
			}),
			item.description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Description, {
				className: "text-sm opacity-90",
				children: item.description
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Close, {
				"aria-label": "Dismiss notification",
				className: "absolute right-2 top-2 rounded-sm text-inherit opacity-70 hover:bg-[var(--mod-color-neutral-a3)] active:bg-[var(--mod-color-neutral-a4)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]",
				children: "×"
			})
		]
	});
}
function useToast() {
	const context = import_react.useContext(ToastContext);
	if (!context) throw new Error("useToast must be used within ToastProvider");
	return context;
}
//#endregion
//#region ../../packages/ui-primitives/dist/Card.js
function Card({ header, footer, children, padded = true, className }) {
	const headingId = import_react.useId();
	const pad = padded ? "p-4" : "";
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", {
		"aria-labelledby": header != null ? headingId : void 0,
		className: cn("rounded-lg border border-border bg-surface text-fg", className),
		children: [
			header != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", {
				id: headingId,
				className: cn("border-b border-border", pad),
				children: header
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: pad,
				children
			}),
			footer != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("footer", {
				className: cn("border-t border-border", pad),
				children: footer
			}) : null
		]
	});
}
//#endregion
//#region ../../node_modules/.pnpm/@date-fns+tz@1.5.0/node_modules/@date-fns/tz/tzName/index.js
/**
* Time zone name format.
*/
/**
* The function returns the time zone name for the given date in the specified
* time zone.
*
* It uses the `Intl.DateTimeFormat` API and by default outputs the time zone
* name in a long format, e.g. "Pacific Standard Time" or
* "Singapore Standard Time".
*
* It is possible to specify the format as the third argument using one of the following options
*
* - "short": e.g. "EDT" or "GMT+8".
* - "long": e.g. "Eastern Daylight Time".
* - "shortGeneric": e.g. "ET" or "Singapore Time".
* - "longGeneric": e.g. "Eastern Time" or "Singapore Standard Time".
*
* These options correspond to TR35 tokens `z..zzz`, `zzzz`, `v`, and `vvvv` respectively: https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-zone
*
* @param timeZone - Time zone name (IANA or UTC offset)
* @param date - Date object to get the time zone name for
* @param format - Optional format of the time zone name. Defaults to "long". Can be "short", "long", "shortGeneric", or "longGeneric".
*
* @returns Time zone name (e.g. "Singapore Standard Time")
*/
function tzName(timeZone, date, format = "long") {
	return new Intl.DateTimeFormat("en-US", {
		hour: "numeric",
		timeZone,
		timeZoneName: format
	}).format(date).split(/\s/g).slice(2).join(" ");
}
//#endregion
//#region ../../node_modules/.pnpm/@date-fns+tz@1.5.0/node_modules/@date-fns/tz/tzOffset/index.js
var offsetFormatCache = {};
var offsetCache = {};
/**
* The function returns UTC offset in minutes for the given date in specified
* time zone.
*
* Unlike `Date.prototype.getTimezoneOffset`, this function returns the value
* mirrored to the sign of the offset in the time zone. For Asia/Singapore
* (UTC+8), `tzOffset` returns `480`, while `getTimezoneOffset` returns `-480`.
*
* It uses `Intl.DateTimeFormat` internally to access otherwise unavailable
* runtime's time zone data, and falls back to basic manual parsing if Intl API
* is not supported (e.g., older Node.js versions, React Native's Hermes, etc.).
*
* @param timeZone - Time zone name (IANA or UTC offset).
* @param date - Date to check the offset for.
*
* @returns UTC offset in minutes (e.g., `480` for date in UTC+8).
*/
function tzOffset(timeZone, date) {
	try {
		const offsetStr = (offsetFormatCache[timeZone] ||= new Intl.DateTimeFormat("en-US", {
			timeZone,
			timeZoneName: "longOffset"
		}).format)(date).split("GMT")[1];
		if (offsetStr in offsetCache) return offsetCache[offsetStr];
		return calcOffset(offsetStr, offsetStr.split(":"));
	} catch {
		if (timeZone in offsetCache) return offsetCache[timeZone];
		const captures = timeZone?.match(offsetRe);
		if (captures) return calcOffset(timeZone, captures.slice(1));
		return NaN;
	}
}
var offsetRe = /([+-]\d\d):?(\d\d)?/;
function calcOffset(cacheStr, values) {
	const hours = +(values[0] || 0);
	const minutes = +(values[1] || 0);
	const seconds = +(values[2] || 0) / 60;
	return offsetCache[cacheStr] = hours * 60 + minutes > 0 ? hours * 60 + minutes + seconds : hours * 60 - minutes - seconds;
}
//#endregion
//#region ../../node_modules/.pnpm/@date-fns+tz@1.5.0/node_modules/@date-fns/tz/date/mini.js
var TZDateMini = class TZDateMini extends Date {
	constructor(...args) {
		super();
		if (args.length > 1 && typeof args[args.length - 1] === "string") this.timeZone = args.pop();
		this.internal = /* @__PURE__ */ new Date();
		if (isNaN(tzOffset(this.timeZone, this))) this.setTime(NaN);
		else if (!args.length) this.setTime(Date.now());
		else if (typeof args[0] === "number" && (args.length === 1 || args.length === 2 && typeof args[1] !== "number")) this.setTime(args[0]);
		else if (typeof args[0] === "string") this.setTime(+new Date(args[0]));
		else if (args[0] instanceof Date) this.setTime(+args[0]);
		else {
			this.setTime(+new Date(...args));
			adjustToSystemTZ(this, args);
		}
	}
	static tz(tz, ...args) {
		return args.length ? new TZDateMini(...args, tz) : new TZDateMini(Date.now(), tz);
	}
	withTimeZone(timeZone) {
		return new TZDateMini(+this, timeZone);
	}
	getTimezoneOffset() {
		const offset = -tzOffset(this.timeZone, this);
		return offset > 0 ? Math.floor(offset) : Math.ceil(offset);
	}
	setTime(_time) {
		Date.prototype.setTime.apply(this, arguments);
		syncToInternal(this);
		return +this;
	}
	[Symbol.for("constructDateFrom")](date) {
		return new TZDateMini(+new Date(date), this.timeZone);
	}
};
var re = /^(get|set)(?!UTC)/;
Object.getOwnPropertyNames(Date.prototype).forEach((method) => {
	if (!re.test(method)) return;
	const utcMethod = method.replace(re, "$1UTC");
	if (!TZDateMini.prototype[utcMethod]) return;
	if (method.startsWith("get")) TZDateMini.prototype[method] = function() {
		return this.internal[utcMethod]();
	};
	else {
		TZDateMini.prototype[method] = function() {
			Date.prototype[utcMethod].apply(this.internal, arguments);
			syncFromInternal(this);
			return +this;
		};
		TZDateMini.prototype[utcMethod] = function() {
			Date.prototype[utcMethod].apply(this, arguments);
			syncToInternal(this);
			return +this;
		};
	}
});
/**
* @internal
* Function syncs time to internal date, applying the current time zone offset.
*
* @param {Date} date - `Date` to sync
*/
function syncToInternal(date) {
	date.internal.setTime(+date);
	date.internal.setUTCSeconds(date.internal.getUTCSeconds() - Math.round(-tzOffset(date.timeZone, date) * 60));
}
/**
* @internal
* Function syncs internal wall-clock fields into the external date.
*
* @param {Date} date - The date to sync
*/
function syncFromInternal(date) {
	Date.prototype.setFullYear.call(date, date.internal.getUTCFullYear(), date.internal.getUTCMonth(), date.internal.getUTCDate());
	Date.prototype.setHours.call(date, date.internal.getUTCHours(), date.internal.getUTCMinutes(), date.internal.getUTCSeconds(), date.internal.getUTCMilliseconds());
	adjustToSystemTZ(date);
}
/**
* @internal
* Function adjusts the date to the system time zone. It uses the time zone
* differences to calculate the offset and adjust the date.
*
* We use it when constructing `TZDate` and syncing the external date from
* the internal one.
*
* @param {TZDate} date - `TZDate` to adjust.
*/
function adjustToSystemTZ(date, constructorArgs) {
	const expectedInternalTime = Array.isArray(constructorArgs) ? constructorArgsToInternalTime(constructorArgs) : +date.internal;
	const offsetWithSeconds = tzOffset(date.timeZone, date);
	const offset = offsetWithSeconds > 0 ? Math.floor(offsetWithSeconds) : Math.ceil(offsetWithSeconds);
	const prevHour = /* @__PURE__ */ new Date(+date);
	prevHour.setUTCHours(prevHour.getUTCHours() - 1);
	const systemOffset = -(/* @__PURE__ */ new Date(+date)).getTimezoneOffset();
	const prevHourSystemOffset = -(/* @__PURE__ */ new Date(+prevHour)).getTimezoneOffset();
	const systemDSTChange = systemOffset - prevHourSystemOffset;
	let systemOffsetForDiff = systemOffset;
	if (systemDSTChange && systemOffset !== offset) {
		if (Date.prototype.getHours.apply(date) !== (Array.isArray(constructorArgs) ? constructorArgs[3] || 0 : date.internal.getUTCHours())) {
			const testDate = /* @__PURE__ */ new Date(+date);
			const testOffsetDiff = systemOffset - offset;
			if (testOffsetDiff) testDate.setUTCMinutes(testDate.getUTCMinutes() + testOffsetDiff);
			const testOffsetWithSeconds = tzOffset(date.timeZone, testDate);
			if ((testOffsetWithSeconds > 0 ? Math.floor(testOffsetWithSeconds) : Math.ceil(testOffsetWithSeconds)) === offset) systemOffsetForDiff = prevHourSystemOffset;
		}
	}
	const offsetDiff = systemOffsetForDiff - offset;
	if (offsetDiff) Date.prototype.setUTCMinutes.call(date, Date.prototype.getUTCMinutes.call(date) + offsetDiff);
	const systemDate = /* @__PURE__ */ new Date(+date);
	systemDate.setUTCSeconds(0);
	const systemSecondsOffset = systemOffset > 0 ? systemDate.getSeconds() : (systemDate.getSeconds() - 60) % 60;
	const secondsOffset = Math.round(-(tzOffset(date.timeZone, date) * 60)) % 60;
	if (secondsOffset || systemSecondsOffset) Date.prototype.setUTCSeconds.call(date, Date.prototype.getUTCSeconds.call(date) + secondsOffset + systemSecondsOffset);
	const postOffsetWithSeconds = tzOffset(date.timeZone, date);
	const postOffset = postOffsetWithSeconds > 0 ? Math.floor(postOffsetWithSeconds) : Math.ceil(postOffsetWithSeconds);
	const postOffsetDiff = -(/* @__PURE__ */ new Date(+date)).getTimezoneOffset() - postOffset;
	const offsetChanged = postOffset !== offset;
	const postDiff = postOffsetDiff - offsetDiff;
	const targetDSTShift = postOffset - offset;
	const postOffsetCandidate = expectedInternalTime - postOffset * 60 * 1e3;
	const normalizedTargetDSTGap = targetDSTShift > 0 && targetInternalTime(date) - expectedInternalTime === targetDSTShift * 60 * 1e3 && targetInternalTime(date, postOffsetCandidate) !== expectedInternalTime;
	if (offsetChanged && postDiff && !normalizedTargetDSTGap) {
		Date.prototype.setUTCMinutes.call(date, Date.prototype.getUTCMinutes.call(date) + postDiff);
		const newOffsetWithSeconds = tzOffset(date.timeZone, date);
		const offsetChange = postOffset - (newOffsetWithSeconds > 0 ? Math.floor(newOffsetWithSeconds) : Math.ceil(newOffsetWithSeconds));
		if (offsetChange && postDiff < 0) Date.prototype.setUTCMinutes.call(date, Date.prototype.getUTCMinutes.call(date) + offsetChange);
	}
	syncToInternal(date);
	const drift = (constructorArgs ? expectedInternalTime : expectedInternalTime + secondsOffset * 1e3) - +date.internal;
	if (drift && Math.abs(drift) < 18e5) {
		Date.prototype.setTime.call(date, +date + drift);
		syncToInternal(date);
	}
}
function constructorArgsToInternalTime(args) {
	return Date.UTC(args[0], args.length > 1 ? args[1] : 0, args.length > 2 ? args[2] : 1, ...args.slice(3));
}
function targetInternalTime(date, time) {
	const internal = new Date(time ?? +date);
	internal.setUTCSeconds(internal.getUTCSeconds() - Math.round(-tzOffset(date.timeZone, internal) * 60));
	return +internal;
}
//#endregion
//#region ../../node_modules/.pnpm/@date-fns+tz@1.5.0/node_modules/@date-fns/tz/date/index.js
var TZDate = class TZDate extends TZDateMini {
	static tz(tz, ...args) {
		return args.length ? new TZDate(...args, tz) : new TZDate(Date.now(), tz);
	}
	toISOString() {
		const [sign, hours, minutes] = this.tzComponents();
		const tz = `${sign}${hours}:${minutes}`;
		return this.internal.toISOString().slice(0, -1) + tz;
	}
	toString() {
		return `${this.toDateString()} ${this.toTimeString()}`;
	}
	toDateString() {
		const [day, date, month, year] = this.internal.toUTCString().split(" ");
		return `${day?.slice(0, -1)} ${month} ${date} ${year}`;
	}
	toTimeString() {
		const time = this.internal.toUTCString().split(" ")[4];
		const [sign, hours, minutes] = this.tzComponents();
		return `${time} GMT${sign}${hours}${minutes} (${tzName(this.timeZone, this)})`;
	}
	toLocaleString(locales, options) {
		return Date.prototype.toLocaleString.call(this, locales, {
			...options,
			timeZone: options?.timeZone || this.timeZone
		});
	}
	toLocaleDateString(locales, options) {
		return Date.prototype.toLocaleDateString.call(this, locales, {
			...options,
			timeZone: options?.timeZone || this.timeZone
		});
	}
	toLocaleTimeString(locales, options) {
		return Date.prototype.toLocaleTimeString.call(this, locales, {
			...options,
			timeZone: options?.timeZone || this.timeZone
		});
	}
	tzComponents() {
		const offset = this.getTimezoneOffset();
		return [
			offset > 0 ? "-" : "+",
			String(Math.floor(Math.abs(offset) / 60)).padStart(2, "0"),
			String(Math.abs(offset) % 60).padStart(2, "0")
		];
	}
	withTimeZone(timeZone) {
		return new TZDate(+this, timeZone);
	}
	[Symbol.for("constructDateFrom")](date) {
		return new TZDate(+new Date(date), this.timeZone);
	}
};
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constants.js
/**
* @constant
* @name daysInYear
* @summary Days in 1 year.
*
* @description
* How many days in a year.
*
* One years equals 365.2425 days according to the formula:
*
* > Leap year occurs every 4 years, except for years that are divisible by 100 and not divisible by 400.
* > 1 mean year = (365+1/4-1/100+1/400) days = 365.2425 days
*/
var daysInYear = 365.2425;
-(Math.pow(10, 8) * 24 * 60 * 60 * 1e3);
/**
* @constant
* @name millisecondsInWeek
* @summary Milliseconds in 1 week.
*/
var millisecondsInWeek = 6048e5;
/**
* @constant
* @name millisecondsInDay
* @summary Milliseconds in 1 day.
*/
var millisecondsInDay = 864e5;
/**
* @constant
* @name secondsInDay
* @summary Seconds in 1 day.
*/
var secondsInDay = 86400;
secondsInDay * 7;
secondsInDay * daysInYear / 12 * 3;
/**
* @constant
* @name constructFromSymbol
* @summary Symbol enabling Date extensions to inherit properties from the reference date.
*
* The symbol is used to enable the `constructFrom` function to construct a date
* using a reference date and a value. It allows to transfer extra properties
* from the reference date to the new date. It's useful for extensions like
* [`TZDate`](https://github.com/date-fns/tz) that accept a time zone as
* a constructor argument.
*/
var constructFromSymbol = Symbol.for("constructDateFrom");
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constructFrom.js
/**
* @name constructFrom
* @category Generic Helpers
* @summary Constructs a date using the reference date and the value
*
* @description
* The function constructs a new date using the constructor from the reference
* date and the given value. It helps to build generic functions that accept
* date extensions.
*
* It defaults to `Date` if the passed reference date is a number or a string.
*
* Starting from v3.7.0, it allows to construct a date using `[Symbol.for("constructDateFrom")]`
* enabling to transfer extra properties from the reference date to the new date.
* It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)
* that accept a time zone as a constructor argument.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
*
* @param date - The reference date to take constructor from
* @param value - The value to create the date
*
* @returns Date initialized using the given date and value
*
* @example
* import { constructFrom } from "./constructFrom/date-fns";
*
* // A function that clones a date preserving the original type
* function cloneDate<DateType extends Date>(date: DateType): DateType {
*   return constructFrom(
*     date, // Use constructor from the given date
*     date.getTime() // Use the date value to create a new date
*   );
* }
*/
function constructFrom(date, value) {
	if (typeof date === "function") return date(value);
	if (date && typeof date === "object" && constructFromSymbol in date) return date[constructFromSymbol](value);
	if (date instanceof Date) return new date.constructor(value);
	return new Date(value);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/toDate.js
/**
* @name toDate
* @category Common Helpers
* @summary Convert the given argument to an instance of Date.
*
* @description
* Convert the given argument to an instance of Date.
*
* If the argument is an instance of Date, the function returns its clone.
*
* If the argument is a number, it is treated as a timestamp.
*
* If the argument is none of the above, the function returns Invalid Date.
*
* Starting from v3.7.0, it clones a date using `[Symbol.for("constructDateFrom")]`
* enabling to transfer extra properties from the reference date to the new date.
* It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)
* that accept a time zone as a constructor argument.
*
* **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param argument - The value to convert
*
* @returns The parsed date in the local time zone
*
* @example
* // Clone the date:
* const result = toDate(new Date(2014, 1, 11, 11, 30, 30))
* //=> Tue Feb 11 2014 11:30:30
*
* @example
* // Convert the timestamp to date:
* const result = toDate(1392098430000)
* //=> Tue Feb 11 2014 11:30:30
*/
function toDate(argument, context) {
	return constructFrom(context || argument, argument);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/addDays.js
/**
* The {@link addDays} function options.
*/
/**
* @name addDays
* @category Day Helpers
* @summary Add the specified number of days to the given date.
*
* @description
* Add the specified number of days to the given date.
*
* **You don't need date-fns\***:
*
* Temporal has a built-in `add` method on all its classes:
*
* - [`Temporal.Instant.prototype.add()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/add)
* - [`Temporal.PlainDate.prototype.add()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate/add)
* - [`Temporal.PlainDateTime.prototype.add()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime/add)
* - [`Temporal.PlainTime.prototype.add()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/add)
* - [`Temporal.PlainYearMonth.prototype.add()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/add)
* - [`Temporal.ZonedDateTime.prototype.add()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/add)
*
* \* **Not really**, see: https://date-fns.org/you-dont-need-date-fns
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The date to be changed
* @param amount - The amount of days to be added.
* @param options - An object with options
*
* @returns The new date with the days added
*
* @example
* // Add 10 days to 1 September 2014:
* const result = addDays(new Date(2014, 8, 1), 10)
* //=> Thu Sep 11 2014 00:00:00
*
* @example
* // Using Temporal:
* // Add 10 days to 1 September 2014:
* Temporal.PlainDate.from("2014-09-01").add({ days: 10 }).toString();
* //=> "2014-09-11"
*/
function addDays(date, amount, options) {
	const _date = toDate(date, options?.in);
	if (isNaN(amount)) return constructFrom(options?.in || date, NaN);
	if (!amount) return _date;
	_date.setDate(_date.getDate() + amount);
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/addMonths.js
/**
* The {@link addMonths} function options.
*/
/**
* @name addMonths
* @category Month Helpers
* @summary Add the specified number of months to the given date.
*
* @description
* Add the specified number of months to the given date.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The date to be changed
* @param amount - The amount of months to be added.
* @param options - The options object
*
* @returns The new date with the months added
*
* @example
* // Add 5 months to 1 September 2014:
* const result = addMonths(new Date(2014, 8, 1), 5)
* //=> Sun Feb 01 2015 00:00:00
*
* // Add one month to 30 January 2023:
* const result = addMonths(new Date(2023, 0, 30), 1)
* //=> Tue Feb 28 2023 00:00:00
*/
function addMonths(date, amount, options) {
	const _date = toDate(date, options?.in);
	if (isNaN(amount)) return constructFrom(options?.in || date, NaN);
	if (!amount) return _date;
	const dayOfMonth = _date.getDate();
	const endOfDesiredMonth = constructFrom(options?.in || date, _date.getTime());
	endOfDesiredMonth.setMonth(_date.getMonth() + amount + 1, 0);
	if (dayOfMonth >= endOfDesiredMonth.getDate()) return endOfDesiredMonth;
	else {
		_date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
		return _date;
	}
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/defaultOptions.js
var defaultOptions = {};
function getDefaultOptions() {
	return defaultOptions;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/startOfWeek.js
/**
* The {@link startOfWeek} function options.
*/
/**
* @name startOfWeek
* @category Week Helpers
* @summary Return the start of a week for the given date.
*
* @description
* Return the start of a week for the given date.
* The result will be in the local timezone.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The start of a week
*
* @example
* // The start of a week for 2 September 2014 11:55:00:
* const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sun Aug 31 2014 00:00:00
*
* @example
* // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:
* const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
* //=> Mon Sep 01 2014 00:00:00
*/
function startOfWeek(date, options) {
	const defaultOptions = getDefaultOptions();
	const weekStartsOn = options?.weekStartsOn ?? options?.locale?.options?.weekStartsOn ?? defaultOptions.weekStartsOn ?? defaultOptions.locale?.options?.weekStartsOn ?? 0;
	const _date = toDate(date, options?.in);
	const day = _date.getDay();
	const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
	_date.setDate(_date.getDate() - diff);
	_date.setHours(0, 0, 0, 0);
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/startOfISOWeek.js
/**
* The {@link startOfISOWeek} function options.
*/
/**
* @name startOfISOWeek
* @category ISO Week Helpers
* @summary Return the start of an ISO week for the given date.
*
* @description
* Return the start of an ISO week for the given date.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The start of an ISO week
*
* @example
* // The start of an ISO week for 2 September 2014 11:55:00:
* const result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Mon Sep 01 2014 00:00:00
*/
function startOfISOWeek(date, options) {
	return startOfWeek(date, {
		...options,
		weekStartsOn: 1
	});
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getISOWeekYear.js
/**
* The {@link getISOWeekYear} function options.
*/
/**
* @name getISOWeekYear
* @category ISO Week-Numbering Year Helpers
* @summary Get the ISO week-numbering year of the given date.
*
* @description
* Get the ISO week-numbering year of the given date,
* which always starts 3 days before the year's first Thursday.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param date - The given date
*
* @returns The ISO week-numbering year
*
* @example
* // Which ISO-week numbering year is 2 January 2005?
* const result = getISOWeekYear(new Date(2005, 0, 2))
* //=> 2004
*/
function getISOWeekYear(date, options) {
	const _date = toDate(date, options?.in);
	const year = _date.getFullYear();
	const fourthOfJanuaryOfNextYear = constructFrom(_date, 0);
	fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);
	fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);
	const startOfNextYear = startOfISOWeek(fourthOfJanuaryOfNextYear);
	const fourthOfJanuaryOfThisYear = constructFrom(_date, 0);
	fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4);
	fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0);
	const startOfThisYear = startOfISOWeek(fourthOfJanuaryOfThisYear);
	if (_date.getTime() >= startOfNextYear.getTime()) return year + 1;
	else if (_date.getTime() >= startOfThisYear.getTime()) return year;
	else return year - 1;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js
/**
* Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.
* They usually appear for dates that denote time before the timezones were introduced
* (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891
* and GMT+01:00:00 after that date)
*
* Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,
* which would lead to incorrect calculations.
*
* This function returns the timezone offset in milliseconds that takes seconds in account.
*/
function getTimezoneOffsetInMilliseconds(date) {
	const _date = toDate(date);
	const utcDate = new Date(Date.UTC(_date.getFullYear(), _date.getMonth(), _date.getDate(), _date.getHours(), _date.getMinutes(), _date.getSeconds(), _date.getMilliseconds()));
	utcDate.setUTCFullYear(_date.getFullYear());
	return +date - +utcDate;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/normalizeDates.js
function normalizeDates(context, ...dates) {
	const normalize = constructFrom.bind(null, context || dates.find((date) => typeof date === "object"));
	return dates.map(normalize);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/startOfDay.js
/**
* The {@link startOfDay} function options.
*/
/**
* @name startOfDay
* @category Day Helpers
* @summary Return the start of a day for the given date.
*
* @description
* Return the start of a day for the given date.
* The result will be in the local timezone.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - The options
*
* @returns The start of a day
*
* @example
* // The start of a day for 2 September 2014 11:55:00:
* const result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 02 2014 00:00:00
*/
function startOfDay(date, options) {
	const _date = toDate(date, options?.in);
	_date.setHours(0, 0, 0, 0);
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/differenceInCalendarDays.js
/**
* The {@link differenceInCalendarDays} function options.
*/
/**
* @name differenceInCalendarDays
* @category Day Helpers
* @summary Get the number of calendar days between the given dates.
*
* @description
* Get the number of calendar days between the given dates. This means that the times are removed
* from the dates and then the difference in days is calculated.
*
* @param laterDate - The later date
* @param earlierDate - The earlier date
* @param options - The options object
*
* @returns The number of calendar days
*
* @example
* // How many calendar days are between
* // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
* const result = differenceInCalendarDays(
*   new Date(2012, 6, 2, 0, 0),
*   new Date(2011, 6, 2, 23, 0)
* )
* //=> 366
* // How many calendar days are between
* // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?
* const result = differenceInCalendarDays(
*   new Date(2011, 6, 3, 0, 1),
*   new Date(2011, 6, 2, 23, 59)
* )
* //=> 1
*/
function differenceInCalendarDays(laterDate, earlierDate, options) {
	const [laterDate_, earlierDate_] = normalizeDates(options?.in, laterDate, earlierDate);
	const laterStartOfDay = startOfDay(laterDate_);
	const earlierStartOfDay = startOfDay(earlierDate_);
	const laterTimestamp = +laterStartOfDay - getTimezoneOffsetInMilliseconds(laterStartOfDay);
	const earlierTimestamp = +earlierStartOfDay - getTimezoneOffsetInMilliseconds(earlierStartOfDay);
	return Math.round((laterTimestamp - earlierTimestamp) / millisecondsInDay);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/startOfISOWeekYear.js
/**
* The {@link startOfISOWeekYear} function options.
*/
/**
* @name startOfISOWeekYear
* @category ISO Week-Numbering Year Helpers
* @summary Return the start of an ISO week-numbering year for the given date.
*
* @description
* Return the start of an ISO week-numbering year,
* which always starts 3 days before the year's first Thursday.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The start of an ISO week-numbering year
*
* @example
* // The start of an ISO week-numbering year for 2 July 2005:
* const result = startOfISOWeekYear(new Date(2005, 6, 2))
* //=> Mon Jan 03 2005 00:00:00
*/
function startOfISOWeekYear(date, options) {
	const year = getISOWeekYear(date, options);
	const fourthOfJanuary = constructFrom(options?.in || date, 0);
	fourthOfJanuary.setFullYear(year, 0, 4);
	fourthOfJanuary.setHours(0, 0, 0, 0);
	return startOfISOWeek(fourthOfJanuary);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/addWeeks.js
/**
* The {@link addWeeks} function options.
*/
/**
* @name addWeeks
* @category Week Helpers
* @summary Add the specified number of weeks to the given date.
*
* @description
* Add the specified number of weeks to the given date.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The date to be changed
* @param amount - The amount of weeks to be added.
* @param options - An object with options
*
* @returns The new date with the weeks added
*
* @example
* // Add 4 weeks to 1 September 2014:
* const result = addWeeks(new Date(2014, 8, 1), 4)
* //=> Mon Sep 29 2014 00:00:00
*/
function addWeeks(date, amount, options) {
	return addDays(date, amount * 7, options);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/addYears.js
/**
* The {@link addYears} function options.
*/
/**
* @name addYears
* @category Year Helpers
* @summary Add the specified number of years to the given date.
*
* @description
* Add the specified number of years to the given date.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type.
*
* @param date - The date to be changed
* @param amount - The amount of years to be added.
* @param options - The options
*
* @returns The new date with the years added
*
* @example
* // Add 5 years to 1 September 2014:
* const result = addYears(new Date(2014, 8, 1), 5)
* //=> Sun Sep 01 2019 00:00:00
*/
function addYears(date, amount, options) {
	return addMonths(date, amount * 12, options);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/max.js
/**
* The {@link max} function options.
*/
/**
* @name max
* @category Common Helpers
* @summary Return the latest of the given dates.
*
* @description
* Return the latest of the given dates.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param dates - The dates to compare
*
* @returns The latest of the dates
*
* @example
* // Which of these dates is the latest?
* const result = max([
*   new Date(1989, 6, 10),
*   new Date(1987, 1, 11),
*   new Date(1995, 6, 2),
*   new Date(1990, 0, 1)
* ])
* //=> Sun Jul 02 1995 00:00:00
*/
function max(dates, options) {
	let result;
	let context = options?.in;
	dates.forEach((date) => {
		if (!context && typeof date === "object") context = constructFrom.bind(null, date);
		const date_ = toDate(date, context);
		if (!result || result < date_ || isNaN(+date_)) result = date_;
	});
	return constructFrom(context, result || NaN);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/min.js
/**
* The {@link min} function options.
*/
/**
* @name min
* @category Common Helpers
* @summary Returns the earliest of the given dates.
*
* @description
* Returns the earliest of the given dates.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param dates - The dates to compare
*
* @returns The earliest of the dates
*
* @example
* // Which of these dates is the earliest?
* const result = min([
*   new Date(1989, 6, 10),
*   new Date(1987, 1, 11),
*   new Date(1995, 6, 2),
*   new Date(1990, 0, 1)
* ])
* //=> Wed Feb 11 1987 00:00:00
*/
function min(dates, options) {
	let result;
	let context = options?.in;
	dates.forEach((date) => {
		if (!context && typeof date === "object") context = constructFrom.bind(null, date);
		const date_ = toDate(date, context);
		if (!result || result > date_ || isNaN(+date_)) result = date_;
	});
	return constructFrom(context, result || NaN);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/isSameDay.js
/**
* The {@link isSameDay} function options.
*/
/**
* @name isSameDay
* @category Day Helpers
* @summary Are the given dates in the same day (and year and month)?
*
* @description
* Are the given dates in the same day (and year and month)?
*
* @param laterDate - The first date to check
* @param earlierDate - The second date to check
* @param options - An object with options
*
* @returns The dates are in the same day (and year and month)
*
* @example
* // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?
* const result = isSameDay(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 18, 0))
* //=> true
*
* @example
* // Are 4 September and 4 October in the same day?
* const result = isSameDay(new Date(2014, 8, 4), new Date(2014, 9, 4))
* //=> false
*
* @example
* // Are 4 September, 2014 and 4 September, 2015 in the same day?
* const result = isSameDay(new Date(2014, 8, 4), new Date(2015, 8, 4))
* //=> false
*/
function isSameDay(laterDate, earlierDate, options) {
	const [dateLeft_, dateRight_] = normalizeDates(options?.in, laterDate, earlierDate);
	return +startOfDay(dateLeft_) === +startOfDay(dateRight_);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/isDate.js
/**
* @name isDate
* @category Common Helpers
* @summary Is the given value a date?
*
* @description
* Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.
*
* @param value - The value to check
*
* @returns True if the given value is a date
*
* @example
* // For a valid date:
* const result = isDate(new Date())
* //=> true
*
* @example
* // For an invalid date:
* const result = isDate(new Date(NaN))
* //=> true
*
* @example
* // For some value:
* const result = isDate('2014-02-31')
* //=> false
*
* @example
* // For an object:
* const result = isDate({})
* //=> false
*/
function isDate(value) {
	return value instanceof Date || typeof value === "object" && Object.prototype.toString.call(value) === "[object Date]";
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/isValid.js
/**
* @name isValid
* @category Common Helpers
* @summary Is the given date valid?
*
* @description
* Returns false if argument is Invalid Date and true otherwise.
* Argument is converted to Date using `toDate`. See [toDate](https://date-fns.org/docs/toDate)
* Invalid Date is a Date, whose time value is NaN.
*
* Time value of Date: http://es5.github.io/#x15.9.1.1
*
* @param date - The date to check
*
* @returns The date is valid
*
* @example
* // For the valid date:
* const result = isValid(new Date(2014, 1, 31))
* //=> true
*
* @example
* // For the value, convertible into a date:
* const result = isValid(1393804800000)
* //=> true
*
* @example
* // For the invalid date:
* const result = isValid(new Date(''))
* //=> false
*/
function isValid(date) {
	return !(!isDate(date) && typeof date !== "number" || isNaN(+toDate(date)));
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/differenceInCalendarMonths.js
/**
* The {@link differenceInCalendarMonths} function options.
*/
/**
* @name differenceInCalendarMonths
* @category Month Helpers
* @summary Get the number of calendar months between the given dates.
*
* @description
* Get the number of calendar months between the given dates.
*
* @param laterDate - The later date
* @param earlierDate - The earlier date
* @param options - An object with options
*
* @returns The number of calendar months
*
* @example
* // How many calendar months are between 31 January 2014 and 1 September 2014?
* const result = differenceInCalendarMonths(
*   new Date(2014, 8, 1),
*   new Date(2014, 0, 31)
* )
* //=> 8
*/
function differenceInCalendarMonths(laterDate, earlierDate, options) {
	const [laterDate_, earlierDate_] = normalizeDates(options?.in, laterDate, earlierDate);
	const yearsDiff = laterDate_.getFullYear() - earlierDate_.getFullYear();
	const monthsDiff = laterDate_.getMonth() - earlierDate_.getMonth();
	return yearsDiff * 12 + monthsDiff;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/endOfMonth.js
/**
* The {@link endOfMonth} function options.
*/
/**
* @name endOfMonth
* @category Month Helpers
* @summary Return the end of a month for the given date.
*
* @description
* Return the end of a month for the given date.
* The result will be in the local timezone.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The end of a month
*
* @example
* // The end of a month for 2 September 2014 11:55:00:
* const result = endOfMonth(new Date(2014, 8, 2, 11, 55, 0))
* //=> Tue Sep 30 2014 23:59:59.999
*/
function endOfMonth(date, options) {
	const _date = toDate(date, options?.in);
	const month = _date.getMonth();
	_date.setFullYear(_date.getFullYear(), month + 1, 0);
	_date.setHours(23, 59, 59, 999);
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/normalizeInterval.js
function normalizeInterval(context, interval) {
	const [start, end] = normalizeDates(context, interval.start, interval.end);
	return {
		start,
		end
	};
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/eachMonthOfInterval.js
/**
* The {@link eachMonthOfInterval} function options.
*/
/**
* The {@link eachMonthOfInterval} function result type. It resolves the proper data type.
*/
/**
* @name eachMonthOfInterval
* @category Interval Helpers
* @summary Return the array of months within the specified time interval.
*
* @description
* Return the array of months within the specified time interval.
*
* @typeParam IntervalType - Interval type.
* @typeParam Options - Options type.
*
* @param interval - The interval.
* @param options - An object with options.
*
* @returns The array with starts of months from the month of the interval start to the month of the interval end
*
* @example
* // Each month between 6 February 2014 and 10 August 2014:
* const result = eachMonthOfInterval({
*   start: new Date(2014, 1, 6),
*   end: new Date(2014, 7, 10)
* })
* //=> [
* //   Sat Feb 01 2014 00:00:00,
* //   Sat Mar 01 2014 00:00:00,
* //   Tue Apr 01 2014 00:00:00,
* //   Thu May 01 2014 00:00:00,
* //   Sun Jun 01 2014 00:00:00,
* //   Tue Jul 01 2014 00:00:00,
* //   Fri Aug 01 2014 00:00:00
* // ]
*/
function eachMonthOfInterval(interval, options) {
	const { start, end } = normalizeInterval(options?.in, interval);
	let reversed = +start > +end;
	const endTime = reversed ? +start : +end;
	const date = reversed ? end : start;
	date.setHours(0, 0, 0, 0);
	date.setDate(1);
	let step = options?.step ?? 1;
	if (!step) return [];
	if (step < 0) {
		step = -step;
		reversed = !reversed;
	}
	const dates = [];
	while (+date <= endTime) {
		dates.push(constructFrom(start, date));
		date.setMonth(date.getMonth() + step);
	}
	return reversed ? dates.reverse() : dates;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/startOfMonth.js
/**
* The {@link startOfMonth} function options.
*/
/**
* @name startOfMonth
* @category Month Helpers
* @summary Return the start of a month for the given date.
*
* @description
* Return the start of a month for the given date. The result will be in the local timezone.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments.
* Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed,
* or inferred from the arguments.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The start of a month
*
* @example
* // The start of a month for 2 September 2014 11:55:00:
* const result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))
* //=> Mon Sep 01 2014 00:00:00
*/
function startOfMonth(date, options) {
	const _date = toDate(date, options?.in);
	_date.setDate(1);
	_date.setHours(0, 0, 0, 0);
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/endOfYear.js
/**
* The {@link endOfYear} function options.
*/
/**
* @name endOfYear
* @category Year Helpers
* @summary Return the end of a year for the given date.
*
* @description
* Return the end of a year for the given date.
* The result will be in the local timezone.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - The options
*
* @returns The end of a year
*
* @example
* // The end of a year for 2 September 2014 11:55:00:
* const result = endOfYear(new Date(2014, 8, 2, 11, 55, 0))
* //=> Wed Dec 31 2014 23:59:59.999
*/
function endOfYear(date, options) {
	const _date = toDate(date, options?.in);
	const year = _date.getFullYear();
	_date.setFullYear(year + 1, 0, 0);
	_date.setHours(23, 59, 59, 999);
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/startOfYear.js
/**
* The {@link startOfYear} function options.
*/
/**
* @name startOfYear
* @category Year Helpers
* @summary Return the start of a year for the given date.
*
* @description
* Return the start of a year for the given date.
* The result will be in the local timezone.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - The options
*
* @returns The start of a year
*
* @example
* // The start of a year for 2 September 2014 11:55:00:
* const result = startOfYear(new Date(2014, 8, 2, 11, 55, 00))
* //=> Wed Jan 01 2014 00:00:00
*/
function startOfYear(date, options) {
	const date_ = toDate(date, options?.in);
	date_.setFullYear(date_.getFullYear(), 0, 1);
	date_.setHours(0, 0, 0, 0);
	return date_;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/eachYearOfInterval.js
/**
* The {@link eachYearOfInterval} function options.
*/
/**
* The {@link eachYearOfInterval} function result type. It resolves the proper data type.
* It uses the first argument date object type, starting from the date argument,
* then the start interval date, and finally the end interval date. If
* a context function is passed, it uses the context function return type.
*/
/**
* @name eachYearOfInterval
* @category Interval Helpers
* @summary Return the array of yearly timestamps within the specified time interval.
*
* @description
* Return the array of yearly timestamps within the specified time interval.
*
* @typeParam IntervalType - Interval type.
* @typeParam Options - Options type.
*
* @param interval - The interval.
* @param options - An object with options.
*
* @returns The array with starts of yearly timestamps from the month of the interval start to the month of the interval end
*
* @example
* // Each year between 6 February 2014 and 10 August 2017:
* const result = eachYearOfInterval({
*   start: new Date(2014, 1, 6),
*   end: new Date(2017, 7, 10)
* })
* //=> [
* //   Wed Jan 01 2014 00:00:00,
* //   Thu Jan 01 2015 00:00:00,
* //   Fri Jan 01 2016 00:00:00,
* //   Sun Jan 01 2017 00:00:00
* // ]
*/
function eachYearOfInterval(interval, options) {
	const { start, end } = normalizeInterval(options?.in, interval);
	let reversed = +start > +end;
	const endTime = reversed ? +start : +end;
	const date = reversed ? end : start;
	date.setHours(0, 0, 0, 0);
	date.setMonth(0, 1);
	let step = options?.step ?? 1;
	if (!step) return [];
	if (step < 0) {
		step = -step;
		reversed = !reversed;
	}
	const dates = [];
	while (+date <= endTime) {
		dates.push(constructFrom(start, date));
		date.setFullYear(date.getFullYear() + step);
	}
	return reversed ? dates.reverse() : dates;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/endOfWeek.js
/**
* The {@link endOfWeek} function options.
*/
/**
* @name endOfWeek
* @category Week Helpers
* @summary Return the end of a week for the given date.
*
* @description
* Return the end of a week for the given date.
* The result will be in the local timezone.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The end of a week
*
* @example
* // The end of a week for 2 September 2014 11:55:00:
* const result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sat Sep 06 2014 23:59:59.999
*
* @example
* // If the week starts on Monday, the end of the week for 2 September 2014 11:55:00:
* const result = endOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
* //=> Sun Sep 07 2014 23:59:59.999
*/
function endOfWeek(date, options) {
	const defaultOptions = getDefaultOptions();
	const weekStartsOn = options?.weekStartsOn ?? options?.locale?.options?.weekStartsOn ?? defaultOptions.weekStartsOn ?? defaultOptions.locale?.options?.weekStartsOn ?? 0;
	const _date = toDate(date, options?.in);
	const day = _date.getDay();
	const diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);
	_date.setDate(_date.getDate() + diff);
	_date.setHours(23, 59, 59, 999);
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/endOfISOWeek.js
/**
* The {@link endOfISOWeek} function options.
*/
/**
* @name endOfISOWeek
* @category ISO Week Helpers
* @summary Return the end of an ISO week for the given date.
*
* @description
* Return the end of an ISO week for the given date.
* The result will be in the local timezone.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The end of an ISO week
*
* @example
* // The end of an ISO week for 2 September 2014 11:55:00:
* const result = endOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))
* //=> Sun Sep 07 2014 23:59:59.999
*/
function endOfISOWeek(date, options) {
	return endOfWeek(date, {
		...options,
		weekStartsOn: 1
	});
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/en-US/_lib/formatDistance.js
var formatDistanceLocale = {
	lessThanXSeconds: {
		one: "less than a second",
		other: "less than {{count}} seconds"
	},
	xSeconds: {
		one: "1 second",
		other: "{{count}} seconds"
	},
	halfAMinute: "half a minute",
	lessThanXMinutes: {
		one: "less than a minute",
		other: "less than {{count}} minutes"
	},
	xMinutes: {
		one: "1 minute",
		other: "{{count}} minutes"
	},
	aboutXHours: {
		one: "about 1 hour",
		other: "about {{count}} hours"
	},
	xHours: {
		one: "1 hour",
		other: "{{count}} hours"
	},
	xDays: {
		one: "1 day",
		other: "{{count}} days"
	},
	aboutXWeeks: {
		one: "about 1 week",
		other: "about {{count}} weeks"
	},
	xWeeks: {
		one: "1 week",
		other: "{{count}} weeks"
	},
	aboutXMonths: {
		one: "about 1 month",
		other: "about {{count}} months"
	},
	xMonths: {
		one: "1 month",
		other: "{{count}} months"
	},
	aboutXYears: {
		one: "about 1 year",
		other: "about {{count}} years"
	},
	xYears: {
		one: "1 year",
		other: "{{count}} years"
	},
	overXYears: {
		one: "over 1 year",
		other: "over {{count}} years"
	},
	almostXYears: {
		one: "almost 1 year",
		other: "almost {{count}} years"
	}
};
var formatDistance = (token, count, options) => {
	let result;
	const tokenValue = formatDistanceLocale[token];
	if (typeof tokenValue === "string") result = tokenValue;
	else if (count === 1) result = tokenValue.one;
	else result = tokenValue.other.replace("{{count}}", count.toString());
	if (options?.addSuffix) {
		if (options.comparison && options.comparison > 0) return "in " + result;
		else return result + " ago";
	}
	return result;
};
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/_lib/buildFormatLongFn.js
function buildFormatLongFn(args) {
	return (options = {}) => {
		const width = options.width ? String(options.width) : args.defaultWidth;
		return args.formats[width] || args.formats[args.defaultWidth];
	};
}
var formatLong = {
	date: buildFormatLongFn({
		formats: {
			full: "EEEE, MMMM do, y",
			long: "MMMM do, y",
			medium: "MMM d, y",
			short: "MM/dd/yyyy"
		},
		defaultWidth: "full"
	}),
	time: buildFormatLongFn({
		formats: {
			full: "h:mm:ss a zzzz",
			long: "h:mm:ss a z",
			medium: "h:mm:ss a",
			short: "h:mm a"
		},
		defaultWidth: "full"
	}),
	dateTime: buildFormatLongFn({
		formats: {
			full: "{{date}} 'at' {{time}}",
			long: "{{date}} 'at' {{time}}",
			medium: "{{date}}, {{time}}",
			short: "{{date}}, {{time}}"
		},
		defaultWidth: "full"
	})
};
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/en-US/_lib/formatRelative.js
var formatRelativeLocale = {
	lastWeek: "'last' eeee 'at' p",
	yesterday: "'yesterday at' p",
	today: "'today at' p",
	tomorrow: "'tomorrow at' p",
	nextWeek: "eeee 'at' p",
	other: "P"
};
var formatRelative = (token, _date, _baseDate, _options) => formatRelativeLocale[token];
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/_lib/buildLocalizeFn.js
/**
* The localize function argument callback which allows to convert raw value to
* the actual type.
*
* @param value - The value to convert
*
* @returns The converted value
*/
/**
* The map of localized values for each width.
*/
/**
* The index type of the locale unit value. It types conversion of units of
* values that don't start at 0 (i.e. quarters).
*/
/**
* Converts the unit value to the tuple of values.
*/
/**
* The tuple of localized era values. The first element represents BC,
* the second element represents AD.
*/
/**
* The tuple of localized quarter values. The first element represents Q1.
*/
/**
* The tuple of localized day values. The first element represents Sunday.
*/
/**
* The tuple of localized month values. The first element represents January.
*/
function buildLocalizeFn(args) {
	return (value, options) => {
		const context = options?.context ? String(options.context) : "standalone";
		let valuesArray;
		if (context === "formatting" && args.formattingValues) {
			const defaultWidth = args.defaultFormattingWidth || args.defaultWidth;
			const width = options?.width ? String(options.width) : defaultWidth;
			valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];
		} else {
			const defaultWidth = args.defaultWidth;
			const width = options?.width ? String(options.width) : args.defaultWidth;
			valuesArray = args.values[width] || args.values[defaultWidth];
		}
		const index = args.argumentCallback ? args.argumentCallback(value) : value;
		return valuesArray[index];
	};
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/en-US/_lib/localize.js
var eraValues = {
	narrow: ["B", "A"],
	abbreviated: ["BC", "AD"],
	wide: ["Before Christ", "Anno Domini"]
};
var quarterValues = {
	narrow: [
		"1",
		"2",
		"3",
		"4"
	],
	abbreviated: [
		"Q1",
		"Q2",
		"Q3",
		"Q4"
	],
	wide: [
		"1st quarter",
		"2nd quarter",
		"3rd quarter",
		"4th quarter"
	]
};
var monthValues = {
	narrow: [
		"J",
		"F",
		"M",
		"A",
		"M",
		"J",
		"J",
		"A",
		"S",
		"O",
		"N",
		"D"
	],
	abbreviated: [
		"Jan",
		"Feb",
		"Mar",
		"Apr",
		"May",
		"Jun",
		"Jul",
		"Aug",
		"Sep",
		"Oct",
		"Nov",
		"Dec"
	],
	wide: [
		"January",
		"February",
		"March",
		"April",
		"May",
		"June",
		"July",
		"August",
		"September",
		"October",
		"November",
		"December"
	]
};
var dayValues = {
	narrow: [
		"S",
		"M",
		"T",
		"W",
		"T",
		"F",
		"S"
	],
	short: [
		"Su",
		"Mo",
		"Tu",
		"We",
		"Th",
		"Fr",
		"Sa"
	],
	abbreviated: [
		"Sun",
		"Mon",
		"Tue",
		"Wed",
		"Thu",
		"Fri",
		"Sat"
	],
	wide: [
		"Sunday",
		"Monday",
		"Tuesday",
		"Wednesday",
		"Thursday",
		"Friday",
		"Saturday"
	]
};
var dayPeriodValues = {
	narrow: {
		am: "a",
		pm: "p",
		midnight: "mi",
		noon: "n",
		morning: "morning",
		afternoon: "afternoon",
		evening: "evening",
		night: "night"
	},
	abbreviated: {
		am: "AM",
		pm: "PM",
		midnight: "midnight",
		noon: "noon",
		morning: "morning",
		afternoon: "afternoon",
		evening: "evening",
		night: "night"
	},
	wide: {
		am: "a.m.",
		pm: "p.m.",
		midnight: "midnight",
		noon: "noon",
		morning: "morning",
		afternoon: "afternoon",
		evening: "evening",
		night: "night"
	}
};
var formattingDayPeriodValues = {
	narrow: {
		am: "a",
		pm: "p",
		midnight: "mi",
		noon: "n",
		morning: "in the morning",
		afternoon: "in the afternoon",
		evening: "in the evening",
		night: "at night"
	},
	abbreviated: {
		am: "AM",
		pm: "PM",
		midnight: "midnight",
		noon: "noon",
		morning: "in the morning",
		afternoon: "in the afternoon",
		evening: "in the evening",
		night: "at night"
	},
	wide: {
		am: "a.m.",
		pm: "p.m.",
		midnight: "midnight",
		noon: "noon",
		morning: "in the morning",
		afternoon: "in the afternoon",
		evening: "in the evening",
		night: "at night"
	}
};
var ordinalNumber = (dirtyNumber, _options) => {
	const number = Number(dirtyNumber);
	const rem100 = number % 100;
	if (rem100 > 20 || rem100 < 10) switch (rem100 % 10) {
		case 1: return number + "st";
		case 2: return number + "nd";
		case 3: return number + "rd";
	}
	return number + "th";
};
var localize = {
	ordinalNumber,
	era: buildLocalizeFn({
		values: eraValues,
		defaultWidth: "wide"
	}),
	quarter: buildLocalizeFn({
		values: quarterValues,
		defaultWidth: "wide",
		argumentCallback: (quarter) => quarter - 1
	}),
	month: buildLocalizeFn({
		values: monthValues,
		defaultWidth: "wide"
	}),
	day: buildLocalizeFn({
		values: dayValues,
		defaultWidth: "wide"
	}),
	dayPeriod: buildLocalizeFn({
		values: dayPeriodValues,
		defaultWidth: "wide",
		formattingValues: formattingDayPeriodValues,
		defaultFormattingWidth: "wide"
	})
};
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/_lib/buildMatchFn.js
function buildMatchFn(args) {
	return (string, options = {}) => {
		const width = options.width;
		const matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];
		const matchResult = string.match(matchPattern);
		if (!matchResult) return null;
		const matchedString = matchResult[0];
		const parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];
		const key = Array.isArray(parsePatterns) ? findIndex(parsePatterns, (pattern) => pattern.test(matchedString)) : findKey(parsePatterns, (pattern) => pattern.test(matchedString));
		let value;
		value = args.valueCallback ? args.valueCallback(key) : key;
		value = options.valueCallback ? options.valueCallback(value) : value;
		const rest = string.slice(matchedString.length);
		return {
			value,
			rest
		};
	};
}
function findKey(object, predicate) {
	for (const key in object) if (Object.prototype.hasOwnProperty.call(object, key) && predicate(object[key])) return key;
}
function findIndex(array, predicate) {
	for (let key = 0; key < array.length; key++) if (predicate(array[key])) return key;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/_lib/buildMatchPatternFn.js
function buildMatchPatternFn(args) {
	return (string, options = {}) => {
		const matchResult = string.match(args.matchPattern);
		if (!matchResult) return null;
		const matchedString = matchResult[0];
		const parseResult = string.match(args.parsePattern);
		if (!parseResult) return null;
		let value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];
		value = options.valueCallback ? options.valueCallback(value) : value;
		const rest = string.slice(matchedString.length);
		return {
			value,
			rest
		};
	};
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/locale/en-US.js
/**
* @category Locales
* @summary English locale (United States).
* @language English
* @iso-639-2 eng
* @author Sasha Koss [@kossnocorp](https://github.com/kossnocorp)
* @author Lesha Koss [@leshakoss](https://github.com/leshakoss)
*/
var enUS$1 = {
	code: "en-US",
	formatDistance,
	formatLong,
	formatRelative,
	localize,
	match: {
		ordinalNumber: buildMatchPatternFn({
			matchPattern: /^(\d+)(th|st|nd|rd)?/i,
			parsePattern: /\d+/i,
			valueCallback: (value) => parseInt(value, 10)
		}),
		era: buildMatchFn({
			matchPatterns: {
				narrow: /^(b|a)/i,
				abbreviated: /^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,
				wide: /^(before christ|before common era|anno domini|common era)/i
			},
			defaultMatchWidth: "wide",
			parsePatterns: { any: [/^b/i, /^(a|c)/i] },
			defaultParseWidth: "any"
		}),
		quarter: buildMatchFn({
			matchPatterns: {
				narrow: /^[1234]/i,
				abbreviated: /^q[1234]/i,
				wide: /^[1234](th|st|nd|rd)? quarter/i
			},
			defaultMatchWidth: "wide",
			parsePatterns: { any: [
				/1/i,
				/2/i,
				/3/i,
				/4/i
			] },
			defaultParseWidth: "any",
			valueCallback: (index) => index + 1
		}),
		month: buildMatchFn({
			matchPatterns: {
				narrow: /^[jfmasond]/i,
				abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,
				wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i
			},
			defaultMatchWidth: "wide",
			parsePatterns: {
				narrow: [
					/^j/i,
					/^f/i,
					/^m/i,
					/^a/i,
					/^m/i,
					/^j/i,
					/^j/i,
					/^a/i,
					/^s/i,
					/^o/i,
					/^n/i,
					/^d/i
				],
				any: [
					/^ja/i,
					/^f/i,
					/^mar/i,
					/^ap/i,
					/^may/i,
					/^jun/i,
					/^jul/i,
					/^au/i,
					/^s/i,
					/^o/i,
					/^n/i,
					/^d/i
				]
			},
			defaultParseWidth: "any"
		}),
		day: buildMatchFn({
			matchPatterns: {
				narrow: /^[smtwf]/i,
				short: /^(su|mo|tu|we|th|fr|sa)/i,
				abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,
				wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i
			},
			defaultMatchWidth: "wide",
			parsePatterns: {
				narrow: [
					/^s/i,
					/^m/i,
					/^t/i,
					/^w/i,
					/^t/i,
					/^f/i,
					/^s/i
				],
				any: [
					/^su/i,
					/^m/i,
					/^tu/i,
					/^w/i,
					/^th/i,
					/^f/i,
					/^sa/i
				]
			},
			defaultParseWidth: "any"
		}),
		dayPeriod: buildMatchFn({
			matchPatterns: {
				narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,
				any: /^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i
			},
			defaultMatchWidth: "any",
			parsePatterns: { any: {
				am: /^a/i,
				pm: /^p/i,
				midnight: /^mi/i,
				noon: /^no/i,
				morning: /morning/i,
				afternoon: /afternoon/i,
				evening: /evening/i,
				night: /night/i
			} },
			defaultParseWidth: "any"
		})
	},
	options: {
		weekStartsOn: 0,
		firstWeekContainsDate: 1
	}
};
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getDayOfYear.js
/**
* The {@link getDayOfYear} function options.
*/
/**
* @name getDayOfYear
* @category Day Helpers
* @summary Get the day of the year of the given date.
*
* @description
* Get the day of the year of the given date.
*
* @param date - The given date
* @param options - The options
*
* @returns The day of year
*
* @example
* // Which day of the year is 2 July 2014?
* const result = getDayOfYear(new Date(2014, 6, 2))
* //=> 183
*/
function getDayOfYear(date, options) {
	const _date = toDate(date, options?.in);
	return differenceInCalendarDays(_date, startOfYear(_date)) + 1;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getISOWeek.js
/**
* The {@link getISOWeek} function options.
*/
/**
* @name getISOWeek
* @category ISO Week Helpers
* @summary Get the ISO week of the given date.
*
* @description
* Get the ISO week of the given date.
*
* ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
*
* @param date - The given date
* @param options - The options
*
* @returns The ISO week
*
* @example
* // Which week of the ISO-week numbering year is 2 January 2005?
* const result = getISOWeek(new Date(2005, 0, 2))
* //=> 53
*/
function getISOWeek(date, options) {
	const _date = toDate(date, options?.in);
	const diff = +startOfISOWeek(_date) - +startOfISOWeekYear(_date);
	return Math.round(diff / millisecondsInWeek) + 1;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getWeekYear.js
/**
* The {@link getWeekYear} function options.
*/
/**
* @name getWeekYear
* @category Week-Numbering Year Helpers
* @summary Get the local week-numbering year of the given date.
*
* @description
* Get the local week-numbering year of the given date.
* The exact calculation depends on the values of
* `options.weekStartsOn` (which is the index of the first day of the week)
* and `options.firstWeekContainsDate` (which is the day of January, which is always in
* the first week of the week-numbering year)
*
* Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
*
* @param date - The given date
* @param options - An object with options.
*
* @returns The local week-numbering year
*
* @example
* // Which week numbering year is 26 December 2004 with the default settings?
* const result = getWeekYear(new Date(2004, 11, 26))
* //=> 2005
*
* @example
* // Which week numbering year is 26 December 2004 if week starts on Saturday?
* const result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 })
* //=> 2004
*
* @example
* // Which week numbering year is 26 December 2004 if the first week contains 4 January?
* const result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })
* //=> 2004
*/
function getWeekYear(date, options) {
	const _date = toDate(date, options?.in);
	const year = _date.getFullYear();
	const defaultOptions = getDefaultOptions();
	const firstWeekContainsDate = options?.firstWeekContainsDate ?? options?.locale?.options?.firstWeekContainsDate ?? defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
	const firstWeekOfNextYear = constructFrom(options?.in || date, 0);
	firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);
	firstWeekOfNextYear.setHours(0, 0, 0, 0);
	const startOfNextYear = startOfWeek(firstWeekOfNextYear, options);
	const firstWeekOfThisYear = constructFrom(options?.in || date, 0);
	firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);
	firstWeekOfThisYear.setHours(0, 0, 0, 0);
	const startOfThisYear = startOfWeek(firstWeekOfThisYear, options);
	if (+_date >= +startOfNextYear) return year + 1;
	else if (+_date >= +startOfThisYear) return year;
	else return year - 1;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/startOfWeekYear.js
/**
* The {@link startOfWeekYear} function options.
*/
/**
* @name startOfWeekYear
* @category Week-Numbering Year Helpers
* @summary Return the start of a local week-numbering year for the given date.
*
* @description
* Return the start of a local week-numbering year.
* The exact calculation depends on the values of
* `options.weekStartsOn` (which is the index of the first day of the week)
* and `options.firstWeekContainsDate` (which is the day of January, which is always in
* the first week of the week-numbering year)
*
* Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type.
*
* @param date - The original date
* @param options - An object with options
*
* @returns The start of a week-numbering year
*
* @example
* // The start of an a week-numbering year for 2 July 2005 with default settings:
* const result = startOfWeekYear(new Date(2005, 6, 2))
* //=> Sun Dec 26 2004 00:00:00
*
* @example
* // The start of a week-numbering year for 2 July 2005
* // if Monday is the first day of week
* // and 4 January is always in the first week of the year:
* const result = startOfWeekYear(new Date(2005, 6, 2), {
*   weekStartsOn: 1,
*   firstWeekContainsDate: 4
* })
* //=> Mon Jan 03 2005 00:00:00
*/
function startOfWeekYear(date, options) {
	const defaultOptions = getDefaultOptions();
	const firstWeekContainsDate = options?.firstWeekContainsDate ?? options?.locale?.options?.firstWeekContainsDate ?? defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
	const year = getWeekYear(date, options);
	const firstWeek = constructFrom(options?.in || date, 0);
	firstWeek.setFullYear(year, 0, firstWeekContainsDate);
	firstWeek.setHours(0, 0, 0, 0);
	return startOfWeek(firstWeek, options);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getWeek.js
/**
* The {@link getWeek} function options.
*/
/**
* @name getWeek
* @category Week Helpers
* @summary Get the local week index of the given date.
*
* @description
* Get the local week index of the given date.
* The exact calculation depends on the values of
* `options.weekStartsOn` (which is the index of the first day of the week)
* and `options.firstWeekContainsDate` (which is the day of January, which is always in
* the first week of the week-numbering year)
*
* Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
*
* @param date - The given date
* @param options - An object with options
*
* @returns The week
*
* @example
* // Which week of the local week numbering year is 2 January 2005 with default options?
* const result = getWeek(new Date(2005, 0, 2))
* //=> 2
*
* @example
* // Which week of the local week numbering year is 2 January 2005,
* // if Monday is the first day of the week,
* // and the first week of the year always contains 4 January?
* const result = getWeek(new Date(2005, 0, 2), {
*   weekStartsOn: 1,
*   firstWeekContainsDate: 4
* })
* //=> 53
*/
function getWeek(date, options) {
	const _date = toDate(date, options?.in);
	const diff = +startOfWeek(_date, options) - +startOfWeekYear(_date, options);
	return Math.round(diff / millisecondsInWeek) + 1;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/addLeadingZeros.js
function addLeadingZeros(number, targetLength) {
	return (number < 0 ? "-" : "") + Math.abs(number).toString().padStart(targetLength, "0");
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/format/lightFormatters.js
var lightFormatters = {
	y(date, token) {
		const signedYear = date.getFullYear();
		const year = signedYear > 0 ? signedYear : 1 - signedYear;
		return addLeadingZeros(token === "yy" ? year % 100 : year, token.length);
	},
	M(date, token) {
		const month = date.getMonth();
		return token === "M" ? String(month + 1) : addLeadingZeros(month + 1, 2);
	},
	d(date, token) {
		return addLeadingZeros(date.getDate(), token.length);
	},
	a(date, token) {
		const dayPeriodEnumValue = date.getHours() / 12 >= 1 ? "pm" : "am";
		switch (token) {
			case "a":
			case "aa": return dayPeriodEnumValue.toUpperCase();
			case "aaa": return dayPeriodEnumValue;
			case "aaaaa": return dayPeriodEnumValue[0];
			default: return dayPeriodEnumValue === "am" ? "a.m." : "p.m.";
		}
	},
	h(date, token) {
		return addLeadingZeros(date.getHours() % 12 || 12, token.length);
	},
	H(date, token) {
		return addLeadingZeros(date.getHours(), token.length);
	},
	m(date, token) {
		return addLeadingZeros(date.getMinutes(), token.length);
	},
	s(date, token) {
		return addLeadingZeros(date.getSeconds(), token.length);
	},
	S(date, token) {
		const numberOfDigits = token.length;
		const milliseconds = date.getMilliseconds();
		return addLeadingZeros(Math.trunc(milliseconds * Math.pow(10, numberOfDigits - 3)), token.length);
	}
};
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/format/formatters.js
var dayPeriodEnum = {
	am: "am",
	pm: "pm",
	midnight: "midnight",
	noon: "noon",
	morning: "morning",
	afternoon: "afternoon",
	evening: "evening",
	night: "night"
};
var formatters = {
	G: function(date, token, localize) {
		const era = date.getFullYear() > 0 ? 1 : 0;
		switch (token) {
			case "G":
			case "GG":
			case "GGG": return localize.era(era, { width: "abbreviated" });
			case "GGGGG": return localize.era(era, { width: "narrow" });
			default: return localize.era(era, { width: "wide" });
		}
	},
	y: function(date, token, localize) {
		if (token === "yo") {
			const signedYear = date.getFullYear();
			const year = signedYear > 0 ? signedYear : 1 - signedYear;
			return localize.ordinalNumber(year, { unit: "year" });
		}
		return lightFormatters.y(date, token);
	},
	Y: function(date, token, localize, options) {
		const signedWeekYear = getWeekYear(date, options);
		const weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear;
		if (token === "YY") return addLeadingZeros(weekYear % 100, 2);
		if (token === "Yo") return localize.ordinalNumber(weekYear, { unit: "year" });
		return addLeadingZeros(weekYear, token.length);
	},
	R: function(date, token) {
		return addLeadingZeros(getISOWeekYear(date), token.length);
	},
	u: function(date, token) {
		return addLeadingZeros(date.getFullYear(), token.length);
	},
	Q: function(date, token, localize) {
		const quarter = Math.ceil((date.getMonth() + 1) / 3);
		switch (token) {
			case "Q": return String(quarter);
			case "QQ": return addLeadingZeros(quarter, 2);
			case "Qo": return localize.ordinalNumber(quarter, { unit: "quarter" });
			case "QQQ": return localize.quarter(quarter, {
				width: "abbreviated",
				context: "formatting"
			});
			case "QQQQQ": return localize.quarter(quarter, {
				width: "narrow",
				context: "formatting"
			});
			default: return localize.quarter(quarter, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	q: function(date, token, localize) {
		const quarter = Math.ceil((date.getMonth() + 1) / 3);
		switch (token) {
			case "q": return String(quarter);
			case "qq": return addLeadingZeros(quarter, 2);
			case "qo": return localize.ordinalNumber(quarter, { unit: "quarter" });
			case "qqq": return localize.quarter(quarter, {
				width: "abbreviated",
				context: "standalone"
			});
			case "qqqqq": return localize.quarter(quarter, {
				width: "narrow",
				context: "standalone"
			});
			default: return localize.quarter(quarter, {
				width: "wide",
				context: "standalone"
			});
		}
	},
	M: function(date, token, localize) {
		const month = date.getMonth();
		switch (token) {
			case "M":
			case "MM": return lightFormatters.M(date, token);
			case "Mo": return localize.ordinalNumber(month + 1, { unit: "month" });
			case "MMM": return localize.month(month, {
				width: "abbreviated",
				context: "formatting"
			});
			case "MMMMM": return localize.month(month, {
				width: "narrow",
				context: "formatting"
			});
			default: return localize.month(month, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	L: function(date, token, localize) {
		const month = date.getMonth();
		switch (token) {
			case "L": return String(month + 1);
			case "LL": return addLeadingZeros(month + 1, 2);
			case "Lo": return localize.ordinalNumber(month + 1, { unit: "month" });
			case "LLL": return localize.month(month, {
				width: "abbreviated",
				context: "standalone"
			});
			case "LLLLL": return localize.month(month, {
				width: "narrow",
				context: "standalone"
			});
			default: return localize.month(month, {
				width: "wide",
				context: "standalone"
			});
		}
	},
	w: function(date, token, localize, options) {
		const week = getWeek(date, options);
		if (token === "wo") return localize.ordinalNumber(week, { unit: "week" });
		return addLeadingZeros(week, token.length);
	},
	I: function(date, token, localize) {
		const isoWeek = getISOWeek(date);
		if (token === "Io") return localize.ordinalNumber(isoWeek, { unit: "week" });
		return addLeadingZeros(isoWeek, token.length);
	},
	d: function(date, token, localize) {
		if (token === "do") return localize.ordinalNumber(date.getDate(), { unit: "date" });
		return lightFormatters.d(date, token);
	},
	D: function(date, token, localize) {
		const dayOfYear = getDayOfYear(date);
		if (token === "Do") return localize.ordinalNumber(dayOfYear, { unit: "dayOfYear" });
		return addLeadingZeros(dayOfYear, token.length);
	},
	E: function(date, token, localize) {
		const dayOfWeek = date.getDay();
		switch (token) {
			case "E":
			case "EE":
			case "EEE": return localize.day(dayOfWeek, {
				width: "abbreviated",
				context: "formatting"
			});
			case "EEEEE": return localize.day(dayOfWeek, {
				width: "narrow",
				context: "formatting"
			});
			case "EEEEEE": return localize.day(dayOfWeek, {
				width: "short",
				context: "formatting"
			});
			default: return localize.day(dayOfWeek, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	e: function(date, token, localize, options) {
		const dayOfWeek = date.getDay();
		const localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
		switch (token) {
			case "e": return String(localDayOfWeek);
			case "ee": return addLeadingZeros(localDayOfWeek, 2);
			case "eo": return localize.ordinalNumber(localDayOfWeek, { unit: "day" });
			case "eee": return localize.day(dayOfWeek, {
				width: "abbreviated",
				context: "formatting"
			});
			case "eeeee": return localize.day(dayOfWeek, {
				width: "narrow",
				context: "formatting"
			});
			case "eeeeee": return localize.day(dayOfWeek, {
				width: "short",
				context: "formatting"
			});
			default: return localize.day(dayOfWeek, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	c: function(date, token, localize, options) {
		const dayOfWeek = date.getDay();
		const localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
		switch (token) {
			case "c": return String(localDayOfWeek);
			case "cc": return addLeadingZeros(localDayOfWeek, token.length);
			case "co": return localize.ordinalNumber(localDayOfWeek, { unit: "day" });
			case "ccc": return localize.day(dayOfWeek, {
				width: "abbreviated",
				context: "standalone"
			});
			case "ccccc": return localize.day(dayOfWeek, {
				width: "narrow",
				context: "standalone"
			});
			case "cccccc": return localize.day(dayOfWeek, {
				width: "short",
				context: "standalone"
			});
			default: return localize.day(dayOfWeek, {
				width: "wide",
				context: "standalone"
			});
		}
	},
	i: function(date, token, localize) {
		const dayOfWeek = date.getDay();
		const isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;
		switch (token) {
			case "i": return String(isoDayOfWeek);
			case "ii": return addLeadingZeros(isoDayOfWeek, token.length);
			case "io": return localize.ordinalNumber(isoDayOfWeek, { unit: "day" });
			case "iii": return localize.day(dayOfWeek, {
				width: "abbreviated",
				context: "formatting"
			});
			case "iiiii": return localize.day(dayOfWeek, {
				width: "narrow",
				context: "formatting"
			});
			case "iiiiii": return localize.day(dayOfWeek, {
				width: "short",
				context: "formatting"
			});
			default: return localize.day(dayOfWeek, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	a: function(date, token, localize) {
		const dayPeriodEnumValue = date.getHours() / 12 >= 1 ? "pm" : "am";
		switch (token) {
			case "a":
			case "aa": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "abbreviated",
				context: "formatting"
			});
			case "aaa": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "abbreviated",
				context: "formatting"
			}).toLowerCase();
			case "aaaaa": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "narrow",
				context: "formatting"
			});
			default: return localize.dayPeriod(dayPeriodEnumValue, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	b: function(date, token, localize) {
		const hours = date.getHours();
		let dayPeriodEnumValue;
		if (hours === 12) dayPeriodEnumValue = dayPeriodEnum.noon;
		else if (hours === 0) dayPeriodEnumValue = dayPeriodEnum.midnight;
		else dayPeriodEnumValue = hours / 12 >= 1 ? "pm" : "am";
		switch (token) {
			case "b":
			case "bb": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "abbreviated",
				context: "formatting"
			});
			case "bbb": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "abbreviated",
				context: "formatting"
			}).toLowerCase();
			case "bbbbb": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "narrow",
				context: "formatting"
			});
			default: return localize.dayPeriod(dayPeriodEnumValue, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	B: function(date, token, localize) {
		const hours = date.getHours();
		let dayPeriodEnumValue;
		if (hours >= 17) dayPeriodEnumValue = dayPeriodEnum.evening;
		else if (hours >= 12) dayPeriodEnumValue = dayPeriodEnum.afternoon;
		else if (hours >= 4) dayPeriodEnumValue = dayPeriodEnum.morning;
		else dayPeriodEnumValue = dayPeriodEnum.night;
		switch (token) {
			case "B":
			case "BB":
			case "BBB": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "abbreviated",
				context: "formatting"
			});
			case "BBBBB": return localize.dayPeriod(dayPeriodEnumValue, {
				width: "narrow",
				context: "formatting"
			});
			default: return localize.dayPeriod(dayPeriodEnumValue, {
				width: "wide",
				context: "formatting"
			});
		}
	},
	h: function(date, token, localize) {
		if (token === "ho") {
			let hours = date.getHours() % 12;
			if (hours === 0) hours = 12;
			return localize.ordinalNumber(hours, { unit: "hour" });
		}
		return lightFormatters.h(date, token);
	},
	H: function(date, token, localize) {
		if (token === "Ho") return localize.ordinalNumber(date.getHours(), { unit: "hour" });
		return lightFormatters.H(date, token);
	},
	K: function(date, token, localize) {
		const hours = date.getHours() % 12;
		if (token === "Ko") return localize.ordinalNumber(hours, { unit: "hour" });
		return addLeadingZeros(hours, token.length);
	},
	k: function(date, token, localize) {
		let hours = date.getHours();
		if (hours === 0) hours = 24;
		if (token === "ko") return localize.ordinalNumber(hours, { unit: "hour" });
		return addLeadingZeros(hours, token.length);
	},
	m: function(date, token, localize) {
		if (token === "mo") return localize.ordinalNumber(date.getMinutes(), { unit: "minute" });
		return lightFormatters.m(date, token);
	},
	s: function(date, token, localize) {
		if (token === "so") return localize.ordinalNumber(date.getSeconds(), { unit: "second" });
		return lightFormatters.s(date, token);
	},
	S: function(date, token) {
		return lightFormatters.S(date, token);
	},
	X: function(date, token, _localize) {
		const timezoneOffset = date.getTimezoneOffset();
		if (timezoneOffset === 0) return "Z";
		switch (token) {
			case "X": return formatTimezoneWithOptionalMinutes(timezoneOffset);
			case "XXXX":
			case "XX": return formatTimezone(timezoneOffset);
			default: return formatTimezone(timezoneOffset, ":");
		}
	},
	x: function(date, token, _localize) {
		const timezoneOffset = date.getTimezoneOffset();
		switch (token) {
			case "x": return formatTimezoneWithOptionalMinutes(timezoneOffset);
			case "xxxx":
			case "xx": return formatTimezone(timezoneOffset);
			default: return formatTimezone(timezoneOffset, ":");
		}
	},
	O: function(date, token, _localize) {
		const timezoneOffset = date.getTimezoneOffset();
		switch (token) {
			case "O":
			case "OO":
			case "OOO": return "GMT" + formatTimezoneShort(timezoneOffset, ":");
			default: return "GMT" + formatTimezone(timezoneOffset, ":");
		}
	},
	z: function(date, token, _localize) {
		const timezoneOffset = date.getTimezoneOffset();
		switch (token) {
			case "z":
			case "zz":
			case "zzz": return "GMT" + formatTimezoneShort(timezoneOffset, ":");
			default: return "GMT" + formatTimezone(timezoneOffset, ":");
		}
	},
	t: function(date, token, _localize) {
		return addLeadingZeros(Math.trunc(+date / 1e3), token.length);
	},
	T: function(date, token, _localize) {
		return addLeadingZeros(+date, token.length);
	}
};
function formatTimezoneShort(offset, delimiter = "") {
	const sign = offset > 0 ? "-" : "+";
	const absOffset = Math.abs(offset);
	const hours = Math.trunc(absOffset / 60);
	const minutes = absOffset % 60;
	if (minutes === 0) return sign + String(hours);
	return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2);
}
function formatTimezoneWithOptionalMinutes(offset, delimiter) {
	if (offset % 60 === 0) return (offset > 0 ? "-" : "+") + addLeadingZeros(Math.abs(offset) / 60, 2);
	return formatTimezone(offset, delimiter);
}
function formatTimezone(offset, delimiter = "") {
	const sign = offset > 0 ? "-" : "+";
	const absOffset = Math.abs(offset);
	const hours = addLeadingZeros(Math.trunc(absOffset / 60), 2);
	const minutes = addLeadingZeros(absOffset % 60, 2);
	return sign + hours + delimiter + minutes;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/format/longFormatters.js
var dateLongFormatter = (pattern, formatLong) => {
	switch (pattern) {
		case "P": return formatLong.date({ width: "short" });
		case "PP": return formatLong.date({ width: "medium" });
		case "PPP": return formatLong.date({ width: "long" });
		default: return formatLong.date({ width: "full" });
	}
};
var timeLongFormatter = (pattern, formatLong) => {
	switch (pattern) {
		case "p": return formatLong.time({ width: "short" });
		case "pp": return formatLong.time({ width: "medium" });
		case "ppp": return formatLong.time({ width: "long" });
		default: return formatLong.time({ width: "full" });
	}
};
var dateTimeLongFormatter = (pattern, formatLong) => {
	const matchResult = pattern.match(/(P+)(p+)?/) || [];
	const datePattern = matchResult[1];
	const timePattern = matchResult[2];
	if (!timePattern) return dateLongFormatter(pattern, formatLong);
	let dateTimeFormat;
	switch (datePattern) {
		case "P":
			dateTimeFormat = formatLong.dateTime({ width: "short" });
			break;
		case "PP":
			dateTimeFormat = formatLong.dateTime({ width: "medium" });
			break;
		case "PPP":
			dateTimeFormat = formatLong.dateTime({ width: "long" });
			break;
		default: dateTimeFormat = formatLong.dateTime({ width: "full" });
	}
	return dateTimeFormat.replace("{{date}}", dateLongFormatter(datePattern, formatLong)).replace("{{time}}", timeLongFormatter(timePattern, formatLong));
};
var longFormatters = {
	p: timeLongFormatter,
	P: dateTimeLongFormatter
};
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/_lib/protectedTokens.js
var dayOfYearTokenRE = /^D+$/;
var weekYearTokenRE = /^Y+$/;
var throwTokens = [
	"D",
	"DD",
	"YY",
	"YYYY"
];
function isProtectedDayOfYearToken(token) {
	return dayOfYearTokenRE.test(token);
}
function isProtectedWeekYearToken(token) {
	return weekYearTokenRE.test(token);
}
function warnOrThrowProtectedError(token, format, input) {
	const _message = message(token, format, input);
	console.warn(_message);
	if (throwTokens.includes(token)) throw new RangeError(_message);
}
function message(token, format, input) {
	const subject = token[0] === "Y" ? "years" : "days of the month";
	return `Use \`${token.toLowerCase()}\` instead of \`${token}\` (in \`${format}\`) for formatting ${subject} to the input \`${input}\`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md`;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/format.js
var formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g;
var longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;
var escapedStringRegExp = /^'([^]*?)'?$/;
var doubleQuoteRegExp = /''/g;
var unescapedLatinCharacterRegExp = /[a-zA-Z]/;
/**
* The {@link format} function options.
*/
/**
* @name format
* @alias formatDate
* @category Common Helpers
* @summary Format the date.
*
* @description
* Return the formatted date string in the given format. The result may vary by locale.
*
* > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.
* > See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
*
* The characters wrapped between two single quotes characters (') are escaped.
* Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.
* (see the last example)
*
* Format of the string is based on Unicode Technical Standard #35:
* https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
* with a few additions (see note 7 below the table).
*
* Accepted patterns:
* | Unit                            | Pattern | Result examples                   | Notes |
* |---------------------------------|---------|-----------------------------------|-------|
* | Era                             | G..GGG  | AD, BC                            |       |
* |                                 | GGGG    | Anno Domini, Before Christ        | 2     |
* |                                 | GGGGG   | A, B                              |       |
* | Calendar year                   | y       | 44, 1, 1900, 2017                 | 5     |
* |                                 | yo      | 44th, 1st, 0th, 17th              | 5,7   |
* |                                 | yy      | 44, 01, 00, 17                    | 5     |
* |                                 | yyy     | 044, 001, 1900, 2017              | 5     |
* |                                 | yyyy    | 0044, 0001, 1900, 2017            | 5     |
* |                                 | yyyyy   | ...                               | 3,5   |
* | Local week-numbering year       | Y       | 44, 1, 1900, 2017                 | 5     |
* |                                 | Yo      | 44th, 1st, 1900th, 2017th         | 5,7   |
* |                                 | YY      | 44, 01, 00, 17                    | 5,8   |
* |                                 | YYY     | 044, 001, 1900, 2017              | 5     |
* |                                 | YYYY    | 0044, 0001, 1900, 2017            | 5,8   |
* |                                 | YYYYY   | ...                               | 3,5   |
* | ISO week-numbering year         | R       | -43, 0, 1, 1900, 2017             | 5,7   |
* |                                 | RR      | -43, 00, 01, 1900, 2017           | 5,7   |
* |                                 | RRR     | -043, 000, 001, 1900, 2017        | 5,7   |
* |                                 | RRRR    | -0043, 0000, 0001, 1900, 2017     | 5,7   |
* |                                 | RRRRR   | ...                               | 3,5,7 |
* | Extended year                   | u       | -43, 0, 1, 1900, 2017             | 5     |
* |                                 | uu      | -43, 01, 1900, 2017               | 5     |
* |                                 | uuu     | -043, 001, 1900, 2017             | 5     |
* |                                 | uuuu    | -0043, 0001, 1900, 2017           | 5     |
* |                                 | uuuuu   | ...                               | 3,5   |
* | Quarter (formatting)            | Q       | 1, 2, 3, 4                        |       |
* |                                 | Qo      | 1st, 2nd, 3rd, 4th                | 7     |
* |                                 | QQ      | 01, 02, 03, 04                    |       |
* |                                 | QQQ     | Q1, Q2, Q3, Q4                    |       |
* |                                 | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |
* |                                 | QQQQQ   | 1, 2, 3, 4                        | 4     |
* | Quarter (stand-alone)           | q       | 1, 2, 3, 4                        |       |
* |                                 | qo      | 1st, 2nd, 3rd, 4th                | 7     |
* |                                 | qq      | 01, 02, 03, 04                    |       |
* |                                 | qqq     | Q1, Q2, Q3, Q4                    |       |
* |                                 | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |
* |                                 | qqqqq   | 1, 2, 3, 4                        | 4     |
* | Month (formatting)              | M       | 1, 2, ..., 12                     |       |
* |                                 | Mo      | 1st, 2nd, ..., 12th               | 7     |
* |                                 | MM      | 01, 02, ..., 12                   |       |
* |                                 | MMM     | Jan, Feb, ..., Dec                |       |
* |                                 | MMMM    | January, February, ..., December  | 2     |
* |                                 | MMMMM   | J, F, ..., D                      |       |
* | Month (stand-alone)             | L       | 1, 2, ..., 12                     |       |
* |                                 | Lo      | 1st, 2nd, ..., 12th               | 7     |
* |                                 | LL      | 01, 02, ..., 12                   |       |
* |                                 | LLL     | Jan, Feb, ..., Dec                |       |
* |                                 | LLLL    | January, February, ..., December  | 2     |
* |                                 | LLLLL   | J, F, ..., D                      |       |
* | Local week of year              | w       | 1, 2, ..., 53                     |       |
* |                                 | wo      | 1st, 2nd, ..., 53th               | 7     |
* |                                 | ww      | 01, 02, ..., 53                   |       |
* | ISO week of year                | I       | 1, 2, ..., 53                     | 7     |
* |                                 | Io      | 1st, 2nd, ..., 53th               | 7     |
* |                                 | II      | 01, 02, ..., 53                   | 7     |
* | Day of month                    | d       | 1, 2, ..., 31                     |       |
* |                                 | do      | 1st, 2nd, ..., 31st               | 7     |
* |                                 | dd      | 01, 02, ..., 31                   |       |
* | Day of year                     | D       | 1, 2, ..., 365, 366               | 9     |
* |                                 | Do      | 1st, 2nd, ..., 365th, 366th       | 7     |
* |                                 | DD      | 01, 02, ..., 365, 366             | 9     |
* |                                 | DDD     | 001, 002, ..., 365, 366           |       |
* |                                 | DDDD    | ...                               | 3     |
* | Day of week (formatting)        | E..EEE  | Mon, Tue, Wed, ..., Sun           |       |
* |                                 | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |
* |                                 | EEEEE   | M, T, W, T, F, S, S               |       |
* |                                 | EEEEEE  | Mo, Tu, We, Th, Fr, Sa, Su        |       |
* | ISO day of week (formatting)    | i       | 1, 2, 3, ..., 7                   | 7     |
* |                                 | io      | 1st, 2nd, ..., 7th                | 7     |
* |                                 | ii      | 01, 02, ..., 07                   | 7     |
* |                                 | iii     | Mon, Tue, Wed, ..., Sun           | 7     |
* |                                 | iiii    | Monday, Tuesday, ..., Sunday      | 2,7   |
* |                                 | iiiii   | M, T, W, T, F, S, S               | 7     |
* |                                 | iiiiii  | Mo, Tu, We, Th, Fr, Sa, Su        | 7     |
* | Local day of week (formatting)  | e       | 2, 3, 4, ..., 1                   |       |
* |                                 | eo      | 2nd, 3rd, ..., 1st                | 7     |
* |                                 | ee      | 02, 03, ..., 01                   |       |
* |                                 | eee     | Mon, Tue, Wed, ..., Sun           |       |
* |                                 | eeee    | Monday, Tuesday, ..., Sunday      | 2     |
* |                                 | eeeee   | M, T, W, T, F, S, S               |       |
* |                                 | eeeeee  | Mo, Tu, We, Th, Fr, Sa, Su        |       |
* | Local day of week (stand-alone) | c       | 2, 3, 4, ..., 1                   |       |
* |                                 | co      | 2nd, 3rd, ..., 1st                | 7     |
* |                                 | cc      | 02, 03, ..., 01                   |       |
* |                                 | ccc     | Mon, Tue, Wed, ..., Sun           |       |
* |                                 | cccc    | Monday, Tuesday, ..., Sunday      | 2     |
* |                                 | ccccc   | M, T, W, T, F, S, S               |       |
* |                                 | cccccc  | Mo, Tu, We, Th, Fr, Sa, Su        |       |
* | AM, PM                          | a..aa   | AM, PM                            |       |
* |                                 | aaa     | am, pm                            |       |
* |                                 | aaaa    | a.m., p.m.                        | 2     |
* |                                 | aaaaa   | a, p                              |       |
* | AM, PM, noon, midnight          | b..bb   | AM, PM, noon, midnight            |       |
* |                                 | bbb     | am, pm, noon, midnight            |       |
* |                                 | bbbb    | a.m., p.m., noon, midnight        | 2     |
* |                                 | bbbbb   | a, p, n, mi                       |       |
* | Flexible day period             | B..BBB  | at night, in the morning, ...     |       |
* |                                 | BBBB    | at night, in the morning, ...     | 2     |
* |                                 | BBBBB   | at night, in the morning, ...     |       |
* | Hour [1-12]                     | h       | 1, 2, ..., 11, 12                 |       |
* |                                 | ho      | 1st, 2nd, ..., 11th, 12th         | 7     |
* |                                 | hh      | 01, 02, ..., 11, 12               |       |
* | Hour [0-23]                     | H       | 0, 1, 2, ..., 23                  |       |
* |                                 | Ho      | 0th, 1st, 2nd, ..., 23rd          | 7     |
* |                                 | HH      | 00, 01, 02, ..., 23               |       |
* | Hour [0-11]                     | K       | 1, 2, ..., 11, 0                  |       |
* |                                 | Ko      | 1st, 2nd, ..., 11th, 0th          | 7     |
* |                                 | KK      | 01, 02, ..., 11, 00               |       |
* | Hour [1-24]                     | k       | 24, 1, 2, ..., 23                 |       |
* |                                 | ko      | 24th, 1st, 2nd, ..., 23rd         | 7     |
* |                                 | kk      | 24, 01, 02, ..., 23               |       |
* | Minute                          | m       | 0, 1, ..., 59                     |       |
* |                                 | mo      | 0th, 1st, ..., 59th               | 7     |
* |                                 | mm      | 00, 01, ..., 59                   |       |
* | Second                          | s       | 0, 1, ..., 59                     |       |
* |                                 | so      | 0th, 1st, ..., 59th               | 7     |
* |                                 | ss      | 00, 01, ..., 59                   |       |
* | Fraction of second              | S       | 0, 1, ..., 9                      |       |
* |                                 | SS      | 00, 01, ..., 99                   |       |
* |                                 | SSS     | 000, 001, ..., 999                |       |
* |                                 | SSSS    | ...                               | 3     |
* | Timezone (ISO-8601 w/ Z)        | X       | -08, +0530, Z                     |       |
* |                                 | XX      | -0800, +0530, Z                   |       |
* |                                 | XXX     | -08:00, +05:30, Z                 |       |
* |                                 | XXXX    | -0800, +0530, Z, +123456          | 2     |
* |                                 | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |
* | Timezone (ISO-8601 w/o Z)       | x       | -08, +0530, +00                   |       |
* |                                 | xx      | -0800, +0530, +0000               |       |
* |                                 | xxx     | -08:00, +05:30, +00:00            | 2     |
* |                                 | xxxx    | -0800, +0530, +0000, +123456      |       |
* |                                 | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |
* | Timezone (GMT)                  | O...OOO | GMT-8, GMT+5:30, GMT+0            |       |
* |                                 | OOOO    | GMT-08:00, GMT+05:30, GMT+00:00   | 2     |
* | Timezone (specific non-locat.)  | z...zzz | GMT-8, GMT+5:30, GMT+0            | 6     |
* |                                 | zzzz    | GMT-08:00, GMT+05:30, GMT+00:00   | 2,6   |
* | Seconds timestamp               | t       | 512969520                         | 7     |
* |                                 | tt      | ...                               | 3,7   |
* | Milliseconds timestamp          | T       | 512969520900                      | 7     |
* |                                 | TT      | ...                               | 3,7   |
* | Long localized date             | P       | 04/29/1453                        | 7     |
* |                                 | PP      | Apr 29, 1453                      | 7     |
* |                                 | PPP     | April 29th, 1453                  | 7     |
* |                                 | PPPP    | Friday, April 29th, 1453          | 2,7   |
* | Long localized time             | p       | 12:00 AM                          | 7     |
* |                                 | pp      | 12:00:00 AM                       | 7     |
* |                                 | ppp     | 12:00:00 AM GMT+2                 | 7     |
* |                                 | pppp    | 12:00:00 AM GMT+02:00             | 2,7   |
* | Combination of date and time    | Pp      | 04/29/1453, 12:00 AM              | 7     |
* |                                 | PPpp    | Apr 29, 1453, 12:00:00 AM         | 7     |
* |                                 | PPPppp  | April 29th, 1453 at ...           | 7     |
* |                                 | PPPPpppp| Friday, April 29th, 1453 at ...   | 2,7   |
* Notes:
* 1. "Formatting" units (e.g. formatting quarter) in the default en-US locale
*    are the same as "stand-alone" units, but are different in some languages.
*    "Formatting" units are declined according to the rules of the language
*    in the context of a date. "Stand-alone" units are always nominative singular:
*
*    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`
*
*    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`
*
* 2. Any sequence of the identical letters is a pattern, unless it is escaped by
*    the single quote characters (see below).
*    If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`)
*    the output will be the same as default pattern for this unit, usually
*    the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units
*    are marked with "2" in the last column of the table.
*
*    `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'`
*
*    `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'`
*
*    `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'`
*
*    `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'`
*
*    `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'`
*
* 3. Some patterns could be unlimited length (such as `yyyyyyyy`).
*    The output will be padded with zeros to match the length of the pattern.
*
*    `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'`
*
* 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.
*    These tokens represent the shortest form of the quarter.
*
* 5. The main difference between `y` and `u` patterns are B.C. years:
*
*    | Year | `y` | `u` |
*    |------|-----|-----|
*    | AC 1 |   1 |   1 |
*    | BC 1 |   1 |   0 |
*    | BC 2 |   2 |  -1 |
*
*    Also `yy` always returns the last two digits of a year,
*    while `uu` pads single digit years to 2 characters and returns other years unchanged:
*
*    | Year | `yy` | `uu` |
*    |------|------|------|
*    | 1    |   01 |   01 |
*    | 14   |   14 |   14 |
*    | 376  |   76 |  376 |
*    | 1453 |   53 | 1453 |
*
*    The same difference is true for local and ISO week-numbering years (`Y` and `R`),
*    except local week-numbering years are dependent on `options.weekStartsOn`
*    and `options.firstWeekContainsDate` (compare [getISOWeekYear](https://date-fns.org/docs/getISOWeekYear)
*    and [getWeekYear](https://date-fns.org/docs/getWeekYear)).
*
* 6. Specific non-location timezones are currently unavailable in `date-fns`,
*    so right now these tokens fall back to GMT timezones.
*
* 7. These patterns are not in the Unicode Technical Standard #35:
*    - `i`: ISO day of week
*    - `I`: ISO week of year
*    - `R`: ISO week-numbering year
*    - `t`: seconds timestamp
*    - `T`: milliseconds timestamp
*    - `o`: ordinal number modifier
*    - `P`: long localized date
*    - `p`: long localized time
*
* 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.
*    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
*
* 9. `D` and `DD` tokens represent days of the year but they are often confused with days of the month.
*    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
*
* @param date - The original date
* @param format - The string of tokens
* @param options - An object with options
*
* @returns The formatted date string
*
* @throws `date` must not be Invalid Date
* @throws `options.locale` must contain `localize` property
* @throws `options.locale` must contain `formatLong` property
* @throws use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
* @throws use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
* @throws use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
* @throws use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
* @throws format string contains an unescaped latin alphabet character
*
* @example
* // Represent 11 February 2014 in middle-endian format:
* const result = format(new Date(2014, 1, 11), 'MM/dd/yyyy')
* //=> '02/11/2014'
*
* @example
* // Represent 2 July 2014 in Esperanto:
* import { eoLocale } from 'date-fns/locale/eo'
* const result = format(new Date(2014, 6, 2), "do 'de' MMMM yyyy", {
*   locale: eoLocale
* })
* //=> '2-a de julio 2014'
*
* @example
* // Escape string by single quote characters:
* const result = format(new Date(2014, 6, 2, 15), "h 'o''clock'")
* //=> "3 o'clock"
*/
function format(date, formatStr, options) {
	const defaultOptions = getDefaultOptions();
	const locale = options?.locale ?? defaultOptions.locale ?? enUS$1;
	const firstWeekContainsDate = options?.firstWeekContainsDate ?? options?.locale?.options?.firstWeekContainsDate ?? defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
	const weekStartsOn = options?.weekStartsOn ?? options?.locale?.options?.weekStartsOn ?? defaultOptions.weekStartsOn ?? defaultOptions.locale?.options?.weekStartsOn ?? 0;
	const originalDate = toDate(date, options?.in);
	if (!isValid(originalDate)) throw new RangeError("Invalid time value");
	let parts = formatStr.match(longFormattingTokensRegExp).map((substring) => {
		const firstCharacter = substring[0];
		if (firstCharacter === "p" || firstCharacter === "P") {
			const longFormatter = longFormatters[firstCharacter];
			return longFormatter(substring, locale.formatLong);
		}
		return substring;
	}).join("").match(formattingTokensRegExp).map((substring) => {
		if (substring === "''") return {
			isToken: false,
			value: "'"
		};
		const firstCharacter = substring[0];
		if (firstCharacter === "'") return {
			isToken: false,
			value: cleanEscapedString(substring)
		};
		if (formatters[firstCharacter]) return {
			isToken: true,
			value: substring
		};
		if (firstCharacter.match(unescapedLatinCharacterRegExp)) throw new RangeError("Format string contains an unescaped latin alphabet character `" + firstCharacter + "`");
		return {
			isToken: false,
			value: substring
		};
	});
	if (locale.localize.preprocessor) parts = locale.localize.preprocessor(originalDate, parts);
	const formatterOptions = {
		firstWeekContainsDate,
		weekStartsOn,
		locale
	};
	return parts.map((part) => {
		if (!part.isToken) return part.value;
		const token = part.value;
		if (!options?.useAdditionalWeekYearTokens && isProtectedWeekYearToken(token) || !options?.useAdditionalDayOfYearTokens && isProtectedDayOfYearToken(token)) warnOrThrowProtectedError(token, formatStr, String(date));
		const formatter = formatters[token[0]];
		return formatter(originalDate, token, locale.localize, formatterOptions);
	}).join("");
}
function cleanEscapedString(input) {
	const matched = input.match(escapedStringRegExp);
	if (!matched) return input;
	return matched[1].replace(doubleQuoteRegExp, "'");
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getDaysInMonth.js
/**
* The {@link getDaysInMonth} function options.
*/
/**
* @name getDaysInMonth
* @category Month Helpers
* @summary Get the number of days in a month of the given date.
*
* @description
* Get the number of days in a month of the given date, considering the context if provided.
*
* @param date - The given date
* @param options - An object with options
*
* @returns The number of days in a month
*
* @example
* // How many days are in February 2000?
* const result = getDaysInMonth(new Date(2000, 1))
* //=> 29
*/
function getDaysInMonth(date, options) {
	const _date = toDate(date, options?.in);
	const year = _date.getFullYear();
	const monthIndex = _date.getMonth();
	const lastDayOfMonth = constructFrom(_date, 0);
	lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);
	lastDayOfMonth.setHours(0, 0, 0, 0);
	return lastDayOfMonth.getDate();
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getMonth.js
/**
* The {@link getMonth} function options.
*/
/**
* @name getMonth
* @category Month Helpers
* @summary Get the month of the given date.
*
* @description
* Get the month of the given date.
*
* @param date - The given date
* @param options - An object with options
*
* @returns The month index (0-11)
*
* @example
* // Which month is 29 February 2012?
* const result = getMonth(new Date(2012, 1, 29))
* //=> 1
*/
function getMonth(date, options) {
	return toDate(date, options?.in).getMonth();
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/getYear.js
/**
* The {@link getYear} function options.
*/
/**
* @name getYear
* @category Year Helpers
* @summary Get the year of the given date.
*
* @description
* Get the year of the given date.
*
* @param date - The given date
* @param options - An object with options
*
* @returns The year
*
* @example
* // Which year is 2 July 2014?
* const result = getYear(new Date(2014, 6, 2))
* //=> 2014
*/
function getYear(date, options) {
	return toDate(date, options?.in).getFullYear();
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/isAfter.js
/**
* @name isAfter
* @category Common Helpers
* @summary Is the first date after the second one?
*
* @description
* Is the first date after the second one?
*
* @param date - The date that should be after the other one to return true
* @param dateToCompare - The date to compare with
*
* @returns The first date is after the second date
*
* @example
* // Is 10 July 1989 after 11 February 1987?
* const result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11))
* //=> true
*/
function isAfter(date, dateToCompare) {
	return +toDate(date) > +toDate(dateToCompare);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/isBefore.js
/**
* @name isBefore
* @category Common Helpers
* @summary Is the first date before the second one?
*
* @description
* Is the first date before the second one?
*
* @param date - The date that should be before the other one to return true
* @param dateToCompare - The date to compare with
*
* @returns The first date is before the second date
*
* @example
* // Is 10 July 1989 before 11 February 1987?
* const result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11))
* //=> false
*/
function isBefore(date, dateToCompare) {
	return +toDate(date) < +toDate(dateToCompare);
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/isSameMonth.js
/**
* The {@link isSameMonth} function options.
*/
/**
* @name isSameMonth
* @category Month Helpers
* @summary Are the given dates in the same month (and year)?
*
* @description
* Are the given dates in the same month (and year)?
*
* @param laterDate - The first date to check
* @param earlierDate - The second date to check
* @param options - An object with options
*
* @returns The dates are in the same month (and year)
*
* @example
* // Are 2 September 2014 and 25 September 2014 in the same month?
* const result = isSameMonth(new Date(2014, 8, 2), new Date(2014, 8, 25))
* //=> true
*
* @example
* // Are 2 September 2014 and 25 September 2015 in the same month?
* const result = isSameMonth(new Date(2014, 8, 2), new Date(2015, 8, 25))
* //=> false
*/
function isSameMonth(laterDate, earlierDate, options) {
	const [laterDate_, earlierDate_] = normalizeDates(options?.in, laterDate, earlierDate);
	return laterDate_.getFullYear() === earlierDate_.getFullYear() && laterDate_.getMonth() === earlierDate_.getMonth();
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/isSameYear.js
/**
* The {@link isSameYear} function options.
*/
/**
* @name isSameYear
* @category Year Helpers
* @summary Are the given dates in the same year?
*
* @description
* Are the given dates in the same year?
*
* @param laterDate - The first date to check
* @param earlierDate - The second date to check
* @param options - An object with options
*
* @returns The dates are in the same year
*
* @example
* // Are 2 September 2014 and 25 September 2014 in the same year?
* const result = isSameYear(new Date(2014, 8, 2), new Date(2014, 8, 25))
* //=> true
*/
function isSameYear(laterDate, earlierDate, options) {
	const [laterDate_, earlierDate_] = normalizeDates(options?.in, laterDate, earlierDate);
	return laterDate_.getFullYear() === earlierDate_.getFullYear();
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/setMonth.js
/**
* The {@link setMonth} function options.
*/
/**
* @name setMonth
* @category Month Helpers
* @summary Set the month to the given date.
*
* @description
* Set the month to the given date.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The date to be changed
* @param month - The month index to set (0-11)
* @param options - The options
*
* @returns The new date with the month set
*
* @example
* // Set February to 1 September 2014:
* const result = setMonth(new Date(2014, 8, 1), 1)
* //=> Sat Feb 01 2014 00:00:00
*/
function setMonth(date, month, options) {
	const _date = toDate(date, options?.in);
	const year = _date.getFullYear();
	const day = _date.getDate();
	const midMonth = constructFrom(options?.in || date, 0);
	midMonth.setFullYear(year, month, 15);
	midMonth.setHours(0, 0, 0, 0);
	const daysInMonth = getDaysInMonth(midMonth);
	_date.setMonth(month, Math.min(day, daysInMonth));
	return _date;
}
//#endregion
//#region ../../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/setYear.js
/**
* The {@link setYear} function options.
*/
/**
* @name setYear
* @category Year Helpers
* @summary Set the year to the given date.
*
* @description
* Set the year to the given date.
*
* @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
* @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
*
* @param date - The date to be changed
* @param year - The year of the new date
* @param options - An object with options.
*
* @returns The new date with the year set
*
* @example
* // Set year 2013 to 1 September 2014:
* const result = setYear(new Date(2014, 8, 1), 2013)
* //=> Sun Sep 01 2013 00:00:00
*/
function setYear(date, year, options) {
	const date_ = toDate(date, options?.in);
	if (isNaN(+date_)) return constructFrom(options?.in || date, NaN);
	date_.setFullYear(year);
	return date_;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getBroadcastWeeksInMonth.js
var FIVE_WEEKS = 5;
var FOUR_WEEKS = 4;
/**
* Returns the number of weeks to display in the broadcast calendar for a given
* month.
*
* The broadcast calendar may have either 4 or 5 weeks in a month, depending on
* the start and end dates of the broadcast weeks.
*
* @since 9.4.0
* @param month The month for which to calculate the number of weeks.
* @param dateLib The date library to use for date manipulation.
* @returns The number of weeks in the broadcast calendar (4 or 5).
*/
function getBroadcastWeeksInMonth(month, dateLib) {
	const firstDayOfMonth = dateLib.startOfMonth(month);
	const firstDayOfWeek = firstDayOfMonth.getDay() > 0 ? firstDayOfMonth.getDay() : 7;
	const broadcastStartDate = dateLib.addDays(month, -firstDayOfWeek + 1);
	const lastDateOfLastWeek = dateLib.addDays(broadcastStartDate, 34);
	return dateLib.getMonth(month) === dateLib.getMonth(lastDateOfLastWeek) ? FIVE_WEEKS : FOUR_WEEKS;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/startOfBroadcastWeek.js
/**
* Returns the start date of the week in the broadcast calendar.
*
* The broadcast week starts on Monday. If the first day of the month is not a
* Monday, this function calculates the previous Monday as the start of the
* broadcast week.
*
* @since 9.4.0
* @param date The date for which to calculate the start of the broadcast week.
* @param dateLib The date library to use for date manipulation.
* @returns The start date of the broadcast week.
*/
function startOfBroadcastWeek(date, dateLib) {
	const firstOfMonth = dateLib.startOfMonth(date);
	const dayOfWeek = firstOfMonth.getDay();
	if (dayOfWeek === 1) return firstOfMonth;
	else if (dayOfWeek === 0) return dateLib.addDays(firstOfMonth, -6);
	else return dateLib.addDays(firstOfMonth, -1 * (dayOfWeek - 1));
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/endOfBroadcastWeek.js
/**
* Returns the end date of the week in the broadcast calendar.
*
* The broadcast week ends on the last day of the last broadcast week for the
* given date.
*
* @since 9.4.0
* @param date The date for which to calculate the end of the broadcast week.
* @param dateLib The date library to use for date manipulation.
* @returns The end date of the broadcast week.
*/
function endOfBroadcastWeek(date, dateLib) {
	const startDate = startOfBroadcastWeek(date, dateLib);
	const numberOfWeeks = getBroadcastWeeksInMonth(date, dateLib);
	return dateLib.addDays(startDate, numberOfWeeks * 7 - 1);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/locale/en-US.js
/** English (United States) locale extended with DayPicker-specific translations. */
var enUS = {
	...enUS$1,
	labels: {
		labelDayButton: (date, modifiers, options, dateLib) => {
			let formatDate;
			if (dateLib && typeof dateLib.format === "function") formatDate = dateLib.format.bind(dateLib);
			else formatDate = (d, pattern) => format(d, pattern, {
				locale: enUS$1,
				...options
			});
			let label = formatDate(date, "PPPP");
			if (modifiers.today) label = `Today, ${label}`;
			if (modifiers.selected) label = `${label}, selected`;
			return label;
		},
		labelMonthDropdown: "Choose the Month",
		labelNext: "Go to the Next Month",
		labelPrevious: "Go to the Previous Month",
		labelWeekNumber: (weekNumber) => `Week ${weekNumber}`,
		labelYearDropdown: "Choose the Year",
		labelGrid: (date, options, dateLib) => {
			let formatDate;
			if (dateLib && typeof dateLib.format === "function") formatDate = dateLib.format.bind(dateLib);
			else formatDate = (d, pattern) => format(d, pattern, {
				locale: enUS$1,
				...options
			});
			return formatDate(date, "LLLL yyyy");
		},
		labelGridcell: (date, modifiers, options, dateLib) => {
			let formatDate;
			if (dateLib && typeof dateLib.format === "function") formatDate = dateLib.format.bind(dateLib);
			else formatDate = (d, pattern) => format(d, pattern, {
				locale: enUS$1,
				...options
			});
			let label = formatDate(date, "PPPP");
			if (modifiers?.today) label = `Today, ${label}`;
			return label;
		},
		labelNav: "Navigation bar",
		labelWeekNumberHeader: "Week Number",
		labelWeekday: (date, options, dateLib) => {
			let formatDate;
			if (dateLib && typeof dateLib.format === "function") formatDate = dateLib.format.bind(dateLib);
			else formatDate = (d, pattern) => format(d, pattern, {
				locale: enUS$1,
				...options
			});
			return formatDate(date, "cccc");
		}
	}
};
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/classes/DateLib.js
/**
* A wrapper class around [date-fns](http://date-fns.org) that provides utility
* methods for date manipulation and formatting.
*
* @since 9.2.0
* @example
*   const dateLib = new DateLib({ locale: es });
*   const newDate = dateLib.addDays(new Date(), 5);
*/
var DateLib = class DateLib {
	/**
	* Creates an instance of `DateLib`.
	*
	* @param options Configuration options for the date library.
	* @param overrides Custom overrides for the date library functions.
	*/
	constructor(options, overrides) {
		/**
		* Creates a new `Date` object representing today's date.
		*
		* @since 9.5.0
		* @returns A `Date` object for today's date.
		*/
		this.today = () => {
			if (this.overrides?.today) return this.overrides.today();
			if (this.options.timeZone) return TZDate.tz(this.options.timeZone);
			return new (this.options.Date ?? Date)();
		};
		/**
		* Creates a new `Date` object with the specified year, month, and day.
		*
		* @since 9.5.0
		* @param year The year.
		* @param monthIndex The month (0-11).
		* @param date The day of the month.
		* @returns A new `Date` object.
		*/
		this.newDate = (year, monthIndex, date) => {
			if (this.overrides?.newDate) return this.overrides.newDate(year, monthIndex, date);
			if (this.options.timeZone) return new TZDate(year, monthIndex, date, this.options.timeZone);
			return new Date(year, monthIndex, date);
		};
		/**
		* Adds the specified number of days to the given date.
		*
		* @param date The date to add days to.
		* @param amount The number of days to add.
		* @returns The new date with the days added.
		*/
		this.addDays = (date, amount) => {
			return this.overrides?.addDays ? this.overrides.addDays(date, amount) : addDays(date, amount);
		};
		/**
		* Adds the specified number of months to the given date.
		*
		* @param date The date to add months to.
		* @param amount The number of months to add.
		* @returns The new date with the months added.
		*/
		this.addMonths = (date, amount) => {
			return this.overrides?.addMonths ? this.overrides.addMonths(date, amount) : addMonths(date, amount);
		};
		/**
		* Adds the specified number of weeks to the given date.
		*
		* @param date The date to add weeks to.
		* @param amount The number of weeks to add.
		* @returns The new date with the weeks added.
		*/
		this.addWeeks = (date, amount) => {
			return this.overrides?.addWeeks ? this.overrides.addWeeks(date, amount) : addWeeks(date, amount);
		};
		/**
		* Adds the specified number of years to the given date.
		*
		* @param date The date to add years to.
		* @param amount The number of years to add.
		* @returns The new date with the years added.
		*/
		this.addYears = (date, amount) => {
			return this.overrides?.addYears ? this.overrides.addYears(date, amount) : addYears(date, amount);
		};
		/**
		* Returns the number of calendar days between the given dates.
		*
		* @param dateLeft The later date.
		* @param dateRight The earlier date.
		* @returns The number of calendar days between the dates.
		*/
		this.differenceInCalendarDays = (dateLeft, dateRight) => {
			return this.overrides?.differenceInCalendarDays ? this.overrides.differenceInCalendarDays(dateLeft, dateRight) : differenceInCalendarDays(dateLeft, dateRight);
		};
		/**
		* Returns the number of calendar months between the given dates.
		*
		* @param dateLeft The later date.
		* @param dateRight The earlier date.
		* @returns The number of calendar months between the dates.
		*/
		this.differenceInCalendarMonths = (dateLeft, dateRight) => {
			return this.overrides?.differenceInCalendarMonths ? this.overrides.differenceInCalendarMonths(dateLeft, dateRight) : differenceInCalendarMonths(dateLeft, dateRight);
		};
		/**
		* Returns the months between the given dates.
		*
		* @param interval The interval to get the months for.
		*/
		this.eachMonthOfInterval = (interval) => {
			return this.overrides?.eachMonthOfInterval ? this.overrides.eachMonthOfInterval(interval) : eachMonthOfInterval(interval);
		};
		/**
		* Returns the years between the given dates.
		*
		* @since 9.11.1
		* @param interval The interval to get the years for.
		* @returns The array of years in the interval.
		*/
		this.eachYearOfInterval = (interval) => {
			const years = this.overrides?.eachYearOfInterval ? this.overrides.eachYearOfInterval(interval) : eachYearOfInterval(interval);
			const uniqueYears = new Set(years.map((d) => this.getYear(d)));
			if (uniqueYears.size === years.length) return years;
			const yearsArray = [];
			uniqueYears.forEach((y) => {
				yearsArray.push(new Date(y, 0, 1));
			});
			return yearsArray;
		};
		/**
		* Returns the end of the broadcast week for the given date.
		*
		* @param date The original date.
		* @returns The end of the broadcast week.
		*/
		this.endOfBroadcastWeek = (date) => {
			return this.overrides?.endOfBroadcastWeek ? this.overrides.endOfBroadcastWeek(date) : endOfBroadcastWeek(date, this);
		};
		/**
		* Returns the end of the ISO week for the given date.
		*
		* @param date The original date.
		* @returns The end of the ISO week.
		*/
		this.endOfISOWeek = (date) => {
			return this.overrides?.endOfISOWeek ? this.overrides.endOfISOWeek(date) : endOfISOWeek(date);
		};
		/**
		* Returns the end of the month for the given date.
		*
		* @param date The original date.
		* @returns The end of the month.
		*/
		this.endOfMonth = (date) => {
			return this.overrides?.endOfMonth ? this.overrides.endOfMonth(date) : endOfMonth(date);
		};
		/**
		* Returns the end of the week for the given date.
		*
		* @param date The original date.
		* @returns The end of the week.
		*/
		this.endOfWeek = (date, options) => {
			return this.overrides?.endOfWeek ? this.overrides.endOfWeek(date, options) : endOfWeek(date, this.options);
		};
		/**
		* Returns the end of the year for the given date.
		*
		* @param date The original date.
		* @returns The end of the year.
		*/
		this.endOfYear = (date) => {
			return this.overrides?.endOfYear ? this.overrides.endOfYear(date) : endOfYear(date);
		};
		/**
		* Formats the given date using the specified format string.
		*
		* @param date The date to format.
		* @param formatStr The format string.
		* @returns The formatted date string.
		*/
		this.format = (date, formatStr, _options) => {
			const formatted = this.overrides?.format ? this.overrides.format(date, formatStr, this.options) : format(date, formatStr, this.options);
			if (this.options.numerals && this.options.numerals !== "latn") return this.replaceDigits(formatted);
			return formatted;
		};
		/**
		* Returns the ISO week number for the given date.
		*
		* @param date The date to get the ISO week number for.
		* @returns The ISO week number.
		*/
		this.getISOWeek = (date) => {
			return this.overrides?.getISOWeek ? this.overrides.getISOWeek(date) : getISOWeek(date);
		};
		/**
		* Returns the month of the given date.
		*
		* @param date The date to get the month for.
		* @returns The month.
		*/
		this.getMonth = (date, _options) => {
			return this.overrides?.getMonth ? this.overrides.getMonth(date, this.options) : getMonth(date, this.options);
		};
		/**
		* Returns the year of the given date.
		*
		* @param date The date to get the year for.
		* @returns The year.
		*/
		this.getYear = (date, _options) => {
			return this.overrides?.getYear ? this.overrides.getYear(date, this.options) : getYear(date, this.options);
		};
		/**
		* Returns the local week number for the given date.
		*
		* @param date The date to get the week number for.
		* @returns The week number.
		*/
		this.getWeek = (date, _options) => {
			return this.overrides?.getWeek ? this.overrides.getWeek(date, this.options) : getWeek(date, this.options);
		};
		/**
		* Checks if the first date is after the second date.
		*
		* @param date The date to compare.
		* @param dateToCompare The date to compare with.
		* @returns True if the first date is after the second date.
		*/
		this.isAfter = (date, dateToCompare) => {
			return this.overrides?.isAfter ? this.overrides.isAfter(date, dateToCompare) : isAfter(date, dateToCompare);
		};
		/**
		* Checks if the first date is before the second date.
		*
		* @param date The date to compare.
		* @param dateToCompare The date to compare with.
		* @returns True if the first date is before the second date.
		*/
		this.isBefore = (date, dateToCompare) => {
			return this.overrides?.isBefore ? this.overrides.isBefore(date, dateToCompare) : isBefore(date, dateToCompare);
		};
		/**
		* Checks if the given value is a Date object.
		*
		* @param value The value to check.
		* @returns True if the value is a Date object.
		*/
		this.isDate = (value) => {
			return this.overrides?.isDate ? this.overrides.isDate(value) : isDate(value);
		};
		/**
		* Checks if the given dates are on the same day.
		*
		* @param dateLeft The first date to compare.
		* @param dateRight The second date to compare.
		* @returns True if the dates are on the same day.
		*/
		this.isSameDay = (dateLeft, dateRight) => {
			return this.overrides?.isSameDay ? this.overrides.isSameDay(dateLeft, dateRight) : isSameDay(dateLeft, dateRight);
		};
		/**
		* Checks if the given dates are in the same month.
		*
		* @param dateLeft The first date to compare.
		* @param dateRight The second date to compare.
		* @returns True if the dates are in the same month.
		*/
		this.isSameMonth = (dateLeft, dateRight) => {
			return this.overrides?.isSameMonth ? this.overrides.isSameMonth(dateLeft, dateRight) : isSameMonth(dateLeft, dateRight);
		};
		/**
		* Checks if the given dates are in the same year.
		*
		* @param dateLeft The first date to compare.
		* @param dateRight The second date to compare.
		* @returns True if the dates are in the same year.
		*/
		this.isSameYear = (dateLeft, dateRight) => {
			return this.overrides?.isSameYear ? this.overrides.isSameYear(dateLeft, dateRight) : isSameYear(dateLeft, dateRight);
		};
		/**
		* Returns the latest date in the given array of dates.
		*
		* @param dates The array of dates to compare.
		* @returns The latest date.
		*/
		this.max = (dates) => {
			return this.overrides?.max ? this.overrides.max(dates) : max(dates);
		};
		/**
		* Returns the earliest date in the given array of dates.
		*
		* @param dates The array of dates to compare.
		* @returns The earliest date.
		*/
		this.min = (dates) => {
			return this.overrides?.min ? this.overrides.min(dates) : min(dates);
		};
		/**
		* Sets the month of the given date.
		*
		* @param date The date to set the month on.
		* @param month The month to set (0-11).
		* @returns The new date with the month set.
		*/
		this.setMonth = (date, month) => {
			return this.overrides?.setMonth ? this.overrides.setMonth(date, month) : setMonth(date, month);
		};
		/**
		* Sets the year of the given date.
		*
		* @param date The date to set the year on.
		* @param year The year to set.
		* @returns The new date with the year set.
		*/
		this.setYear = (date, year) => {
			return this.overrides?.setYear ? this.overrides.setYear(date, year) : setYear(date, year);
		};
		/**
		* Returns the start of the broadcast week for the given date.
		*
		* @param date The original date.
		* @returns The start of the broadcast week.
		*/
		this.startOfBroadcastWeek = (date, _dateLib) => {
			return this.overrides?.startOfBroadcastWeek ? this.overrides.startOfBroadcastWeek(date, this) : startOfBroadcastWeek(date, this);
		};
		/**
		* Returns the start of the day for the given date.
		*
		* @param date The original date.
		* @returns The start of the day.
		*/
		this.startOfDay = (date) => {
			return this.overrides?.startOfDay ? this.overrides.startOfDay(date) : startOfDay(date);
		};
		/**
		* Returns the start of the ISO week for the given date.
		*
		* @param date The original date.
		* @returns The start of the ISO week.
		*/
		this.startOfISOWeek = (date) => {
			return this.overrides?.startOfISOWeek ? this.overrides.startOfISOWeek(date) : startOfISOWeek(date);
		};
		/**
		* Returns the start of the month for the given date.
		*
		* @param date The original date.
		* @returns The start of the month.
		*/
		this.startOfMonth = (date) => {
			return this.overrides?.startOfMonth ? this.overrides.startOfMonth(date) : startOfMonth(date);
		};
		/**
		* Returns the start of the week for the given date.
		*
		* @param date The original date.
		* @returns The start of the week.
		*/
		this.startOfWeek = (date, _options) => {
			return this.overrides?.startOfWeek ? this.overrides.startOfWeek(date, this.options) : startOfWeek(date, this.options);
		};
		/**
		* Returns the start of the year for the given date.
		*
		* @param date The original date.
		* @returns The start of the year.
		*/
		this.startOfYear = (date) => {
			return this.overrides?.startOfYear ? this.overrides.startOfYear(date) : startOfYear(date);
		};
		this.options = {
			locale: enUS,
			...options
		};
		this.overrides = overrides;
	}
	/**
	* Generates a mapping of Arabic digits (0-9) to the target numbering system
	* digits.
	*
	* @since 9.5.0
	* @returns A record mapping Arabic digits to the target numerals.
	*/
	getDigitMap() {
		const { numerals = "latn" } = this.options;
		const formatter = new Intl.NumberFormat("en-US", { numberingSystem: numerals });
		const digitMap = {};
		for (let i = 0; i < 10; i++) digitMap[i.toString()] = formatter.format(i);
		return digitMap;
	}
	/**
	* Replaces Arabic digits in a string with the target numbering system digits.
	*
	* @since 9.5.0
	* @param input The string containing Arabic digits.
	* @returns The string with digits replaced.
	*/
	replaceDigits(input) {
		const digitMap = this.getDigitMap();
		return input.replace(/\d/g, (digit) => digitMap[digit] || digit);
	}
	/**
	* Formats a number using the configured numbering system.
	*
	* @since 9.5.0
	* @param value The number to format.
	* @returns The formatted number as a string.
	*/
	formatNumber(value) {
		return this.replaceDigits(value.toString());
	}
	/**
	* Returns the preferred ordering for month and year labels for the current
	* locale.
	*/
	getMonthYearOrder() {
		const code = this.options.locale?.code;
		if (!code) return "month-first";
		return DateLib.yearFirstLocales.has(code) ? "year-first" : "month-first";
	}
	/**
	* Formats the month/year pair respecting locale conventions.
	*
	* @since 9.11.0
	*/
	formatMonthYear(date) {
		const { locale, timeZone, numerals } = this.options;
		const localeCode = locale?.code;
		if (localeCode && DateLib.yearFirstLocales.has(localeCode)) try {
			return new Intl.DateTimeFormat(localeCode, {
				month: "long",
				year: "numeric",
				timeZone,
				numberingSystem: numerals
			}).format(date);
		} catch {}
		const pattern = this.getMonthYearOrder() === "year-first" ? "y LLLL" : "LLLL y";
		return this.format(date, pattern);
	}
};
DateLib.yearFirstLocales = /* @__PURE__ */ new Set([
	"eu",
	"hu",
	"ja",
	"ja-Hira",
	"ja-JP",
	"ko",
	"ko-KR",
	"lt",
	"lt-LT",
	"lv",
	"lv-LV",
	"mn",
	"mn-MN",
	"zh",
	"zh-CN",
	"zh-HK",
	"zh-TW"
]);
/**
* The default date library with English locale.
*
* @since 9.2.0
*/
var defaultDateLib = new DateLib();
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/classes/CalendarDay.js
/**
* Represents a day displayed in the calendar.
*
* In DayPicker, a `CalendarDay` is a wrapper around a `Date` object that
* provides additional information about the day, such as whether it belongs to
* the displayed month.
*/
var CalendarDay = class {
	constructor(date, displayMonth, dateLib = defaultDateLib) {
		this.date = date;
		this.displayMonth = displayMonth;
		this.outside = Boolean(displayMonth && !dateLib.isSameMonth(date, displayMonth));
		this.dateLib = dateLib;
		this.isoDate = dateLib.format(date, "yyyy-MM-dd");
		this.displayMonthId = dateLib.format(displayMonth, "yyyy-MM");
		this.dateMonthId = dateLib.format(date, "yyyy-MM");
	}
	/**
	* Checks if this day is equal to another `CalendarDay`, considering both the
	* date and the displayed month.
	*
	* @param day The `CalendarDay` to compare with.
	* @returns `true` if the days are equal, otherwise `false`.
	*/
	isEqualTo(day) {
		return this.dateLib.isSameDay(day.date, this.date) && this.dateLib.isSameMonth(day.displayMonth, this.displayMonth);
	}
};
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/classes/CalendarMonth.js
/**
* Represents a month in a calendar year.
*
* A `CalendarMonth` contains the weeks within the month and the date of the
* month.
*/
var CalendarMonth = class {
	constructor(month, weeks) {
		this.date = month;
		this.weeks = weeks;
	}
};
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/classes/CalendarWeek.js
/**
* Represents a week in a calendar month.
*
* A `CalendarWeek` contains the days within the week and the week number.
*/
var CalendarWeek = class {
	constructor(weekNumber, days) {
		this.days = days;
		this.weekNumber = weekNumber;
	}
};
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/CaptionLabel.js
/**
* Render the label in the month caption.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function CaptionLabel(props) {
	return import_react.createElement("span", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Chevron.js
/**
* Render the chevron icon used in the navigation buttons and dropdowns.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Chevron(props) {
	const { size = 24, orientation = "left", className, style } = props;
	return import_react.createElement("svg", {
		className,
		style,
		width: size,
		height: size,
		viewBox: "0 0 24 24"
	}, orientation === "up" && import_react.createElement("polygon", { points: "6.77 17 12.5 11.43 18.24 17 20 15.28 12.5 8 5 15.28" }), orientation === "down" && import_react.createElement("polygon", { points: "6.77 8 12.5 13.57 18.24 8 20 9.72 12.5 17 5 9.72" }), orientation === "left" && import_react.createElement("polygon", { points: "16 18.112 9.81111111 12 16 5.87733333 14.0888889 4 6 12 14.0888889 20" }), orientation === "right" && import_react.createElement("polygon", { points: "8 18.112 14.18888889 12 8 5.87733333 9.91111111 4 18 12 9.91111111 20" }));
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Day.js
/**
* Render a grid cell for a specific day in the calendar.
*
* Handles interaction and focus for the day. If you only need to change the
* content of the day cell, consider swapping the `DayButton` component
* instead.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Day(props) {
	const { day, modifiers, ...tdProps } = props;
	return import_react.createElement("td", { ...tdProps });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/DayButton.js
/**
* Render a button for a specific day in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function DayButton(props) {
	const { day, modifiers, ...buttonProps } = props;
	const ref = import_react.useRef(null);
	import_react.useEffect(() => {
		if (modifiers.focused) ref.current?.focus();
	}, [modifiers.focused]);
	return import_react.createElement("button", {
		ref,
		...buttonProps
	});
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/UI.js
/**
* Enum representing the UI elements composing DayPicker. These elements are
* mapped to {@link CustomComponents}, {@link ClassNames}, and {@link Styles}.
*
* Some elements are extended by flags and modifiers.
*/
var UI;
(function(UI) {
	/** The root component displaying the months and the navigation bar. */
	UI["Root"] = "root";
	/** The Chevron SVG element used by navigation buttons and dropdowns. */
	UI["Chevron"] = "chevron";
	/**
	* The grid cell with the day's date. Extended by {@link DayFlag} and
	* {@link SelectionState}.
	*/
	UI["Day"] = "day";
	/** The button containing the formatted day's date, inside the grid cell. */
	UI["DayButton"] = "day_button";
	/** The caption label of the month (when not showing the dropdown navigation). */
	UI["CaptionLabel"] = "caption_label";
	/** The container of the dropdown navigation (when enabled). */
	UI["Dropdowns"] = "dropdowns";
	/** The dropdown element to select for years and months. */
	UI["Dropdown"] = "dropdown";
	/** The container element of the dropdown. */
	UI["DropdownRoot"] = "dropdown_root";
	/** The root element of the footer. */
	UI["Footer"] = "footer";
	/** The month grid. */
	UI["MonthGrid"] = "month_grid";
	/** Contains the dropdown navigation or the caption label. */
	UI["MonthCaption"] = "month_caption";
	/** The dropdown with the months. */
	UI["MonthsDropdown"] = "months_dropdown";
	/** Wrapper of the month grid. */
	UI["Month"] = "month";
	/** The container of the displayed months. */
	UI["Months"] = "months";
	/** The navigation bar with the previous and next buttons. */
	UI["Nav"] = "nav";
	/**
	* The next month button in the navigation. *
	*
	* @since 9.1.0
	*/
	UI["NextMonthButton"] = "button_next";
	/**
	* The previous month button in the navigation.
	*
	* @since 9.1.0
	*/
	UI["PreviousMonthButton"] = "button_previous";
	/** The row containing the week. */
	UI["Week"] = "week";
	/** The group of row weeks in a month (`tbody`). */
	UI["Weeks"] = "weeks";
	/** The column header with the weekday. */
	UI["Weekday"] = "weekday";
	/** The row grouping the weekdays in the column headers. */
	UI["Weekdays"] = "weekdays";
	/** The cell containing the week number. */
	UI["WeekNumber"] = "week_number";
	/** The cell header of the week numbers column. */
	UI["WeekNumberHeader"] = "week_number_header";
	/** The dropdown with the years. */
	UI["YearsDropdown"] = "years_dropdown";
})(UI || (UI = {}));
/** Enum representing flags for the {@link UI | UI.Day} element. */
var DayFlag;
(function(DayFlag) {
	/** The day is disabled. */
	DayFlag["disabled"] = "disabled";
	/** The day is hidden. */
	DayFlag["hidden"] = "hidden";
	/** The day is outside the current month. */
	DayFlag["outside"] = "outside";
	/** The day is focused. */
	DayFlag["focused"] = "focused";
	/** The day is today. */
	DayFlag["today"] = "today";
})(DayFlag || (DayFlag = {}));
/**
* Enum representing selection states that can be applied to the
* {@link UI | UI.Day} element in selection mode.
*/
var SelectionState;
(function(SelectionState) {
	/** The day is at the end of a selected range. */
	SelectionState["range_end"] = "range_end";
	/** The day is at the middle of a selected range. */
	SelectionState["range_middle"] = "range_middle";
	/** The day is at the start of a selected range. */
	SelectionState["range_start"] = "range_start";
	/** The day is selected. */
	SelectionState["selected"] = "selected";
})(SelectionState || (SelectionState = {}));
/**
* Enum representing different animation states for transitioning between
* months.
*/
var Animation;
(function(Animation) {
	/** The entering weeks when they appear before the exiting month. */
	Animation["weeks_before_enter"] = "weeks_before_enter";
	/** The exiting weeks when they disappear before the entering month. */
	Animation["weeks_before_exit"] = "weeks_before_exit";
	/** The entering weeks when they appear after the exiting month. */
	Animation["weeks_after_enter"] = "weeks_after_enter";
	/** The exiting weeks when they disappear after the entering month. */
	Animation["weeks_after_exit"] = "weeks_after_exit";
	/** The entering caption when it appears after the exiting month. */
	Animation["caption_after_enter"] = "caption_after_enter";
	/** The exiting caption when it disappears after the entering month. */
	Animation["caption_after_exit"] = "caption_after_exit";
	/** The entering caption when it appears before the exiting month. */
	Animation["caption_before_enter"] = "caption_before_enter";
	/** The exiting caption when it disappears before the entering month. */
	Animation["caption_before_exit"] = "caption_before_exit";
})(Animation || (Animation = {}));
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/useDayPicker.js
/** @ignore */
var dayPickerContext = (0, import_react.createContext)(void 0);
/**
* Provides access to the DayPicker context, which includes properties and
* methods to interact with the DayPicker component. This hook must be used
* within a custom component.
*
* @template T - Use this type to refine the returned context type with a
*   specific selection mode.
* @returns The context to work with DayPicker.
* @throws {Error} If the hook is used outside of a DayPicker provider.
* @group Hooks
* @see https://daypicker.dev/guides/custom-components
*/
function useDayPicker() {
	const context = (0, import_react.useContext)(dayPickerContext);
	if (context === void 0) throw new Error("useDayPicker() must be used within a custom component.");
	return context;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Dropdown.js
/**
* Render a dropdown component for navigation in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Dropdown(props) {
	const { options, className, ...selectProps } = props;
	const { classNames, components, styles } = useDayPicker();
	const cssClassSelect = [classNames[UI.Dropdown], className].join(" ");
	const selectedOption = options?.find(({ value }) => value === selectProps.value);
	return import_react.createElement("span", {
		"data-disabled": selectProps.disabled,
		className: classNames[UI.DropdownRoot],
		style: styles?.[UI.DropdownRoot]
	}, import_react.createElement(components.Select, {
		className: cssClassSelect,
		...selectProps
	}, options?.map(({ value, label, disabled }) => import_react.createElement(components.Option, {
		key: value,
		value,
		disabled
	}, label))), import_react.createElement("span", {
		className: classNames[UI.CaptionLabel],
		style: styles?.[UI.CaptionLabel],
		"aria-hidden": true
	}, selectedOption?.label, import_react.createElement(components.Chevron, {
		orientation: "down",
		size: 18,
		className: classNames[UI.Chevron],
		style: styles?.[UI.Chevron]
	})));
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/DropdownNav.js
/**
* Render the navigation dropdowns for the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function DropdownNav(props) {
	return import_react.createElement("div", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Footer.js
/**
* Render the footer of the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Footer(props) {
	return import_react.createElement("div", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Month.js
/**
* Render the grid with the weekday header row and the weeks for a specific
* month.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Month(props) {
	const { calendarMonth, displayIndex, ...divProps } = props;
	return import_react.createElement("div", { ...divProps }, props.children);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/MonthCaption.js
/**
* Render the caption for a month in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function MonthCaption(props) {
	const { calendarMonth, displayIndex, ...divProps } = props;
	return import_react.createElement("div", { ...divProps });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/MonthGrid.js
/**
* Render the grid of days for a specific month.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function MonthGrid(props) {
	return import_react.createElement("table", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Months.js
/**
* Render a container wrapping the month grids.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Months(props) {
	return import_react.createElement("div", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/MonthsDropdown.js
/**
* Render a dropdown to navigate between months in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function MonthsDropdown(props) {
	const { components } = useDayPicker();
	return import_react.createElement(components.Dropdown, { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Nav.js
/**
* Render the navigation toolbar with buttons to navigate between months.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Nav(props) {
	const { onPreviousClick, onNextClick, previousMonth, nextMonth, ...navProps } = props;
	const { components, classNames, styles, labels: { labelPrevious, labelNext } } = useDayPicker();
	const handleNextClick = (0, import_react.useCallback)((e) => {
		if (nextMonth) onNextClick?.(e);
	}, [nextMonth, onNextClick]);
	const handlePreviousClick = (0, import_react.useCallback)((e) => {
		if (previousMonth) onPreviousClick?.(e);
	}, [previousMonth, onPreviousClick]);
	return import_react.createElement("nav", { ...navProps }, import_react.createElement(components.PreviousMonthButton, {
		type: "button",
		className: classNames[UI.PreviousMonthButton],
		style: styles?.[UI.PreviousMonthButton],
		tabIndex: previousMonth ? void 0 : -1,
		"aria-disabled": previousMonth ? void 0 : true,
		"aria-label": labelPrevious(previousMonth),
		onClick: handlePreviousClick
	}, import_react.createElement(components.Chevron, {
		disabled: previousMonth ? void 0 : true,
		className: classNames[UI.Chevron],
		style: styles?.[UI.Chevron],
		orientation: "left"
	})), import_react.createElement(components.NextMonthButton, {
		type: "button",
		className: classNames[UI.NextMonthButton],
		style: styles?.[UI.NextMonthButton],
		tabIndex: nextMonth ? void 0 : -1,
		"aria-disabled": nextMonth ? void 0 : true,
		"aria-label": labelNext(nextMonth),
		onClick: handleNextClick
	}, import_react.createElement(components.Chevron, {
		disabled: nextMonth ? void 0 : true,
		orientation: "right",
		className: classNames[UI.Chevron],
		style: styles?.[UI.Chevron]
	})));
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/NextMonthButton.js
/**
* Render the button to navigate to the next month in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function NextMonthButton(props) {
	return import_react.createElement("button", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Option.js
/**
* Render an `option` element.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Option(props) {
	return import_react.createElement("option", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/PreviousMonthButton.js
/**
* Render the button to navigate to the previous month in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function PreviousMonthButton(props) {
	return import_react.createElement("button", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Root.js
/**
* Render the root element of the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Root(props) {
	const { rootRef, ...rest } = props;
	return import_react.createElement("div", {
		...rest,
		ref: rootRef
	});
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Select.js
/**
* Render a `select` element.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Select(props) {
	return import_react.createElement("select", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Week.js
/**
* Render a table row representing a week in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Week(props) {
	const { week, ...trProps } = props;
	return import_react.createElement("tr", { ...trProps });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Weekday.js
/**
* Render a table header cell with the name of a weekday (e.g., "Mo", "Tu").
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Weekday(props) {
	return import_react.createElement("th", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Weekdays.js
/**
* Render the table row containing the weekday names.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Weekdays(props) {
	return import_react.createElement("thead", { "aria-hidden": true }, import_react.createElement("tr", { ...props }));
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/WeekNumber.js
/**
* Render a table cell displaying the number of the week.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function WeekNumber(props) {
	const { week, ...thProps } = props;
	return import_react.createElement("th", { ...thProps });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/WeekNumberHeader.js
/**
* Render the header cell for the week numbers column.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function WeekNumberHeader(props) {
	return import_react.createElement("th", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/Weeks.js
/**
* Render the container for the weeks in the month grid.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function Weeks(props) {
	return import_react.createElement("tbody", { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/YearsDropdown.js
/**
* Render a dropdown to navigate between years in the calendar.
*
* @group Components
* @see https://daypicker.dev/guides/custom-components
*/
function YearsDropdown(props) {
	const { components } = useDayPicker();
	return import_react.createElement(components.Dropdown, { ...props });
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/components/custom-components.js
var custom_components_exports = /* @__PURE__ */ __exportAll({
	CaptionLabel: () => CaptionLabel,
	Chevron: () => Chevron,
	Day: () => Day,
	DayButton: () => DayButton,
	Dropdown: () => Dropdown,
	DropdownNav: () => DropdownNav,
	Footer: () => Footer,
	Month: () => Month,
	MonthCaption: () => MonthCaption,
	MonthGrid: () => MonthGrid,
	Months: () => Months,
	MonthsDropdown: () => MonthsDropdown,
	Nav: () => Nav,
	NextMonthButton: () => NextMonthButton,
	Option: () => Option,
	PreviousMonthButton: () => PreviousMonthButton,
	Root: () => Root,
	Select: () => Select,
	Week: () => Week,
	WeekNumber: () => WeekNumber,
	WeekNumberHeader: () => WeekNumberHeader,
	Weekday: () => Weekday,
	Weekdays: () => Weekdays,
	Weeks: () => Weeks,
	YearsDropdown: () => YearsDropdown
});
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/rangeIncludesDate.js
/**
* Checks if a given date is within a specified date range.
*
* @since 9.0.0
* @param range - The date range to check against.
* @param date - The date to check.
* @param excludeEnds - If `true`, the range's start and end dates are excluded.
* @param dateLib - The date utility library instance.
* @returns `true` if the date is within the range, otherwise `false`.
* @group Utilities
*/
function rangeIncludesDate(range, date, excludeEnds = false, dateLib = defaultDateLib) {
	let { from, to } = range;
	const { differenceInCalendarDays, isSameDay } = dateLib;
	if (from && to) {
		if (differenceInCalendarDays(to, from) < 0) [from, to] = [to, from];
		return differenceInCalendarDays(date, from) >= (excludeEnds ? 1 : 0) && differenceInCalendarDays(to, date) >= (excludeEnds ? 1 : 0);
	}
	if (!excludeEnds && to) return isSameDay(to, date);
	if (!excludeEnds && from) return isSameDay(from, date);
	return false;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/typeguards.js
/**
* Checks if the given value is of type {@link DateInterval}.
*
* @param matcher - The value to check.
* @returns `true` if the value is a {@link DateInterval}, otherwise `false`.
* @group Utilities
*/
function isDateInterval(matcher) {
	return Boolean(matcher && typeof matcher === "object" && "before" in matcher && "after" in matcher);
}
/**
* Checks if the given value is of type {@link DateRange}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateRange}, otherwise `false`.
* @group Utilities
*/
function isDateRange(value) {
	return Boolean(value && typeof value === "object" && "from" in value);
}
/**
* Checks if the given value is of type {@link DateAfter}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateAfter}, otherwise `false`.
* @group Utilities
*/
function isDateAfterType(value) {
	return Boolean(value && typeof value === "object" && "after" in value);
}
/**
* Checks if the given value is of type {@link DateBefore}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DateBefore}, otherwise `false`.
* @group Utilities
*/
function isDateBeforeType(value) {
	return Boolean(value && typeof value === "object" && "before" in value);
}
/**
* Checks if the given value is of type {@link DayOfWeek}.
*
* @param value - The value to check.
* @returns `true` if the value is a {@link DayOfWeek}, otherwise `false`.
* @group Utilities
*/
function isDayOfWeekType(value) {
	return Boolean(value && typeof value === "object" && "dayOfWeek" in value);
}
/**
* Checks if the given value is an array of valid dates.
*
* @private
* @param value - The value to check.
* @param dateLib - The date utility library instance.
* @returns `true` if the value is an array of valid dates, otherwise `false`.
*/
function isDatesArray(value, dateLib) {
	return Array.isArray(value) && value.every(dateLib.isDate);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/dateMatchModifiers.js
/**
* Checks if a given date matches at least one of the specified {@link Matcher}.
*
* @param date - The date to check.
* @param matchers - The matchers to check against.
* @param dateLib - The date utility library instance.
* @returns `true` if the date matches any of the matchers, otherwise `false`.
* @group Utilities
*/
function dateMatchModifiers(date, matchers, dateLib = defaultDateLib) {
	const matchersArr = !Array.isArray(matchers) ? [matchers] : matchers;
	const { isSameDay, differenceInCalendarDays, isAfter } = dateLib;
	return matchersArr.some((matcher) => {
		if (typeof matcher === "boolean") return matcher;
		if (dateLib.isDate(matcher)) return isSameDay(date, matcher);
		if (isDatesArray(matcher, dateLib)) return matcher.some((matcherDate) => isSameDay(date, matcherDate));
		if (isDateRange(matcher)) return rangeIncludesDate(matcher, date, false, dateLib);
		if (isDayOfWeekType(matcher)) {
			if (!Array.isArray(matcher.dayOfWeek)) return matcher.dayOfWeek === date.getDay();
			return matcher.dayOfWeek.includes(date.getDay());
		}
		if (isDateInterval(matcher)) {
			const diffBefore = differenceInCalendarDays(matcher.before, date);
			const diffAfter = differenceInCalendarDays(matcher.after, date);
			const isDayBefore = diffBefore > 0;
			const isDayAfter = diffAfter < 0;
			if (isAfter(matcher.before, matcher.after)) return isDayAfter && isDayBefore;
			else return isDayBefore || isDayAfter;
		}
		if (isDateAfterType(matcher)) return differenceInCalendarDays(date, matcher.after) > 0;
		if (isDateBeforeType(matcher)) return differenceInCalendarDays(matcher.before, date) > 0;
		if (typeof matcher === "function") return matcher(date);
		return false;
	});
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/createGetModifiers.js
/**
* Creates a function to retrieve the modifiers for a given day.
*
* This function calculates both internal and custom modifiers for each day
* based on the provided calendar days and DayPicker props.
*
* @private
* @param days The array of `CalendarDay` objects to process.
* @param props The DayPicker props, including modifiers and configuration
*   options.
* @param dateLib The date library to use for date manipulation.
* @returns A function that retrieves the modifiers for a given `CalendarDay`.
*/
function createGetModifiers(days, props, navStart, navEnd, dateLib) {
	const { disabled, hidden, modifiers, showOutsideDays, broadcastCalendar, today = dateLib.today() } = props;
	const { isSameDay, isSameMonth, startOfMonth, isBefore, endOfMonth, isAfter } = dateLib;
	const computedNavStart = navStart && startOfMonth(navStart);
	const computedNavEnd = navEnd && endOfMonth(navEnd);
	const internalModifiersMap = {
		[DayFlag.focused]: [],
		[DayFlag.outside]: [],
		[DayFlag.disabled]: [],
		[DayFlag.hidden]: [],
		[DayFlag.today]: []
	};
	const customModifiersMap = {};
	for (const day of days) {
		const { date, displayMonth } = day;
		const isOutside = Boolean(displayMonth && !isSameMonth(date, displayMonth));
		const isBeforeNavStart = Boolean(computedNavStart && isBefore(date, computedNavStart));
		const isAfterNavEnd = Boolean(computedNavEnd && isAfter(date, computedNavEnd));
		const isDisabled = Boolean(disabled && dateMatchModifiers(date, disabled, dateLib));
		const isHidden = Boolean(hidden && dateMatchModifiers(date, hidden, dateLib)) || isBeforeNavStart || isAfterNavEnd || !broadcastCalendar && !showOutsideDays && isOutside || broadcastCalendar && showOutsideDays === false && isOutside;
		const isToday = isSameDay(date, today);
		if (isOutside) internalModifiersMap.outside.push(day);
		if (isDisabled) internalModifiersMap.disabled.push(day);
		if (isHidden) internalModifiersMap.hidden.push(day);
		if (isToday) internalModifiersMap.today.push(day);
		if (modifiers) Object.keys(modifiers).forEach((name) => {
			const modifierValue = modifiers?.[name];
			if (!(modifierValue ? dateMatchModifiers(date, modifierValue, dateLib) : false)) return;
			if (customModifiersMap[name]) customModifiersMap[name].push(day);
			else customModifiersMap[name] = [day];
		});
	}
	return (day) => {
		const dayFlags = {
			[DayFlag.focused]: false,
			[DayFlag.disabled]: false,
			[DayFlag.hidden]: false,
			[DayFlag.outside]: false,
			[DayFlag.today]: false
		};
		const customModifiers = {};
		for (const name in internalModifiersMap) dayFlags[name] = internalModifiersMap[name].some((d) => d === day);
		for (const name in customModifiersMap) customModifiers[name] = customModifiersMap[name].some((d) => d === day);
		return {
			...dayFlags,
			...customModifiers
		};
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getClassNamesForModifiers.js
/**
* Returns the class names for a day based on its modifiers.
*
* This function combines the base class name for the day with any class names
* associated with active modifiers.
*
* @param modifiers The modifiers applied to the day.
* @param classNames The base class names for the calendar elements.
* @param modifiersClassNames The class names associated with specific
*   modifiers.
* @returns An array of class names for the day.
*/
function getClassNamesForModifiers(modifiers, classNames, modifiersClassNames = {}) {
	return Object.entries(modifiers).filter(([, active]) => active === true).reduce((previousValue, [key]) => {
		if (modifiersClassNames[key]) previousValue.push(modifiersClassNames[key]);
		else if (classNames[DayFlag[key]]) previousValue.push(classNames[DayFlag[key]]);
		else if (classNames[SelectionState[key]]) previousValue.push(classNames[SelectionState[key]]);
		return previousValue;
	}, [classNames[UI.Day]]);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getComponents.js
/**
* Merges custom components from the props with the default components.
*
* This function ensures that any custom components provided in the props
* override the default components.
*
* @param customComponents The custom components provided in the DayPicker
*   props.
* @returns An object containing the merged components.
*/
function getComponents(customComponents) {
	return {
		...custom_components_exports,
		...customComponents
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getDataAttributes.js
/**
* Extracts `data-` attributes from the DayPicker props.
*
* This function collects all `data-` attributes from the props and adds
* additional attributes based on the DayPicker configuration.
*
* @param props The DayPicker props.
* @returns An object containing the `data-` attributes.
*/
function getDataAttributes(props) {
	const dataAttributes = {
		"data-mode": props.mode ?? void 0,
		"data-required": "required" in props ? props.required : void 0,
		"data-multiple-months": props.numberOfMonths && props.numberOfMonths > 1 || void 0,
		"data-week-numbers": props.showWeekNumber || void 0,
		"data-broadcast-calendar": props.broadcastCalendar || void 0,
		"data-nav-layout": props.navLayout || void 0
	};
	Object.entries(props).forEach(([key, val]) => {
		if (key.startsWith("data-")) dataAttributes[key] = val;
	});
	return dataAttributes;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getDefaultClassNames.js
/**
* Returns the default class names for the UI elements.
*
* This function generates a mapping of default class names for various UI
* elements, day flags, selection states, and animations.
*
* @returns An object containing the default class names.
* @group Utilities
*/
function getDefaultClassNames() {
	const classNames = {};
	for (const key in UI) classNames[UI[key]] = `rdp-${UI[key]}`;
	for (const key in DayFlag) classNames[DayFlag[key]] = `rdp-${DayFlag[key]}`;
	for (const key in SelectionState) classNames[SelectionState[key]] = `rdp-${SelectionState[key]}`;
	for (const key in Animation) classNames[Animation[key]] = `rdp-${Animation[key]}`;
	return classNames;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/formatCaption.js
/**
* Formats the caption of the month.
*
* @defaultValue Locale-specific month/year order (e.g., "November 2022").
* @param month The date representing the month.
* @param options Configuration options for the date library.
* @param dateLib The date library to use for formatting. If not provided, a new
*   instance is created.
* @returns The formatted caption as a string.
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
function formatCaption(month, options, dateLib) {
	return (dateLib ?? new DateLib(options)).formatMonthYear(month);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/formatDay.js
/**
* Formats the day date shown in the day cell.
*
* @defaultValue `d` (e.g., "1").
* @param date The date to format.
* @param options Configuration options for the date library.
* @param dateLib The date library to use for formatting. If not provided, a new
*   instance is created.
* @returns The formatted day as a string.
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
function formatDay(date, options, dateLib) {
	return (dateLib ?? new DateLib(options)).format(date, "d");
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/formatMonthDropdown.js
/**
* Formats the month for the dropdown option label.
*
* @defaultValue The localized full month name.
* @param month The date representing the month.
* @param dateLib The date library to use for formatting. Defaults to
*   `defaultDateLib`.
* @returns The formatted month name as a string.
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
function formatMonthDropdown(month, dateLib = defaultDateLib) {
	return dateLib.format(month, "LLLL");
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/formatWeekdayName.js
/**
* Formats the name of a weekday to be displayed in the weekdays header.
*
* @defaultValue `cccccc` (e.g., "Mo" for Monday).
* @param weekday The date representing the weekday.
* @param options Configuration options for the date library.
* @param dateLib The date library to use for formatting. If not provided, a new
*   instance is created.
* @returns The formatted weekday name as a string.
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
function formatWeekdayName(weekday, options, dateLib) {
	return (dateLib ?? new DateLib(options)).format(weekday, "cccccc");
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/formatWeekNumber.js
/**
* Formats the week number.
*
* @defaultValue The week number as a string, with a leading zero for single-digit numbers.
* @param weekNumber The week number to format.
* @param dateLib The date library to use for formatting. Defaults to
*   `defaultDateLib`.
* @returns The formatted week number as a string.
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
function formatWeekNumber(weekNumber, dateLib = defaultDateLib) {
	if (weekNumber < 10) return dateLib.formatNumber(`0${weekNumber.toLocaleString()}`);
	return dateLib.formatNumber(`${weekNumber.toLocaleString()}`);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/formatWeekNumberHeader.js
/**
* Formats the header for the week number column.
*
* @defaultValue An empty string `""`.
* @returns The formatted week number header as a string.
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
function formatWeekNumberHeader() {
	return ``;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/formatYearDropdown.js
/**
* Formats the year for the dropdown option label.
*
* @param year The year to format.
* @param dateLib The date library to use for formatting. Defaults to
*   `defaultDateLib`.
* @returns The formatted year as a string.
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
function formatYearDropdown(year, dateLib = defaultDateLib) {
	return dateLib.format(year, "yyyy");
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/formatters/index.js
var formatters_exports = /* @__PURE__ */ __exportAll({
	formatCaption: () => formatCaption,
	formatDay: () => formatDay,
	formatMonthDropdown: () => formatMonthDropdown,
	formatWeekNumber: () => formatWeekNumber,
	formatWeekNumberHeader: () => formatWeekNumberHeader,
	formatWeekdayName: () => formatWeekdayName,
	formatYearDropdown: () => formatYearDropdown
});
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getFormatters.js
/**
* Merges custom formatters from the props with the default formatters.
*
* @param customFormatters The custom formatters provided in the DayPicker
*   props.
* @returns The merged formatters object.
*/
function getFormatters(customFormatters) {
	return {
		...formatters_exports,
		...customFormatters
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelDayButton.js
/**
* Generates the ARIA label for a day button.
*
* Use the `modifiers` argument to provide additional context for the label,
* such as indicating if the day is "today" or "selected."
*
* @defaultValue The formatted date.
* @param date - The date to format.
* @param modifiers - The modifiers providing context for the day.
* @param options - Optional configuration for the date formatting library.
* @param dateLib - An optional instance of the date formatting library.
* @returns The ARIA label for the day button.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelDayButton(date, modifiers, options, dateLib) {
	let label = (dateLib ?? new DateLib(options)).format(date, "PPPP");
	if (modifiers.today) label = `Today, ${label}`;
	if (modifiers.selected) label = `${label}, selected`;
	return label;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelGrid.js
/**
* Generates the ARIA label for the month grid, which is announced when entering
* the grid.
*
* @defaultValue Locale-specific month/year order (e.g., "November 2022").
* @param date - The date representing the month.
* @param options - Optional configuration for the date formatting library.
* @param dateLib - An optional instance of the date formatting library.
* @returns The ARIA label for the month grid.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelGrid(date, options, dateLib) {
	return (dateLib ?? new DateLib(options)).formatMonthYear(date);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelGridcell.js
/**
* Generates the label for a day grid cell when the calendar is not interactive.
*
* @param date - The date to format.
* @param modifiers - Optional modifiers providing context for the day.
* @param options - Optional configuration for the date formatting library.
* @param dateLib - An optional instance of the date formatting library.
* @returns The label for the day grid cell.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelGridcell(date, modifiers, options, dateLib) {
	let label = (dateLib ?? new DateLib(options)).format(date, "PPPP");
	if (modifiers?.today) label = `Today, ${label}`;
	return label;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelMonthDropdown.js
/**
* Generates the ARIA label for the months dropdown.
*
* @defaultValue `"Choose the Month"`
* @param options - Optional configuration for the date formatting library.
* @returns The ARIA label for the months dropdown.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelMonthDropdown(_options) {
	return "Choose the Month";
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelNav.js
/**
* Generates the ARIA label for the navigation toolbar.
*
* @defaultValue `""`
* @returns The ARIA label for the navigation toolbar.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelNav() {
	return "";
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelNext.js
var defaultLabel = "Go to the Next Month";
/**
* Generates the ARIA label for the "next month" button.
*
* @defaultValue `"Go to the Next Month"`
* @param month - The date representing the next month, or `undefined` if there
*   is no next month.
* @returns The ARIA label for the "next month" button.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelNext(_month, _options) {
	return defaultLabel;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelPrevious.js
/**
* Generates the ARIA label for the "previous month" button.
*
* @defaultValue `"Go to the Previous Month"`
* @param month - The date representing the previous month, or `undefined` if
*   there is no previous month.
* @returns The ARIA label for the "previous month" button.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelPrevious(_month) {
	return "Go to the Previous Month";
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelWeekday.js
/**
* Generates the ARIA label for a weekday column header.
*
* @defaultValue `"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"`
* @param date - The date representing the weekday.
* @param options - Optional configuration for the date formatting library.
* @param dateLib - An optional instance of the date formatting library.
* @returns The ARIA label for the weekday column header.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelWeekday(date, options, dateLib) {
	return (dateLib ?? new DateLib(options)).format(date, "cccc");
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelWeekNumber.js
/**
* Generates the ARIA label for the week number cell (the first cell in a row).
*
* @defaultValue `Week ${weekNumber}`
* @param weekNumber - The number of the week.
* @param options - Optional configuration for the date formatting library.
* @returns The ARIA label for the week number cell.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelWeekNumber(weekNumber, _options) {
	return `Week ${weekNumber}`;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelWeekNumberHeader.js
/**
* Generates the ARIA label for the week number header element.
*
* @defaultValue `"Week Number"`
* @param options - Optional configuration for the date formatting library.
* @returns The ARIA label for the week number header.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelWeekNumberHeader(_options) {
	return "Week Number";
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/labelYearDropdown.js
/**
* Generates the ARIA label for the years dropdown.
*
* @defaultValue `"Choose the Year"`
* @param options - Optional configuration for the date formatting library.
* @returns The ARIA label for the years dropdown.
* @group Labels
* @see https://daypicker.dev/docs/translation#aria-labels
*/
function labelYearDropdown(_options) {
	return "Choose the Year";
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/labels/index.js
var labels_exports = /* @__PURE__ */ __exportAll({
	labelDayButton: () => labelDayButton,
	labelGrid: () => labelGrid,
	labelGridcell: () => labelGridcell,
	labelMonthDropdown: () => labelMonthDropdown,
	labelNav: () => labelNav,
	labelNext: () => labelNext,
	labelPrevious: () => labelPrevious,
	labelWeekNumber: () => labelWeekNumber,
	labelWeekNumberHeader: () => labelWeekNumberHeader,
	labelWeekday: () => labelWeekday,
	labelYearDropdown: () => labelYearDropdown
});
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getLabels.js
var resolveLabel = (defaultLabel, customLabel, localeLabel) => {
	if (customLabel) return customLabel;
	if (localeLabel) return typeof localeLabel === "function" ? localeLabel : (..._args) => localeLabel;
	return defaultLabel;
};
/**
* Merges custom labels from the props with the default labels.
*
* When available, uses the locale-provided translation for `labelNext`.
*
* @param customLabels The custom labels provided in the DayPicker props.
* @param options Options from the date library, used to resolve locale
*   translations.
* @returns The merged labels object with locale-aware defaults.
*/
function getLabels(customLabels, options) {
	const localeLabels = options.locale?.labels ?? {};
	return {
		...labels_exports,
		...customLabels ?? {},
		labelDayButton: resolveLabel(labelDayButton, customLabels?.labelDayButton, localeLabels.labelDayButton),
		labelMonthDropdown: resolveLabel(labelMonthDropdown, customLabels?.labelMonthDropdown, localeLabels.labelMonthDropdown),
		labelNext: resolveLabel(labelNext, customLabels?.labelNext, localeLabels.labelNext),
		labelPrevious: resolveLabel(labelPrevious, customLabels?.labelPrevious, localeLabels.labelPrevious),
		labelWeekNumber: resolveLabel(labelWeekNumber, customLabels?.labelWeekNumber, localeLabels.labelWeekNumber),
		labelYearDropdown: resolveLabel(labelYearDropdown, customLabels?.labelYearDropdown, localeLabels.labelYearDropdown),
		labelGrid: resolveLabel(labelGrid, customLabels?.labelGrid, localeLabels.labelGrid),
		labelGridcell: resolveLabel(labelGridcell, customLabels?.labelGridcell, localeLabels.labelGridcell),
		labelNav: resolveLabel(labelNav, customLabels?.labelNav, localeLabels.labelNav),
		labelWeekNumberHeader: resolveLabel(labelWeekNumberHeader, customLabels?.labelWeekNumberHeader, localeLabels.labelWeekNumberHeader),
		labelWeekday: resolveLabel(labelWeekday, customLabels?.labelWeekday, localeLabels.labelWeekday)
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getMonthOptions.js
/**
* Returns the months to show in the dropdown.
*
* This function generates a list of months for the current year, formatted
* using the provided formatter, and determines whether each month should be
* disabled based on the navigation range.
*
* @param displayMonth The currently displayed month.
* @param navStart The start date for navigation.
* @param navEnd The end date for navigation.
* @param formatters The formatters to use for formatting the month labels.
* @param dateLib The date library to use for date manipulation.
* @returns An array of dropdown options representing the months, or `undefined`
*   if no months are available.
*/
function getMonthOptions(displayMonth, navStart, navEnd, formatters, dateLib) {
	const { startOfMonth, startOfYear, endOfYear, eachMonthOfInterval, getMonth } = dateLib;
	return eachMonthOfInterval({
		start: startOfYear(displayMonth),
		end: endOfYear(displayMonth)
	}).map((month) => {
		const label = formatters.formatMonthDropdown(month, dateLib);
		return {
			value: getMonth(month),
			label,
			disabled: navStart && month < startOfMonth(navStart) || navEnd && month > startOfMonth(navEnd) || false
		};
	});
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getStyleForModifiers.js
/**
* Returns the computed style for a day based on its modifiers.
*
* This function merges the base styles for the day with any styles associated
* with active modifiers.
*
* @param dayModifiers The modifiers applied to the day.
* @param styles The base styles for the calendar elements.
* @param modifiersStyles The styles associated with specific modifiers.
* @returns The computed style for the day.
*/
function getStyleForModifiers(dayModifiers, styles = {}, modifiersStyles = {}) {
	let style = { ...styles?.[UI.Day] };
	Object.entries(dayModifiers).filter(([, active]) => active === true).forEach(([modifier]) => {
		style = {
			...style,
			...modifiersStyles?.[modifier]
		};
	});
	return style;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getWeekdays.js
/**
* Generates a series of 7 days, starting from the beginning of the week, to use
* for formatting weekday names (e.g., Monday, Tuesday, etc.).
*
* @param dateLib The date library to use for date manipulation.
* @param ISOWeek Whether to use ISO week numbering (weeks start on Monday).
* @param broadcastCalendar Whether to use the broadcast calendar (weeks start
*   on Monday, but may include adjustments for broadcast-specific rules).
* @returns An array of 7 dates representing the weekdays.
*/
function getWeekdays(dateLib, ISOWeek, broadcastCalendar, today) {
	const referenceToday = today ?? dateLib.today();
	const start = broadcastCalendar ? dateLib.startOfBroadcastWeek(referenceToday, dateLib) : ISOWeek ? dateLib.startOfISOWeek(referenceToday) : dateLib.startOfWeek(referenceToday);
	const days = [];
	for (let i = 0; i < 7; i++) {
		const day = dateLib.addDays(start, i);
		days.push(day);
	}
	return days;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getYearOptions.js
/**
* Returns the years to display in the dropdown.
*
* This function generates a list of years between the navigation start and end
* dates, formatted using the provided formatter.
*
* @param navStart The start date for navigation.
* @param navEnd The end date for navigation.
* @param formatters The formatters to use for formatting the year labels.
* @param dateLib The date library to use for date manipulation.
* @param reverse If true, reverses the order of the years (descending).
* @returns An array of dropdown options representing the years, or `undefined`
*   if `navStart` or `navEnd` is not provided.
*/
function getYearOptions(navStart, navEnd, formatters, dateLib, reverse = false) {
	if (!navStart) return void 0;
	if (!navEnd) return void 0;
	const { startOfYear, endOfYear, eachYearOfInterval, getYear } = dateLib;
	const years = eachYearOfInterval({
		start: startOfYear(navStart),
		end: endOfYear(navEnd)
	});
	if (reverse) years.reverse();
	return years.map((year) => {
		const label = formatters.formatYearDropdown(year, dateLib);
		return {
			value: getYear(year),
			label,
			disabled: false
		};
	});
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/noonDateLib.js
/**
* Creates `dateLib` overrides that keep all calendar math at noon in the target
* time zone. This avoids second-level offset changes (e.g., historical zones
* with +03:41:12) from pushing dates backward across midnight.
*/
function createNoonOverrides(timeZone, options = {}) {
	const { weekStartsOn, locale } = options;
	const fallbackWeekStartsOn = weekStartsOn ?? locale?.options?.weekStartsOn ?? 0;
	const toNoonTZDate = (date) => {
		const normalizedDate = typeof date === "number" || typeof date === "string" ? new Date(date) : date;
		return new TZDate(normalizedDate.getFullYear(), normalizedDate.getMonth(), normalizedDate.getDate(), 12, 0, 0, timeZone);
	};
	const toCalendarDate = (date) => {
		const zoned = toNoonTZDate(date);
		return new Date(zoned.getFullYear(), zoned.getMonth(), zoned.getDate(), 0, 0, 0, 0);
	};
	return {
		today: () => {
			return toNoonTZDate(TZDate.tz(timeZone));
		},
		newDate: (year, monthIndex, date) => {
			return new TZDate(year, monthIndex, date, 12, 0, 0, timeZone);
		},
		startOfDay: (date) => {
			return toNoonTZDate(date);
		},
		startOfWeek: (date, options) => {
			const base = toNoonTZDate(date);
			const weekStartsOnValue = options?.weekStartsOn ?? fallbackWeekStartsOn;
			const diff = (base.getDay() - weekStartsOnValue + 7) % 7;
			base.setDate(base.getDate() - diff);
			return base;
		},
		startOfISOWeek: (date) => {
			const base = toNoonTZDate(date);
			const diff = (base.getDay() - 1 + 7) % 7;
			base.setDate(base.getDate() - diff);
			return base;
		},
		startOfMonth: (date) => {
			const base = toNoonTZDate(date);
			base.setDate(1);
			return base;
		},
		startOfYear: (date) => {
			const base = toNoonTZDate(date);
			base.setMonth(0, 1);
			return base;
		},
		endOfWeek: (date, options) => {
			const base = toNoonTZDate(date);
			const diff = (((options?.weekStartsOn ?? fallbackWeekStartsOn) + 6) % 7 - base.getDay() + 7) % 7;
			base.setDate(base.getDate() + diff);
			return base;
		},
		endOfISOWeek: (date) => {
			const base = toNoonTZDate(date);
			const diff = (7 - base.getDay()) % 7;
			base.setDate(base.getDate() + diff);
			return base;
		},
		endOfMonth: (date) => {
			const base = toNoonTZDate(date);
			base.setMonth(base.getMonth() + 1, 0);
			return base;
		},
		endOfYear: (date) => {
			const base = toNoonTZDate(date);
			base.setMonth(11, 31);
			return base;
		},
		eachMonthOfInterval: (interval) => {
			const start = toNoonTZDate(interval.start);
			const end = toNoonTZDate(interval.end);
			const result = [];
			const cursor = new TZDate(start.getFullYear(), start.getMonth(), 1, 12, 0, 0, timeZone);
			const endKey = end.getFullYear() * 12 + end.getMonth();
			while (cursor.getFullYear() * 12 + cursor.getMonth() <= endKey) {
				result.push(new TZDate(cursor, timeZone));
				cursor.setMonth(cursor.getMonth() + 1, 1);
			}
			return result;
		},
		addDays: (date, amount) => {
			const base = toNoonTZDate(date);
			base.setDate(base.getDate() + amount);
			return base;
		},
		addWeeks: (date, amount) => {
			const base = toNoonTZDate(date);
			base.setDate(base.getDate() + amount * 7);
			return base;
		},
		addMonths: (date, amount) => {
			const base = toNoonTZDate(date);
			base.setMonth(base.getMonth() + amount);
			return base;
		},
		addYears: (date, amount) => {
			const base = toNoonTZDate(date);
			base.setFullYear(base.getFullYear() + amount);
			return base;
		},
		eachYearOfInterval: (interval) => {
			const start = toNoonTZDate(interval.start);
			const end = toNoonTZDate(interval.end);
			const years = [];
			const cursor = new TZDate(start.getFullYear(), 0, 1, 12, 0, 0, timeZone);
			while (cursor.getFullYear() <= end.getFullYear()) {
				years.push(new TZDate(cursor, timeZone));
				cursor.setFullYear(cursor.getFullYear() + 1, 0, 1);
			}
			return years;
		},
		getWeek: (date, options) => {
			return getWeek(toCalendarDate(date), {
				weekStartsOn: options?.weekStartsOn ?? fallbackWeekStartsOn,
				firstWeekContainsDate: options?.firstWeekContainsDate ?? locale?.options?.firstWeekContainsDate ?? 1
			});
		},
		getISOWeek: (date) => {
			return getISOWeek(toCalendarDate(date));
		},
		differenceInCalendarDays: (dateLeft, dateRight) => {
			return differenceInCalendarDays(toCalendarDate(dateLeft), toCalendarDate(dateRight));
		},
		differenceInCalendarMonths: (dateLeft, dateRight) => {
			return differenceInCalendarMonths(toCalendarDate(dateLeft), toCalendarDate(dateRight));
		}
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/useAnimation.js
var asHtmlElement = (element) => {
	if (element instanceof HTMLElement) return element;
	return null;
};
var queryMonthEls = (element) => [...element.querySelectorAll("[data-animated-month]") ?? []];
var queryMonthEl = (element) => asHtmlElement(element.querySelector("[data-animated-month]"));
var queryCaptionEl = (element) => asHtmlElement(element.querySelector("[data-animated-caption]"));
var queryWeeksEl = (element) => asHtmlElement(element.querySelector("[data-animated-weeks]"));
var queryNavEl = (element) => asHtmlElement(element.querySelector("[data-animated-nav]"));
var queryWeekdaysEl = (element) => asHtmlElement(element.querySelector("[data-animated-weekdays]"));
/**
* Handles animations for transitioning between months in the DayPicker
* component.
*
* @private
* @param rootElRef - A reference to the root element of the DayPicker
*   component.
* @param enabled - Whether animations are enabled.
* @param options - Configuration options for the animation, including class
*   names, months, focused day, and the date utility library.
*/
function useAnimation(rootElRef, enabled, { classNames, months, focused, dateLib }) {
	const previousRootElSnapshotRef = (0, import_react.useRef)(null);
	const previousMonthsRef = (0, import_react.useRef)(months);
	const animatingRef = (0, import_react.useRef)(false);
	(0, import_react.useLayoutEffect)(() => {
		const previousMonths = previousMonthsRef.current;
		previousMonthsRef.current = months;
		if (!enabled || !rootElRef.current || !(rootElRef.current instanceof HTMLElement) || months.length === 0 || previousMonths.length === 0 || months.length !== previousMonths.length) return;
		const isSameMonth = dateLib.isSameMonth(months[0].date, previousMonths[0].date);
		const isAfterPreviousMonth = dateLib.isAfter(months[0].date, previousMonths[0].date);
		const captionAnimationClass = isAfterPreviousMonth ? classNames[Animation.caption_after_enter] : classNames[Animation.caption_before_enter];
		const weeksAnimationClass = isAfterPreviousMonth ? classNames[Animation.weeks_after_enter] : classNames[Animation.weeks_before_enter];
		const previousRootElSnapshot = previousRootElSnapshotRef.current;
		const rootElSnapshot = rootElRef.current.cloneNode(true);
		if (rootElSnapshot instanceof HTMLElement) {
			queryMonthEls(rootElSnapshot).forEach((currentMonthElSnapshot) => {
				if (!(currentMonthElSnapshot instanceof HTMLElement)) return;
				const previousMonthElSnapshot = queryMonthEl(currentMonthElSnapshot);
				if (previousMonthElSnapshot && currentMonthElSnapshot.contains(previousMonthElSnapshot)) currentMonthElSnapshot.removeChild(previousMonthElSnapshot);
				const captionEl = queryCaptionEl(currentMonthElSnapshot);
				if (captionEl) captionEl.classList.remove(captionAnimationClass);
				const weeksEl = queryWeeksEl(currentMonthElSnapshot);
				if (weeksEl) weeksEl.classList.remove(weeksAnimationClass);
			});
			previousRootElSnapshotRef.current = rootElSnapshot;
		} else previousRootElSnapshotRef.current = null;
		if (animatingRef.current || isSameMonth || focused) return;
		const previousMonthEls = previousRootElSnapshot instanceof HTMLElement ? queryMonthEls(previousRootElSnapshot) : [];
		const currentMonthEls = queryMonthEls(rootElRef.current);
		if (currentMonthEls?.every((el) => el instanceof HTMLElement) && previousMonthEls?.every((el) => el instanceof HTMLElement)) {
			animatingRef.current = true;
			const cleanUpFunctions = [];
			rootElRef.current.style.isolation = "isolate";
			const navEl = queryNavEl(rootElRef.current);
			if (navEl) navEl.style.zIndex = "1";
			currentMonthEls.forEach((currentMonthEl, index) => {
				const previousMonthEl = previousMonthEls[index];
				if (!previousMonthEl) return;
				currentMonthEl.style.position = "relative";
				currentMonthEl.style.overflow = "hidden";
				const captionEl = queryCaptionEl(currentMonthEl);
				if (captionEl) captionEl.classList.add(captionAnimationClass);
				const weeksEl = queryWeeksEl(currentMonthEl);
				if (weeksEl) weeksEl.classList.add(weeksAnimationClass);
				const cleanUp = () => {
					animatingRef.current = false;
					if (rootElRef.current) rootElRef.current.style.isolation = "";
					if (navEl) navEl.style.zIndex = "";
					if (captionEl) captionEl.classList.remove(captionAnimationClass);
					if (weeksEl) weeksEl.classList.remove(weeksAnimationClass);
					currentMonthEl.style.position = "";
					currentMonthEl.style.overflow = "";
					if (currentMonthEl.contains(previousMonthEl)) currentMonthEl.removeChild(previousMonthEl);
				};
				cleanUpFunctions.push(cleanUp);
				previousMonthEl.style.pointerEvents = "none";
				previousMonthEl.style.position = "absolute";
				previousMonthEl.style.overflow = "hidden";
				previousMonthEl.setAttribute("aria-hidden", "true");
				const previousWeekdaysEl = queryWeekdaysEl(previousMonthEl);
				if (previousWeekdaysEl) previousWeekdaysEl.style.opacity = "0";
				const previousCaptionEl = queryCaptionEl(previousMonthEl);
				if (previousCaptionEl) {
					previousCaptionEl.classList.add(isAfterPreviousMonth ? classNames[Animation.caption_before_exit] : classNames[Animation.caption_after_exit]);
					previousCaptionEl.addEventListener("animationend", cleanUp);
				}
				const previousWeeksEl = queryWeeksEl(previousMonthEl);
				if (previousWeeksEl) previousWeeksEl.classList.add(isAfterPreviousMonth ? classNames[Animation.weeks_before_exit] : classNames[Animation.weeks_after_exit]);
				currentMonthEl.insertBefore(previousMonthEl, currentMonthEl.firstChild);
			});
		}
	});
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getDates.js
/**
* Returns all the dates to display in the calendar.
*
* This function calculates the range of dates to display based on the provided
* display months, constraints, and calendar configuration.
*
* @param displayMonths The months to display in the calendar.
* @param maxDate The maximum date to include in the range.
* @param props The DayPicker props, including calendar configuration options.
* @param dateLib The date library to use for date manipulation.
* @returns An array of dates to display in the calendar.
*/
function getDates(displayMonths, maxDate, props, dateLib) {
	const firstMonth = displayMonths[0];
	const lastMonth = displayMonths[displayMonths.length - 1];
	const { ISOWeek, fixedWeeks, broadcastCalendar } = props ?? {};
	const { addDays, differenceInCalendarDays, differenceInCalendarMonths, endOfBroadcastWeek, endOfISOWeek, endOfMonth, endOfWeek, isAfter, startOfBroadcastWeek, startOfISOWeek, startOfWeek } = dateLib;
	const startWeekFirstDate = broadcastCalendar ? startOfBroadcastWeek(firstMonth, dateLib) : ISOWeek ? startOfISOWeek(firstMonth) : startOfWeek(firstMonth);
	const displayMonthsWeekEnd = broadcastCalendar ? endOfBroadcastWeek(lastMonth) : ISOWeek ? endOfISOWeek(endOfMonth(lastMonth)) : endOfWeek(endOfMonth(lastMonth));
	const constraintWeekEnd = maxDate && (broadcastCalendar ? endOfBroadcastWeek(maxDate) : ISOWeek ? endOfISOWeek(maxDate) : endOfWeek(maxDate));
	const nOfDays = differenceInCalendarDays(constraintWeekEnd && isAfter(displayMonthsWeekEnd, constraintWeekEnd) ? constraintWeekEnd : displayMonthsWeekEnd, startWeekFirstDate);
	const nOfMonths = differenceInCalendarMonths(lastMonth, firstMonth) + 1;
	const dates = [];
	for (let i = 0; i <= nOfDays; i++) {
		const date = addDays(startWeekFirstDate, i);
		dates.push(date);
	}
	const extraDates = (broadcastCalendar ? 35 : 42) * nOfMonths;
	if (fixedWeeks && dates.length < extraDates) {
		const daysToAdd = extraDates - dates.length;
		for (let i = 0; i < daysToAdd; i++) {
			const date = addDays(dates[dates.length - 1], 1);
			dates.push(date);
		}
	}
	return dates;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getDays.js
/**
* Returns all the days belonging to the calendar by merging the days in the
* weeks for each month.
*
* @param calendarMonths The array of calendar months.
* @returns An array of `CalendarDay` objects representing all the days in the
*   calendar.
*/
function getDays(calendarMonths) {
	const initialDays = [];
	return calendarMonths.reduce((days, month) => {
		const weekDays = month.weeks.reduce((weekDays, week) => {
			return weekDays.concat(week.days.slice());
		}, initialDays.slice());
		return days.concat(weekDays.slice());
	}, initialDays.slice());
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getDisplayMonths.js
/**
* Returns the months to display in the calendar.
*
* @param firstDisplayedMonth The first month currently displayed in the
*   calendar.
* @param calendarEndMonth The latest month the user can navigate to.
* @param props The DayPicker props, including `numberOfMonths`.
* @param dateLib The date library to use for date manipulation.
* @returns An array of dates representing the months to display.
*/
function getDisplayMonths(firstDisplayedMonth, calendarEndMonth, props, dateLib) {
	const { numberOfMonths = 1 } = props;
	const months = [];
	for (let i = 0; i < numberOfMonths; i++) {
		const month = dateLib.addMonths(firstDisplayedMonth, i);
		if (calendarEndMonth && month > calendarEndMonth) break;
		months.push(month);
	}
	return months;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getInitialMonth.js
/**
* Determines the initial month to display in the calendar based on the provided
* props.
*
* This function calculates the starting month, considering constraints such as
* `startMonth`, `endMonth`, and the number of months to display.
*
* @param props The DayPicker props, including navigation and date constraints.
* @param dateLib The date library to use for date manipulation.
* @returns The initial month to display.
*/
function getInitialMonth(props, navStart, navEnd, dateLib) {
	const { month, defaultMonth, today = dateLib.today(), numberOfMonths = 1 } = props;
	let initialMonth = month || defaultMonth || today;
	const { differenceInCalendarMonths, addMonths, startOfMonth } = dateLib;
	if (navEnd && differenceInCalendarMonths(navEnd, initialMonth) < numberOfMonths - 1) initialMonth = addMonths(navEnd, -1 * (numberOfMonths - 1));
	if (navStart && differenceInCalendarMonths(initialMonth, navStart) < 0) initialMonth = navStart;
	return startOfMonth(initialMonth);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getMonths.js
/**
* Returns the months to display in the calendar.
*
* This function generates `CalendarMonth` objects for each month to be
* displayed, including their weeks and days, based on the provided display
* months and dates.
*
* @param displayMonths The months (as dates) to display in the calendar.
* @param dates The dates to display in the calendar.
* @param props Options from the DayPicker props context.
* @param dateLib The date library to use for date manipulation.
* @returns An array of `CalendarMonth` objects representing the months to
*   display.
*/
function getMonths(displayMonths, dates, props, dateLib) {
	const { addDays, endOfBroadcastWeek, endOfISOWeek, endOfMonth, endOfWeek, getISOWeek, getWeek, startOfBroadcastWeek, startOfISOWeek, startOfWeek } = dateLib;
	const dayPickerMonths = displayMonths.reduce((months, month) => {
		const firstDateOfFirstWeek = props.broadcastCalendar ? startOfBroadcastWeek(month, dateLib) : props.ISOWeek ? startOfISOWeek(month) : startOfWeek(month);
		const lastDateOfLastWeek = props.broadcastCalendar ? endOfBroadcastWeek(month) : props.ISOWeek ? endOfISOWeek(endOfMonth(month)) : endOfWeek(endOfMonth(month));
		/** The dates to display in the month. */
		const monthDates = dates.filter((date) => {
			return date >= firstDateOfFirstWeek && date <= lastDateOfLastWeek;
		});
		const nrOfDaysWithFixedWeeks = props.broadcastCalendar ? 35 : 42;
		if (props.fixedWeeks && monthDates.length < nrOfDaysWithFixedWeeks) {
			const extraDates = dates.filter((date) => {
				const daysToAdd = nrOfDaysWithFixedWeeks - monthDates.length;
				return date > lastDateOfLastWeek && date <= addDays(lastDateOfLastWeek, daysToAdd);
			});
			monthDates.push(...extraDates);
		}
		const dayPickerMonth = new CalendarMonth(month, monthDates.reduce((weeks, date) => {
			const weekNumber = props.ISOWeek ? getISOWeek(date) : getWeek(date);
			const week = weeks.find((week) => week.weekNumber === weekNumber);
			const day = new CalendarDay(date, month, dateLib);
			if (!week) weeks.push(new CalendarWeek(weekNumber, [day]));
			else week.days.push(day);
			return weeks;
		}, []));
		months.push(dayPickerMonth);
		return months;
	}, []);
	if (!props.reverseMonths) return dayPickerMonths;
	else return dayPickerMonths.reverse();
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getNavMonth.js
/**
* Returns the start and end months for calendar navigation.
*
* @param props The DayPicker props, including navigation and layout options.
* @param dateLib The date library to use for date manipulation.
* @returns A tuple containing the start and end months for navigation.
*/
function getNavMonths(props, dateLib) {
	let { startMonth, endMonth } = props;
	const { startOfYear, startOfDay, startOfMonth, endOfMonth, addYears, endOfYear, today } = dateLib;
	const hasYearDropdown = props.captionLayout === "dropdown" || props.captionLayout === "dropdown-years";
	if (startMonth) startMonth = startOfMonth(startMonth);
	else if (!startMonth && hasYearDropdown) startMonth = startOfYear(addYears(props.today ?? today(), -100));
	if (endMonth) endMonth = endOfMonth(endMonth);
	else if (!endMonth && hasYearDropdown) endMonth = endOfYear(props.today ?? today());
	return [startMonth ? startOfDay(startMonth) : startMonth, endMonth ? startOfDay(endMonth) : endMonth];
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getNextMonth.js
/**
* Returns the next month the user can navigate to, based on the given options.
*
* The next month is not always the next calendar month:
*
* - If it is after the `calendarEndMonth`, it returns `undefined`.
* - If paged navigation is enabled, it skips forward by the number of displayed
*   months.
*
* @param firstDisplayedMonth The first month currently displayed in the
*   calendar.
* @param calendarEndMonth The latest month the user can navigate to.
* @param options Navigation options, including `numberOfMonths` and
*   `pagedNavigation`.
* @param dateLib The date library to use for date manipulation.
* @returns The next month, or `undefined` if navigation is not possible.
*/
function getNextMonth(firstDisplayedMonth, calendarEndMonth, options, dateLib) {
	if (options.disableNavigation) return;
	const { pagedNavigation, numberOfMonths = 1 } = options;
	const { startOfMonth, addMonths, differenceInCalendarMonths } = dateLib;
	const offset = pagedNavigation ? numberOfMonths : 1;
	const month = startOfMonth(firstDisplayedMonth);
	if (!calendarEndMonth) return addMonths(month, offset);
	if (differenceInCalendarMonths(calendarEndMonth, firstDisplayedMonth) < numberOfMonths) return;
	return addMonths(month, offset);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getPreviousMonth.js
/**
* Returns the previous month the user can navigate to, based on the given
* options.
*
* The previous month is not always the previous calendar month:
*
* - If it is before the `calendarStartMonth`, it returns `undefined`.
* - If paged navigation is enabled, it skips back by the number of displayed
*   months.
*
* @param firstDisplayedMonth The first month currently displayed in the
*   calendar.
* @param calendarStartMonth The earliest month the user can navigate to.
* @param options Navigation options, including `numberOfMonths` and
*   `pagedNavigation`.
* @param dateLib The date library to use for date manipulation.
* @returns The previous month, or `undefined` if navigation is not possible.
*/
function getPreviousMonth(firstDisplayedMonth, calendarStartMonth, options, dateLib) {
	if (options.disableNavigation) return;
	const { pagedNavigation, numberOfMonths } = options;
	const { startOfMonth, addMonths, differenceInCalendarMonths } = dateLib;
	const offset = pagedNavigation ? numberOfMonths ?? 1 : 1;
	const month = startOfMonth(firstDisplayedMonth);
	if (!calendarStartMonth) return addMonths(month, -offset);
	if (differenceInCalendarMonths(month, calendarStartMonth) <= 0) return;
	return addMonths(month, -offset);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getWeeks.js
/**
* Returns an array of calendar weeks from an array of calendar months.
*
* @param months The array of calendar months.
* @returns An array of calendar weeks.
*/
function getWeeks(months) {
	return months.reduce((weeks, month) => {
		return weeks.concat(month.weeks.slice());
	}, [].slice());
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/useControlledValue.js
/**
* A custom hook for managing both controlled and uncontrolled component states.
*
* This hook allows a component to support both controlled and uncontrolled
* states by determining whether the `controlledValue` is provided. If it is
* undefined, the hook falls back to using the internal state.
*
* @example
*   // Uncontrolled usage
*   const [value, setValue] = useControlledValue(0, undefined);
*
*   // Controlled usage
*   const [value, setValue] = useControlledValue(0, props.value);
*
* @template T - The type of the value.
* @param defaultValue The initial value for the uncontrolled state.
* @param controlledValue The value for the controlled state. If undefined, the
*   component will use the uncontrolled state.
* @returns A tuple where the first element is the current value (either
*   controlled or uncontrolled) and the second element is a setter function to
*   update the value.
*/
function useControlledValue(defaultValue, controlledValue) {
	const [uncontrolledValue, setValue] = (0, import_react.useState)(defaultValue);
	return [controlledValue === void 0 ? uncontrolledValue : controlledValue, setValue];
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/useCalendar.js
/**
* Provides the calendar object to work with the calendar in custom components.
*
* @private
* @param props - The DayPicker props related to calendar configuration.
* @param dateLib - The date utility library instance.
* @returns The calendar object containing displayed days, weeks, months, and
*   navigation methods.
*/
function useCalendar(props, dateLib) {
	const [navStart, navEnd] = getNavMonths(props, dateLib);
	const { startOfMonth, endOfMonth } = dateLib;
	const initialMonth = getInitialMonth(props, navStart, navEnd, dateLib);
	const [firstMonth, setFirstMonth] = useControlledValue(initialMonth, props.month ? initialMonth : void 0);
	(0, import_react.useEffect)(() => {
		const newInitialMonth = getInitialMonth(props, navStart, navEnd, dateLib);
		setFirstMonth(newInitialMonth);
	}, [props.timeZone]);
	/** The months displayed in the calendar. */
	const { months, weeks, days, previousMonth, nextMonth } = (0, import_react.useMemo)(() => {
		const displayMonths = getDisplayMonths(firstMonth, navEnd, { numberOfMonths: props.numberOfMonths }, dateLib);
		const months = getMonths(displayMonths, getDates(displayMonths, props.endMonth ? endOfMonth(props.endMonth) : void 0, {
			ISOWeek: props.ISOWeek,
			fixedWeeks: props.fixedWeeks,
			broadcastCalendar: props.broadcastCalendar
		}, dateLib), {
			broadcastCalendar: props.broadcastCalendar,
			fixedWeeks: props.fixedWeeks,
			ISOWeek: props.ISOWeek,
			reverseMonths: props.reverseMonths
		}, dateLib);
		return {
			months,
			weeks: getWeeks(months),
			days: getDays(months),
			previousMonth: getPreviousMonth(firstMonth, navStart, props, dateLib),
			nextMonth: getNextMonth(firstMonth, navEnd, props, dateLib)
		};
	}, [
		dateLib,
		firstMonth.getTime(),
		navEnd?.getTime(),
		navStart?.getTime(),
		props.disableNavigation,
		props.broadcastCalendar,
		props.endMonth?.getTime(),
		props.fixedWeeks,
		props.ISOWeek,
		props.numberOfMonths,
		props.pagedNavigation,
		props.reverseMonths
	]);
	const { disableNavigation, onMonthChange } = props;
	const isDayInCalendar = (day) => weeks.some((week) => week.days.some((d) => d.isEqualTo(day)));
	const goToMonth = (date) => {
		if (disableNavigation) return;
		let newMonth = startOfMonth(date);
		if (navStart && newMonth < startOfMonth(navStart)) newMonth = startOfMonth(navStart);
		if (navEnd && newMonth > startOfMonth(navEnd)) newMonth = startOfMonth(navEnd);
		setFirstMonth(newMonth);
		onMonthChange?.(newMonth);
	};
	const goToDay = (day) => {
		if (isDayInCalendar(day)) return;
		goToMonth(day.date);
	};
	return {
		months,
		weeks,
		days,
		navStart,
		navEnd,
		previousMonth,
		nextMonth,
		goToMonth,
		goToDay
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/calculateFocusTarget.js
var FocusTargetPriority;
(function(FocusTargetPriority) {
	FocusTargetPriority[FocusTargetPriority["Today"] = 0] = "Today";
	FocusTargetPriority[FocusTargetPriority["Selected"] = 1] = "Selected";
	FocusTargetPriority[FocusTargetPriority["LastFocused"] = 2] = "LastFocused";
	FocusTargetPriority[FocusTargetPriority["FocusedModifier"] = 3] = "FocusedModifier";
})(FocusTargetPriority || (FocusTargetPriority = {}));
/**
* Determines if a day is focusable based on its modifiers.
*
* A day is considered focusable if it is not disabled, hidden, or outside the
* displayed month.
*
* @param modifiers The modifiers applied to the day.
* @returns `true` if the day is focusable, otherwise `false`.
*/
function isFocusableDay(modifiers) {
	return !modifiers[DayFlag.disabled] && !modifiers[DayFlag.hidden] && !modifiers[DayFlag.outside];
}
/**
* Calculates the focus target day based on priority.
*
* This function determines the day that should receive focus in the calendar,
* prioritizing days with specific modifiers (e.g., "focused", "today") or
* selection states.
*
* @param days The array of `CalendarDay` objects to evaluate.
* @param getModifiers A function to retrieve the modifiers for a given day.
* @param isSelected A function to determine if a day is selected.
* @param lastFocused The last focused day, if any.
* @returns The `CalendarDay` that should receive focus, or `undefined` if no
*   focusable day is found.
*/
function calculateFocusTarget(days, getModifiers, isSelected, lastFocused) {
	let focusTarget;
	let foundFocusTargetPriority = -1;
	for (const day of days) {
		const modifiers = getModifiers(day);
		if (isFocusableDay(modifiers)) {
			if (modifiers[DayFlag.focused] && foundFocusTargetPriority < FocusTargetPriority.FocusedModifier) {
				focusTarget = day;
				foundFocusTargetPriority = FocusTargetPriority.FocusedModifier;
			} else if (lastFocused?.isEqualTo(day) && foundFocusTargetPriority < FocusTargetPriority.LastFocused) {
				focusTarget = day;
				foundFocusTargetPriority = FocusTargetPriority.LastFocused;
			} else if (isSelected(day.date) && foundFocusTargetPriority < FocusTargetPriority.Selected) {
				focusTarget = day;
				foundFocusTargetPriority = FocusTargetPriority.Selected;
			} else if (modifiers[DayFlag.today] && foundFocusTargetPriority < FocusTargetPriority.Today) {
				focusTarget = day;
				foundFocusTargetPriority = FocusTargetPriority.Today;
			}
		}
	}
	if (!focusTarget) focusTarget = days.find((day) => isFocusableDay(getModifiers(day)));
	return focusTarget;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getFocusableDate.js
/**
* Calculates the next date that should be focused in the calendar.
*
* This function determines the next focusable date based on the movement
* direction, constraints, and calendar configuration.
*
* @param moveBy The unit of movement (e.g., "day", "week").
* @param moveDir The direction of movement ("before" or "after").
* @param refDate The reference date from which to calculate the next focusable
*   date.
* @param navStart The earliest date the user can navigate to.
* @param navEnd The latest date the user can navigate to.
* @param props The DayPicker props, including calendar configuration options.
* @param dateLib The date library to use for date manipulation.
* @returns The next focusable date.
*/
function getFocusableDate(moveBy, moveDir, refDate, navStart, navEnd, props, dateLib) {
	const { ISOWeek, broadcastCalendar } = props;
	const { addDays, addMonths, addWeeks, addYears, endOfBroadcastWeek, endOfISOWeek, endOfWeek, max, min, startOfBroadcastWeek, startOfISOWeek, startOfWeek } = dateLib;
	let focusableDate = {
		day: addDays,
		week: addWeeks,
		month: addMonths,
		year: addYears,
		startOfWeek: (date) => broadcastCalendar ? startOfBroadcastWeek(date, dateLib) : ISOWeek ? startOfISOWeek(date) : startOfWeek(date),
		endOfWeek: (date) => broadcastCalendar ? endOfBroadcastWeek(date) : ISOWeek ? endOfISOWeek(date) : endOfWeek(date)
	}[moveBy](refDate, moveDir === "after" ? 1 : -1);
	if (moveDir === "before" && navStart) focusableDate = max([navStart, focusableDate]);
	else if (moveDir === "after" && navEnd) focusableDate = min([navEnd, focusableDate]);
	return focusableDate;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/helpers/getNextFocus.js
/**
* Determines the next focusable day in the calendar.
*
* This function recursively calculates the next focusable day based on the
* movement direction and modifiers applied to the days.
*
* @param moveBy The unit of movement (e.g., "day", "week").
* @param moveDir The direction of movement ("before" or "after").
* @param refDay The currently focused day.
* @param calendarStartMonth The earliest month the user can navigate to.
* @param calendarEndMonth The latest month the user can navigate to.
* @param props The DayPicker props, including modifiers and configuration
*   options.
* @param dateLib The date library to use for date manipulation.
* @param attempt The current recursion attempt (used to limit recursion depth).
* @returns The next focusable day, or `undefined` if no focusable day is found.
*/
function getNextFocus(moveBy, moveDir, refDay, calendarStartMonth, calendarEndMonth, props, dateLib, attempt = 0) {
	if (attempt > 365) return;
	const focusableDate = getFocusableDate(moveBy, moveDir, refDay.date, calendarStartMonth, calendarEndMonth, props, dateLib);
	const isDisabled = Boolean(props.disabled && dateMatchModifiers(focusableDate, props.disabled, dateLib));
	const isHidden = Boolean(props.hidden && dateMatchModifiers(focusableDate, props.hidden, dateLib));
	const focusDay = new CalendarDay(focusableDate, focusableDate, dateLib);
	if (!isDisabled && !isHidden) return focusDay;
	return getNextFocus(moveBy, moveDir, focusDay, calendarStartMonth, calendarEndMonth, props, dateLib, attempt + 1);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/useFocus.js
/**
* Manages focus behavior for the DayPicker component, including setting,
* moving, and blurring focus on calendar days.
*
* @template T - The type of DayPicker props.
* @param props - The DayPicker props.
* @param calendar - The calendar object containing the displayed days and
*   months.
* @param getModifiers - A function to retrieve modifiers for a given day.
* @param isSelected - A function to check if a date is selected.
* @param dateLib - The date utility library instance.
* @returns An object containing focus-related methods and the currently focused
*   day.
*/
function useFocus(props, calendar, getModifiers, isSelected, dateLib) {
	const { autoFocus } = props;
	const [lastFocused, setLastFocused] = (0, import_react.useState)();
	const focusTarget = calculateFocusTarget(calendar.days, getModifiers, isSelected || (() => false), lastFocused);
	const [focusedDay, setFocused] = (0, import_react.useState)(autoFocus ? focusTarget : void 0);
	const blur = () => {
		setLastFocused(focusedDay);
		setFocused(void 0);
	};
	const moveFocus = (moveBy, moveDir) => {
		if (!focusedDay) return;
		const nextFocus = getNextFocus(moveBy, moveDir, focusedDay, calendar.navStart, calendar.navEnd, props, dateLib);
		if (!nextFocus) return;
		if (props.disableNavigation) {
			if (!calendar.days.some((day) => day.isEqualTo(nextFocus))) return;
		}
		calendar.goToDay(nextFocus);
		setFocused(nextFocus);
	};
	const isFocusTarget = (day) => {
		return Boolean(focusTarget?.isEqualTo(day));
	};
	return {
		isFocusTarget,
		setFocused,
		focused: focusedDay,
		blur,
		moveFocus
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/selection/useMulti.js
/**
* Hook to manage multiple-date selection in the DayPicker component.
*
* @template T - The type of DayPicker props.
* @param props - The DayPicker props.
* @param dateLib - The date utility library instance.
* @returns An object containing the selected dates, a function to select dates,
*   and a function to check if a date is selected.
*/
function useMulti(props, dateLib) {
	const { selected: initiallySelected, required, onSelect } = props;
	const [internallySelected, setSelected] = useControlledValue(initiallySelected, onSelect ? initiallySelected : void 0);
	const selected = !onSelect ? internallySelected : initiallySelected;
	const { isSameDay } = dateLib;
	const isSelected = (date) => {
		return selected?.some((d) => isSameDay(d, date)) ?? false;
	};
	const { min, max } = props;
	const select = (triggerDate, modifiers, e) => {
		let newDates = [...selected ?? []];
		if (isSelected(triggerDate)) {
			if (selected?.length === min) return;
			if (required && selected?.length === 1) return;
			newDates = selected?.filter((d) => !isSameDay(d, triggerDate));
		} else if (selected?.length === max) newDates = [triggerDate];
		else newDates = [...newDates, triggerDate];
		if (!onSelect) setSelected(newDates);
		onSelect?.(newDates, triggerDate, modifiers, e);
		return newDates;
	};
	return {
		selected,
		select,
		isSelected
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/addToRange.js
/**
* Adds a date to an existing range, considering constraints like minimum and
* maximum range size.
*
* @param date - The date to add to the range.
* @param initialRange - The initial range to which the date will be added.
* @param min - The minimum number of days in the range.
* @param max - The maximum number of days in the range.
* @param required - Whether the range must always include at least one date.
* @param dateLib - The date utility library instance.
* @returns The updated date range, or `undefined` if the range is cleared.
* @group Utilities
*/
function addToRange(date, initialRange, min = 0, max = 0, required = false, dateLib = defaultDateLib) {
	const { from, to } = initialRange || {};
	const { isSameDay, isAfter, isBefore } = dateLib;
	let range;
	if (!from && !to) range = {
		from: date,
		to: min > 0 ? void 0 : date
	};
	else if (from && !to) {
		if (isSameDay(from, date)) {
			if (min === 0) range = {
				from,
				to: date
			};
			else if (required) range = {
				from,
				to: void 0
			};
			else range = void 0;
		} else if (isBefore(date, from)) range = {
			from: date,
			to: from
		};
		else range = {
			from,
			to: date
		};
	} else if (from && to) {
		if (isSameDay(from, date) && isSameDay(to, date)) {
			if (required) range = {
				from,
				to
			};
			else range = void 0;
		} else if (isSameDay(from, date)) range = {
			from,
			to: min > 0 ? void 0 : date
		};
		else if (isSameDay(to, date)) range = {
			from: date,
			to: min > 0 ? void 0 : date
		};
		else if (isBefore(date, from)) range = {
			from: date,
			to
		};
		else if (isAfter(date, from)) range = {
			from,
			to: date
		};
		else if (isAfter(date, to)) range = {
			from,
			to: date
		};
		else throw new Error("Invalid range");
	}
	if (range?.from && range?.to) {
		const diff = dateLib.differenceInCalendarDays(range.to, range.from);
		if (max > 0 && diff > max) range = {
			from: date,
			to: void 0
		};
		else if (min > 1 && diff < min) range = {
			from: date,
			to: void 0
		};
	}
	return range;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/rangeContainsDayOfWeek.js
/**
* Checks if a date range contains one or more specified days of the week.
*
* @since 9.2.2
* @param range - The date range to check.
* @param dayOfWeek - The day(s) of the week to check for (`0-6`, where `0` is
*   Sunday).
* @param dateLib - The date utility library instance.
* @returns `true` if the range contains the specified day(s) of the week,
*   otherwise `false`.
* @group Utilities
*/
function rangeContainsDayOfWeek(range, dayOfWeek, dateLib = defaultDateLib) {
	const dayOfWeekArr = !Array.isArray(dayOfWeek) ? [dayOfWeek] : dayOfWeek;
	let date = range.from;
	const totalDays = dateLib.differenceInCalendarDays(range.to, range.from);
	const totalDaysLimit = Math.min(totalDays, 6);
	for (let i = 0; i <= totalDaysLimit; i++) {
		if (dayOfWeekArr.includes(date.getDay())) return true;
		date = dateLib.addDays(date, 1);
	}
	return false;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/rangeOverlaps.js
/**
* Determines if two date ranges overlap.
*
* @since 9.2.2
* @param rangeLeft - The first date range.
* @param rangeRight - The second date range.
* @param dateLib - The date utility library instance.
* @returns `true` if the ranges overlap, otherwise `false`.
* @group Utilities
*/
function rangeOverlaps(rangeLeft, rangeRight, dateLib = defaultDateLib) {
	return rangeIncludesDate(rangeLeft, rangeRight.from, false, dateLib) || rangeIncludesDate(rangeLeft, rangeRight.to, false, dateLib) || rangeIncludesDate(rangeRight, rangeLeft.from, false, dateLib) || rangeIncludesDate(rangeRight, rangeLeft.to, false, dateLib);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/rangeContainsModifiers.js
/**
* Checks if a date range contains dates that match the given modifiers.
*
* @since 9.2.2
* @param range - The date range to check.
* @param modifiers - The modifiers to match against.
* @param dateLib - The date utility library instance.
* @returns `true` if the range contains matching dates, otherwise `false`.
* @group Utilities
*/
function rangeContainsModifiers(range, modifiers, dateLib = defaultDateLib) {
	const matchers = Array.isArray(modifiers) ? modifiers : [modifiers];
	if (matchers.filter((matcher) => typeof matcher !== "function").some((matcher) => {
		if (typeof matcher === "boolean") return matcher;
		if (dateLib.isDate(matcher)) return rangeIncludesDate(range, matcher, false, dateLib);
		if (isDatesArray(matcher, dateLib)) return matcher.some((date) => rangeIncludesDate(range, date, false, dateLib));
		if (isDateRange(matcher)) {
			if (matcher.from && matcher.to) return rangeOverlaps(range, {
				from: matcher.from,
				to: matcher.to
			}, dateLib);
			return false;
		}
		if (isDayOfWeekType(matcher)) return rangeContainsDayOfWeek(range, matcher.dayOfWeek, dateLib);
		if (isDateInterval(matcher)) {
			if (dateLib.isAfter(matcher.before, matcher.after)) return rangeOverlaps(range, {
				from: dateLib.addDays(matcher.after, 1),
				to: dateLib.addDays(matcher.before, -1)
			}, dateLib);
			return dateMatchModifiers(range.from, matcher, dateLib) || dateMatchModifiers(range.to, matcher, dateLib);
		}
		if (isDateAfterType(matcher) || isDateBeforeType(matcher)) return dateMatchModifiers(range.from, matcher, dateLib) || dateMatchModifiers(range.to, matcher, dateLib);
		return false;
	})) return true;
	const functionMatchers = matchers.filter((matcher) => typeof matcher === "function");
	if (functionMatchers.length) {
		let date = range.from;
		const totalDays = dateLib.differenceInCalendarDays(range.to, range.from);
		for (let i = 0; i <= totalDays; i++) {
			if (functionMatchers.some((matcher) => matcher(date))) return true;
			date = dateLib.addDays(date, 1);
		}
	}
	return false;
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/selection/useRange.js
/**
* Hook to manage range selection in the DayPicker component.
*
* @template T - The type of DayPicker props.
* @param props - The DayPicker props.
* @param dateLib - The date utility library instance.
* @returns An object containing the selected range, a function to select a
*   range, and a function to check if a date is within the range.
*/
function useRange(props, dateLib) {
	const { disabled, excludeDisabled, resetOnSelect, selected: initiallySelected, required, onSelect } = props;
	const [internallySelected, setSelected] = useControlledValue(initiallySelected, onSelect ? initiallySelected : void 0);
	const selected = !onSelect ? internallySelected : initiallySelected;
	const isSelected = (date) => selected && rangeIncludesDate(selected, date, false, dateLib);
	const select = (triggerDate, modifiers, e) => {
		const { min, max } = props;
		let newRange;
		if (triggerDate) {
			const selectedFrom = selected?.from;
			const selectedTo = selected?.to;
			const hasFullRange = !!selectedFrom && !!selectedTo;
			const isClickingSingleDayRange = !!selectedFrom && !!selectedTo && dateLib.isSameDay(selectedFrom, selectedTo) && dateLib.isSameDay(triggerDate, selectedFrom);
			if (resetOnSelect && (hasFullRange || !selected?.from)) {
				if (!required && isClickingSingleDayRange) newRange = void 0;
				else newRange = {
					from: triggerDate,
					to: void 0
				};
			} else newRange = addToRange(triggerDate, selected, min, max, required, dateLib);
		}
		if (excludeDisabled && disabled && newRange?.from && newRange.to) {
			if (rangeContainsModifiers({
				from: newRange.from,
				to: newRange.to
			}, disabled, dateLib)) {
				newRange.from = triggerDate;
				newRange.to = void 0;
			}
		}
		if (!onSelect) setSelected(newRange);
		onSelect?.(newRange, triggerDate, modifiers, e);
		return newRange;
	};
	return {
		selected,
		select,
		isSelected
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/selection/useSingle.js
/**
* Hook to manage single-date selection in the DayPicker component.
*
* @template T - The type of DayPicker props.
* @param props - The DayPicker props.
* @param dateLib - The date utility library instance.
* @returns An object containing the selected date, a function to select a date,
*   and a function to check if a date is selected.
*/
function useSingle(props, dateLib) {
	const { selected: initiallySelected, required, onSelect } = props;
	const [internallySelected, setSelected] = useControlledValue(initiallySelected, onSelect ? initiallySelected : void 0);
	const selected = !onSelect ? internallySelected : initiallySelected;
	const { isSameDay } = dateLib;
	const isSelected = (compareDate) => {
		return selected ? isSameDay(selected, compareDate) : false;
	};
	const select = (triggerDate, modifiers, e) => {
		let newDate = triggerDate;
		if (!required && selected && selected && isSameDay(triggerDate, selected)) newDate = void 0;
		if (!onSelect) setSelected(newDate);
		if (required) onSelect?.(newDate, triggerDate, modifiers, e);
		else onSelect?.(newDate, triggerDate, modifiers, e);
		return newDate;
	};
	return {
		selected,
		select,
		isSelected
	};
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/useSelection.js
/**
* Determines the appropriate selection hook to use based on the selection mode
* and returns the corresponding selection object.
*
* @template T - The type of DayPicker props.
* @param props - The DayPicker props.
* @param dateLib - The date utility library instance.
* @returns The selection object for the specified mode, or `undefined` if no
*   mode is set.
*/
function useSelection(props, dateLib) {
	const single = useSingle(props, dateLib);
	const multi = useMulti(props, dateLib);
	const range = useRange(props, dateLib);
	switch (props.mode) {
		case "single": return single;
		case "multiple": return multi;
		case "range": return range;
		default: return;
	}
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/toTimeZone.js
/**
* Convert a {@link Date} or {@link TZDate} instance to the given time zone.
* Reuses the same instance when it is already a {@link TZDate} using the target
* time zone to avoid extra allocations.
*/
function toTimeZone(date, timeZone) {
	if (date instanceof TZDate && date.timeZone === timeZone) return date;
	return new TZDate(date, timeZone);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/utils/convertMatchersToTimeZone.js
function toZoneNoon(date, timeZone, noonSafe) {
	if (!noonSafe) return toTimeZone(date, timeZone);
	const zoned = toTimeZone(date, timeZone);
	const noonZoned = new TZDate(zoned.getFullYear(), zoned.getMonth(), zoned.getDate(), 12, 0, 0, timeZone);
	return new Date(noonZoned.getTime());
}
function convertMatcher(matcher, timeZone, noonSafe) {
	if (typeof matcher === "boolean" || typeof matcher === "function") return matcher;
	if (matcher instanceof Date) return toZoneNoon(matcher, timeZone, noonSafe);
	if (Array.isArray(matcher)) return matcher.map((value) => value instanceof Date ? toZoneNoon(value, timeZone, noonSafe) : value);
	if (isDateRange(matcher)) return {
		...matcher,
		from: matcher.from ? toTimeZone(matcher.from, timeZone) : matcher.from,
		to: matcher.to ? toTimeZone(matcher.to, timeZone) : matcher.to
	};
	if (isDateInterval(matcher)) return {
		before: toZoneNoon(matcher.before, timeZone, noonSafe),
		after: toZoneNoon(matcher.after, timeZone, noonSafe)
	};
	if (isDateAfterType(matcher)) return { after: toZoneNoon(matcher.after, timeZone, noonSafe) };
	if (isDateBeforeType(matcher)) return { before: toZoneNoon(matcher.before, timeZone, noonSafe) };
	return matcher;
}
/**
* Convert any {@link Matcher} or array of matchers to the specified time zone.
*
* @param matchers - The matcher or matchers to convert.
* @param timeZone - The target IANA time zone.
* @returns The converted matcher(s).
* @group Utilities
*/
function convertMatchersToTimeZone(matchers, timeZone, noonSafe) {
	if (!matchers) return matchers;
	if (Array.isArray(matchers)) return matchers.map((matcher) => convertMatcher(matcher, timeZone, noonSafe));
	return convertMatcher(matchers, timeZone, noonSafe);
}
//#endregion
//#region ../../node_modules/.pnpm/react-day-picker@10.0.1_@types+react@19.2.18_react@19.2.8/node_modules/react-day-picker/dist/esm/DayPicker.js
/**
* Renders the DayPicker calendar component.
*
* @param initialProps - The props for the DayPicker component.
* @returns The rendered DayPicker component.
* @group DayPicker
* @see https://daypicker.dev
*/
function DayPicker(initialProps) {
	let props = initialProps;
	const timeZone = props.timeZone;
	if (timeZone) {
		props = {
			...initialProps,
			timeZone
		};
		if (props.today) props.today = toTimeZone(props.today, timeZone);
		if (props.month) props.month = toTimeZone(props.month, timeZone);
		if (props.defaultMonth) props.defaultMonth = toTimeZone(props.defaultMonth, timeZone);
		if (props.startMonth) props.startMonth = toTimeZone(props.startMonth, timeZone);
		if (props.endMonth) props.endMonth = toTimeZone(props.endMonth, timeZone);
		if (props.mode === "single" && props.selected) props.selected = toTimeZone(props.selected, timeZone);
		else if (props.mode === "multiple" && props.selected) props.selected = props.selected?.map((date) => toTimeZone(date, timeZone));
		else if (props.mode === "range" && props.selected) props.selected = {
			from: props.selected.from ? toTimeZone(props.selected.from, timeZone) : props.selected.from,
			to: props.selected.to ? toTimeZone(props.selected.to, timeZone) : props.selected.to
		};
		if (props.disabled !== void 0) props.disabled = convertMatchersToTimeZone(props.disabled, timeZone);
		if (props.hidden !== void 0) props.hidden = convertMatchersToTimeZone(props.hidden, timeZone);
		if (props.modifiers) {
			const nextModifiers = {};
			Object.keys(props.modifiers).forEach((key) => {
				nextModifiers[key] = convertMatchersToTimeZone(props.modifiers?.[key], timeZone);
			});
			props.modifiers = nextModifiers;
		}
	}
	const { components, formatters, labels, dateLib, locale, classNames } = (0, import_react.useMemo)(() => {
		const locale = {
			...enUS,
			...props.locale
		};
		const weekStartsOn = props.broadcastCalendar ? 1 : props.weekStartsOn;
		const noonOverrides = props.noonSafe && props.timeZone ? createNoonOverrides(props.timeZone, {
			weekStartsOn,
			locale
		}) : void 0;
		const overrides = props.dateLib && noonOverrides ? {
			...noonOverrides,
			...props.dateLib
		} : props.dateLib ?? noonOverrides;
		const dateLib = new DateLib({
			locale,
			weekStartsOn,
			firstWeekContainsDate: props.firstWeekContainsDate,
			useAdditionalWeekYearTokens: props.useAdditionalWeekYearTokens,
			useAdditionalDayOfYearTokens: props.useAdditionalDayOfYearTokens,
			timeZone: props.timeZone,
			numerals: props.numerals
		}, overrides);
		return {
			dateLib,
			components: getComponents(props.components),
			formatters: getFormatters(props.formatters),
			labels: getLabels(props.labels, dateLib.options),
			locale,
			classNames: {
				...getDefaultClassNames(),
				...props.classNames
			}
		};
	}, [
		props.locale,
		props.broadcastCalendar,
		props.weekStartsOn,
		props.firstWeekContainsDate,
		props.useAdditionalWeekYearTokens,
		props.useAdditionalDayOfYearTokens,
		props.timeZone,
		props.numerals,
		props.dateLib,
		props.noonSafe,
		props.components,
		props.formatters,
		props.labels,
		props.classNames
	]);
	if (!props.today) props = {
		...props,
		today: dateLib.today()
	};
	const { captionLayout, mode, navLayout, numberOfMonths = 1, onDayBlur, onDayClick, onDayFocus, onDayKeyDown, onDayMouseEnter, onDayMouseLeave, onNextClick, onPrevClick, showWeekNumber, styles } = props;
	const { formatCaption, formatDay, formatMonthDropdown, formatWeekNumber, formatWeekNumberHeader, formatWeekdayName, formatYearDropdown } = formatters;
	const calendar = useCalendar(props, dateLib);
	const { days, months, navStart, navEnd, previousMonth, nextMonth, goToMonth } = calendar;
	const getModifiers = createGetModifiers(days, props, navStart, navEnd, dateLib);
	const { isSelected, select, selected: selectedValue } = useSelection(props, dateLib) ?? {};
	const { blur, focused, isFocusTarget, moveFocus, setFocused } = useFocus(props, calendar, getModifiers, isSelected ?? (() => false), dateLib);
	const { labelDayButton, labelGridcell, labelGrid, labelMonthDropdown, labelNav, labelPrevious, labelNext, labelWeekday, labelWeekNumber, labelWeekNumberHeader, labelYearDropdown } = labels;
	const weekdays = (0, import_react.useMemo)(() => getWeekdays(dateLib, props.ISOWeek, props.broadcastCalendar, props.today), [
		dateLib,
		props.ISOWeek,
		props.broadcastCalendar,
		props.today
	]);
	const isInteractive = mode !== void 0 || onDayClick !== void 0;
	const handlePreviousClick = (0, import_react.useCallback)(() => {
		if (!previousMonth) return;
		goToMonth(previousMonth);
		onPrevClick?.(previousMonth);
	}, [
		previousMonth,
		goToMonth,
		onPrevClick
	]);
	const handleNextClick = (0, import_react.useCallback)(() => {
		if (!nextMonth) return;
		goToMonth(nextMonth);
		onNextClick?.(nextMonth);
	}, [
		goToMonth,
		nextMonth,
		onNextClick
	]);
	const handleDayClick = (0, import_react.useCallback)((day, m) => (e) => {
		e.preventDefault();
		e.stopPropagation();
		setFocused(day);
		if (m.disabled) return;
		select?.(day.date, m, e);
		onDayClick?.(day.date, m, e);
	}, [
		select,
		onDayClick,
		setFocused
	]);
	const handleDayFocus = (0, import_react.useCallback)((day, m) => (e) => {
		setFocused(day);
		onDayFocus?.(day.date, m, e);
	}, [onDayFocus, setFocused]);
	const handleDayBlur = (0, import_react.useCallback)((day, m) => (e) => {
		blur();
		onDayBlur?.(day.date, m, e);
	}, [blur, onDayBlur]);
	const handleDayKeyDown = (0, import_react.useCallback)((day, modifiers) => (e) => {
		const keyMap = {
			ArrowLeft: [e.shiftKey ? "month" : "day", props.dir === "rtl" ? "after" : "before"],
			ArrowRight: [e.shiftKey ? "month" : "day", props.dir === "rtl" ? "before" : "after"],
			ArrowDown: [e.shiftKey ? "year" : "week", "after"],
			ArrowUp: [e.shiftKey ? "year" : "week", "before"],
			PageUp: [e.shiftKey ? "year" : "month", "before"],
			PageDown: [e.shiftKey ? "year" : "month", "after"],
			Home: ["startOfWeek", "before"],
			End: ["endOfWeek", "after"]
		};
		if (keyMap[e.key]) {
			e.preventDefault();
			e.stopPropagation();
			const [moveBy, moveDir] = keyMap[e.key];
			moveFocus(moveBy, moveDir);
		}
		onDayKeyDown?.(day.date, modifiers, e);
	}, [
		moveFocus,
		onDayKeyDown,
		props.dir
	]);
	const handleDayMouseEnter = (0, import_react.useCallback)((day, modifiers) => (e) => {
		onDayMouseEnter?.(day.date, modifiers, e);
	}, [onDayMouseEnter]);
	const handleDayMouseLeave = (0, import_react.useCallback)((day, modifiers) => (e) => {
		onDayMouseLeave?.(day.date, modifiers, e);
	}, [onDayMouseLeave]);
	const handleMonthChange = (0, import_react.useCallback)((date, monthOffset) => (e) => {
		const selectedMonth = Number(e.target.value);
		const month = dateLib.setMonth(dateLib.startOfMonth(date), selectedMonth);
		goToMonth(dateLib.addMonths(month, -monthOffset));
	}, [dateLib, goToMonth]);
	const handleYearChange = (0, import_react.useCallback)((date, monthOffset) => (e) => {
		const selectedYear = Number(e.target.value);
		const month = dateLib.setYear(dateLib.startOfMonth(date), selectedYear);
		goToMonth(dateLib.addMonths(month, -monthOffset));
	}, [dateLib, goToMonth]);
	const { className, style } = (0, import_react.useMemo)(() => ({
		className: [classNames[UI.Root], props.className].filter(Boolean).join(" "),
		style: {
			...styles?.[UI.Root],
			...props.style
		}
	}), [
		classNames,
		props.className,
		props.style,
		styles
	]);
	const dataAttributes = getDataAttributes(props);
	const getDropdownStyle = (dropdown) => {
		const dropdownStyle = styles?.[UI.Dropdown];
		const specificDropdownStyle = styles?.[dropdown];
		if (!dropdownStyle && !specificDropdownStyle) return;
		return {
			...dropdownStyle,
			...specificDropdownStyle
		};
	};
	const rootElRef = (0, import_react.useRef)(null);
	useAnimation(rootElRef, Boolean(props.animate), {
		classNames,
		months,
		focused,
		dateLib
	});
	const contextValue = {
		dayPickerProps: props,
		selected: selectedValue,
		select,
		isSelected,
		months,
		nextMonth,
		previousMonth,
		goToMonth,
		getModifiers,
		components,
		classNames,
		styles,
		labels,
		formatters
	};
	return import_react.createElement(dayPickerContext.Provider, { value: contextValue }, import_react.createElement(components.Root, {
		rootRef: props.animate ? rootElRef : void 0,
		className,
		style,
		dir: props.dir,
		id: props.id,
		lang: props.lang ?? locale.code,
		nonce: props.nonce,
		title: props.title,
		role: props.role,
		"aria-label": props["aria-label"],
		"aria-labelledby": props["aria-labelledby"],
		...dataAttributes
	}, import_react.createElement(components.Months, {
		className: classNames[UI.Months],
		style: styles?.[UI.Months]
	}, !props.hideNavigation && !navLayout && import_react.createElement(components.Nav, {
		"data-animated-nav": props.animate ? "true" : void 0,
		className: classNames[UI.Nav],
		style: styles?.[UI.Nav],
		"aria-label": labelNav(),
		onPreviousClick: handlePreviousClick,
		onNextClick: handleNextClick,
		previousMonth,
		nextMonth
	}), months.map((calendarMonth, displayIndex) => {
		const monthOffset = props.reverseMonths ? months.length - 1 - displayIndex : displayIndex;
		return import_react.createElement(components.Month, {
			"data-animated-month": props.animate ? "true" : void 0,
			className: classNames[UI.Month],
			style: styles?.[UI.Month],
			key: displayIndex,
			displayIndex,
			calendarMonth
		}, navLayout === "around" && !props.hideNavigation && displayIndex === 0 && import_react.createElement(components.PreviousMonthButton, {
			type: "button",
			className: classNames[UI.PreviousMonthButton],
			style: styles?.[UI.PreviousMonthButton],
			tabIndex: previousMonth ? void 0 : -1,
			"aria-disabled": previousMonth ? void 0 : true,
			"aria-label": labelPrevious(previousMonth),
			onClick: handlePreviousClick,
			"data-animated-button": props.animate ? "true" : void 0
		}, import_react.createElement(components.Chevron, {
			disabled: previousMonth ? void 0 : true,
			className: classNames[UI.Chevron],
			style: styles?.[UI.Chevron],
			orientation: props.dir === "rtl" ? "right" : "left"
		})), import_react.createElement(components.MonthCaption, {
			"data-animated-caption": props.animate ? "true" : void 0,
			className: classNames[UI.MonthCaption],
			style: styles?.[UI.MonthCaption],
			calendarMonth,
			displayIndex
		}, captionLayout?.startsWith("dropdown") ? import_react.createElement(components.DropdownNav, {
			className: classNames[UI.Dropdowns],
			style: styles?.[UI.Dropdowns]
		}, (() => {
			const monthControl = captionLayout === "dropdown" || captionLayout === "dropdown-months" ? import_react.createElement(components.MonthsDropdown, {
				key: "month",
				className: classNames[UI.MonthsDropdown],
				"aria-label": labelMonthDropdown(),
				disabled: Boolean(props.disableNavigation),
				onChange: handleMonthChange(calendarMonth.date, monthOffset),
				options: getMonthOptions(calendarMonth.date, navStart, navEnd, formatters, dateLib),
				style: getDropdownStyle(UI.MonthsDropdown),
				value: dateLib.getMonth(calendarMonth.date)
			}) : import_react.createElement("span", { key: "month" }, formatMonthDropdown(calendarMonth.date, dateLib));
			const yearControl = captionLayout === "dropdown" || captionLayout === "dropdown-years" ? import_react.createElement(components.YearsDropdown, {
				key: "year",
				className: classNames[UI.YearsDropdown],
				"aria-label": labelYearDropdown(dateLib.options),
				disabled: Boolean(props.disableNavigation),
				onChange: handleYearChange(calendarMonth.date, monthOffset),
				options: getYearOptions(navStart, navEnd, formatters, dateLib, Boolean(props.reverseYears)),
				style: getDropdownStyle(UI.YearsDropdown),
				value: dateLib.getYear(calendarMonth.date)
			}) : import_react.createElement("span", { key: "year" }, formatYearDropdown(calendarMonth.date, dateLib));
			return dateLib.getMonthYearOrder() === "year-first" ? [yearControl, monthControl] : [monthControl, yearControl];
		})(), import_react.createElement("span", {
			role: "status",
			"aria-live": "polite",
			style: {
				border: 0,
				clip: "rect(0 0 0 0)",
				height: "1px",
				margin: "-1px",
				overflow: "hidden",
				padding: 0,
				position: "absolute",
				width: "1px",
				whiteSpace: "nowrap",
				wordWrap: "normal"
			}
		}, formatCaption(calendarMonth.date, dateLib.options, dateLib))) : import_react.createElement(components.CaptionLabel, {
			className: classNames[UI.CaptionLabel],
			style: styles?.[UI.CaptionLabel],
			role: "status",
			"aria-live": "polite"
		}, formatCaption(calendarMonth.date, dateLib.options, dateLib))), navLayout === "around" && !props.hideNavigation && displayIndex === numberOfMonths - 1 && import_react.createElement(components.NextMonthButton, {
			type: "button",
			className: classNames[UI.NextMonthButton],
			style: styles?.[UI.NextMonthButton],
			tabIndex: nextMonth ? void 0 : -1,
			"aria-disabled": nextMonth ? void 0 : true,
			"aria-label": labelNext(nextMonth),
			onClick: handleNextClick,
			"data-animated-button": props.animate ? "true" : void 0
		}, import_react.createElement(components.Chevron, {
			disabled: nextMonth ? void 0 : true,
			className: classNames[UI.Chevron],
			style: styles?.[UI.Chevron],
			orientation: props.dir === "rtl" ? "left" : "right"
		})), displayIndex === numberOfMonths - 1 && navLayout === "after" && !props.hideNavigation && import_react.createElement(components.Nav, {
			"data-animated-nav": props.animate ? "true" : void 0,
			className: classNames[UI.Nav],
			style: styles?.[UI.Nav],
			"aria-label": labelNav(),
			onPreviousClick: handlePreviousClick,
			onNextClick: handleNextClick,
			previousMonth,
			nextMonth
		}), import_react.createElement(components.MonthGrid, {
			role: "grid",
			"aria-multiselectable": mode === "multiple" || mode === "range",
			"aria-label": labelGrid(calendarMonth.date, dateLib.options, dateLib) || void 0,
			className: classNames[UI.MonthGrid],
			style: styles?.[UI.MonthGrid]
		}, !props.hideWeekdays && import_react.createElement(components.Weekdays, {
			"data-animated-weekdays": props.animate ? "true" : void 0,
			className: classNames[UI.Weekdays],
			style: styles?.[UI.Weekdays]
		}, showWeekNumber && import_react.createElement(components.WeekNumberHeader, {
			"aria-label": labelWeekNumberHeader(dateLib.options),
			className: classNames[UI.WeekNumberHeader],
			style: styles?.[UI.WeekNumberHeader],
			scope: "col"
		}, formatWeekNumberHeader()), weekdays.map((weekday) => import_react.createElement(components.Weekday, {
			"aria-label": labelWeekday(weekday, dateLib.options, dateLib),
			className: classNames[UI.Weekday],
			key: String(weekday),
			style: styles?.[UI.Weekday],
			scope: "col"
		}, formatWeekdayName(weekday, dateLib.options, dateLib)))), import_react.createElement(components.Weeks, {
			"data-animated-weeks": props.animate ? "true" : void 0,
			className: classNames[UI.Weeks],
			style: styles?.[UI.Weeks]
		}, calendarMonth.weeks.map((week) => {
			return import_react.createElement(components.Week, {
				className: classNames[UI.Week],
				key: week.weekNumber,
				style: styles?.[UI.Week],
				week
			}, showWeekNumber && import_react.createElement(components.WeekNumber, {
				week,
				style: styles?.[UI.WeekNumber],
				"aria-label": labelWeekNumber(week.weekNumber, { locale }),
				className: classNames[UI.WeekNumber],
				scope: "row",
				role: "rowheader"
			}, formatWeekNumber(week.weekNumber, dateLib)), week.days.map((day) => {
				const { date } = day;
				const modifiers = getModifiers(day);
				modifiers[DayFlag.focused] = !modifiers.hidden && Boolean(focused?.isEqualTo(day));
				modifiers[SelectionState.selected] = isSelected?.(date) || modifiers.selected;
				if (isDateRange(selectedValue)) {
					const { from, to } = selectedValue;
					modifiers[SelectionState.range_start] = Boolean(from && to && dateLib.isSameDay(date, from));
					modifiers[SelectionState.range_end] = Boolean(from && to && dateLib.isSameDay(date, to));
					modifiers[SelectionState.range_middle] = rangeIncludesDate(selectedValue, date, true, dateLib);
				}
				const style = getStyleForModifiers(modifiers, styles, props.modifiersStyles);
				const className = getClassNamesForModifiers(modifiers, classNames, props.modifiersClassNames);
				const ariaLabel = !isInteractive && !modifiers.hidden ? labelGridcell(date, modifiers, dateLib.options, dateLib) : void 0;
				return import_react.createElement(components.Day, {
					key: `${day.isoDate}_${day.displayMonthId}`,
					day,
					modifiers,
					className: className.join(" "),
					style,
					role: "gridcell",
					"aria-selected": modifiers.selected || void 0,
					"aria-label": ariaLabel,
					"data-day": day.isoDate,
					"data-month": day.outside ? day.dateMonthId : void 0,
					"data-selected": modifiers.selected || void 0,
					"data-disabled": modifiers.disabled || void 0,
					"data-hidden": modifiers.hidden || void 0,
					"data-outside": day.outside || void 0,
					"data-focused": modifiers.focused || void 0,
					"data-today": modifiers.today || void 0
				}, !modifiers.hidden && isInteractive ? import_react.createElement(components.DayButton, {
					className: classNames[UI.DayButton],
					style: styles?.[UI.DayButton],
					type: "button",
					day,
					modifiers,
					disabled: !modifiers.focused && modifiers.disabled || void 0,
					"aria-disabled": modifiers.focused && modifiers.disabled || void 0,
					tabIndex: isFocusTarget(day) ? 0 : -1,
					"aria-label": labelDayButton(date, modifiers, dateLib.options, dateLib),
					onClick: handleDayClick(day, modifiers),
					onBlur: handleDayBlur(day, modifiers),
					onFocus: handleDayFocus(day, modifiers),
					onKeyDown: handleDayKeyDown(day, modifiers),
					onMouseEnter: handleDayMouseEnter(day, modifiers),
					onMouseLeave: handleDayMouseLeave(day, modifiers)
				}, formatDay(date, dateLib.options, dateLib)) : !modifiers.hidden && formatDay(day.date, dateLib.options, dateLib));
			}));
		}))));
	})), props.footer && import_react.createElement(components.Footer, {
		className: classNames[UI.Footer],
		style: styles?.[UI.Footer],
		role: "status",
		"aria-live": "polite"
	}, props.footer)));
}
//#endregion
//#region ../../packages/ui-primitives/dist/Calendar.js
var calendarClassNames = {
	root: cn(surface({
		tone: "surface",
		radius: "lg"
	}), "p-3"),
	month_caption: "flex items-center justify-center text-fg",
	nav: "flex items-center gap-1",
	button_previous: cn(surface({
		tone: "surface",
		radius: "md"
	}), "inline-flex h-[var(--mod-touch-min)] w-[var(--mod-touch-min)] items-center justify-center border border-border hover:bg-[var(--mod-color-accent-a3)] active:bg-[var(--mod-color-accent-a4)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]"),
	button_next: cn(surface({
		tone: "surface",
		radius: "md"
	}), "inline-flex h-[var(--mod-touch-min)] w-[var(--mod-touch-min)] items-center justify-center border border-border hover:bg-[var(--mod-color-accent-a3)] active:bg-[var(--mod-color-accent-a4)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]"),
	month_grid: "w-full border-collapse",
	weekdays: "text-fg-muted",
	weekday: "text-center text-sm font-normal",
	week: "",
	day: "p-0 text-center",
	day_button: cn("inline-flex h-[var(--mod-touch-min)] w-[var(--mod-touch-min)] items-center justify-center rounded-md text-sm text-fg hover:bg-[var(--mod-color-accent-4)] hover:text-[var(--mod-color-accent-contrast)] active:bg-[var(--mod-color-accent-5)] active:text-[var(--mod-color-accent-contrast)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]"),
	selected: "bg-[var(--mod-color-accent-9)] text-[var(--mod-color-accent-contrast)] hover:bg-[var(--mod-color-accent-10)] hover:text-[var(--mod-color-accent-contrast)] active:bg-[var(--mod-color-accent-11)]",
	today: "border border-border",
	outside: "text-fg-muted opacity-50",
	disabled: "text-fg-muted opacity-[var(--mod-opacity-disabled)]"
};
function Calendar({ selected, onSelect, mode = "single", month, onMonthChange }) {
	if (mode === "multiple") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DayPicker, {
		mode: "multiple",
		selected,
		month,
		onMonthChange,
		onSelect: (dates) => onSelect?.(dates?.[dates.length - 1]),
		classNames: calendarClassNames,
		showOutsideDays: true
	});
	if (mode === "range") {
		const range = selected;
		return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DayPicker, {
			mode: "range",
			selected: range ? {
				from: range.from,
				to: range.to
			} : void 0,
			month,
			onMonthChange,
			onSelect: (r) => onSelect?.(r?.to ?? r?.from),
			classNames: calendarClassNames,
			showOutsideDays: true
		});
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DayPicker, {
		mode: "single",
		selected,
		month,
		onMonthChange,
		onSelect: (date) => onSelect?.(date),
		classNames: calendarClassNames,
		showOutsideDays: true
	});
}
//#endregion
//#region ../../packages/ui-primitives/dist/PalettePicker.js
function PalettePicker({ value, onChange, options, className, ...aria }) {
	if (options.length === 0) return null;
	const selected = options.find((o) => o.id === value) ?? options[0];
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		className: cn("@container", className),
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
			className: "flex flex-col gap-4 @md:flex-row @md:items-start",
			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroup, {
				value,
				onValueChange: onChange,
				className: "flex flex-col gap-2",
				...aria,
				children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
					className: "flex cursor-pointer items-center gap-3 text-sm text-fg",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Radio, {
							value: option.id,
							"aria-label": option.label
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							className: "flex flex-row flex-wrap gap-1",
							"aria-hidden": true,
							children: option.swatches.map((color, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
								className: "h-4 w-4 shrink-0 rounded-full border border-border bg-[var(--swatch)]",
								style: { ["--swatch"]: color }
							}, i))
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: option.label })
					]
				}, option.id))
			}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				"data-testid": "palette-preview",
				"aria-hidden": true,
				className: "flex w-full flex-col gap-2 rounded-md border bg-[var(--pp-bg)] p-4 text-[var(--pp-fg)] @md:flex-1 @md:min-w-0",
				style: {
					["--pp-bg"]: selected.preview.bg,
					["--pp-surface"]: selected.preview.surface,
					["--pp-fg"]: selected.preview.fg,
					["--pp-fg-muted"]: selected.preview.fgMuted,
					["--pp-accent"]: selected.preview.accent,
					["--pp-accent-fg"]: selected.preview.accentFg,
					["--pp-border"]: selected.preview.border,
					borderColor: "var(--pp-border)"
				},
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
						className: "text-sm font-medium text-[var(--pp-fg)]",
						children: selected.label
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
						className: "text-xs text-[var(--pp-fg-muted)]",
						children: "The quick brown fox jumps over the lazy dog."
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
						className: "flex flex-col items-start gap-2 rounded-sm bg-[var(--pp-surface)] p-2 text-xs text-[var(--pp-fg)]",
						children: ["Surface block", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							className: "inline-flex w-fit rounded-sm bg-[var(--pp-accent)] px-3 py-1 text-xs text-[var(--pp-accent-fg)]",
							children: "Primary action"
						})]
					})
				]
			})]
		})
	});
}
//#endregion
//#region ../../packages/auth-react/dist/index.js
var AuthProviderError = class extends Error {
	name = "AuthProviderError";
	constructor(hook) {
		super(`${hook} must be used within <AuthProvider>`);
	}
};
var AuthContext = (0, import_react.createContext)(null);
function useAuthContext(hook) {
	const ctx = (0, import_react.useContext)(AuthContext);
	if (!ctx) throw new AuthProviderError(hook);
	return ctx;
}
/** Holds the current Principal snapshot and refreshes it on mount. */
function AuthProvider({ client, children }) {
	const [user, setUser] = (0, import_react.useState)(null);
	const [loading, setLoading] = (0, import_react.useState)(true);
	const [error, setError] = (0, import_react.useState)(null);
	const [reloadToken, setReloadToken] = (0, import_react.useState)(0);
	const clientRef = (0, import_react.useRef)(client);
	clientRef.current = client;
	const reload = (0, import_react.useCallback)(() => {
		setReloadToken((t) => t + 1);
	}, []);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		setLoading(true);
		setError(null);
		clientRef.current.getCurrentUser().then((principal) => {
			if (!cancelled) {
				setUser(principal);
				setLoading(false);
			}
		}).catch((e) => {
			if (!cancelled) {
				setError(e instanceof Error ? e : new Error(String(e)));
				setLoading(false);
			}
		});
		return () => {
			cancelled = true;
		};
	}, [reloadToken]);
	const value = (0, import_react.useMemo)(() => ({
		client,
		user,
		loading,
		error,
		reload,
		setUser
	}), [
		client,
		user,
		loading,
		error,
		reload
	]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthContext.Provider, {
		value,
		children
	});
}
function useCurrentUser() {
	const { user, loading, error, reload } = useAuthContext("useCurrentUser");
	return {
		user,
		loading,
		error,
		reload
	};
}
function useSignIn() {
	const { client, setUser } = useAuthContext("useSignIn");
	const [pending, setPending] = (0, import_react.useState)(false);
	const [error, setError] = (0, import_react.useState)(null);
	const clientRef = (0, import_react.useRef)(client);
	clientRef.current = client;
	return {
		signIn: (0, import_react.useCallback)(async (creds) => {
			setPending(true);
			setError(null);
			try {
				const principal = await clientRef.current.signIn(creds);
				setUser(principal);
				setPending(false);
				return principal;
			} catch (e) {
				const err = e instanceof Error ? e : new Error(String(e));
				setError(err);
				setPending(false);
				throw err;
			}
		}, [setUser]),
		pending,
		error
	};
}
function useSignOut() {
	const { client, setUser } = useAuthContext("useSignOut");
	const [pending, setPending] = (0, import_react.useState)(false);
	const [error, setError] = (0, import_react.useState)(null);
	const clientRef = (0, import_react.useRef)(client);
	clientRef.current = client;
	return {
		signOut: (0, import_react.useCallback)(async () => {
			setPending(true);
			setError(null);
			try {
				await clientRef.current.signOut();
				setUser(null);
				setPending(false);
			} catch (e) {
				const err = e instanceof Error ? e : new Error(String(e));
				setError(err);
				setPending(false);
				throw err;
			}
		}, [setUser]),
		pending,
		error
	};
}
//#endregion
//#region src/lib/clients.ts
var AdminApiError = class extends Error {
	status;
	code;
	field;
	name = "AdminApiError";
	constructor(status, code, message, field) {
		super(message);
		this.status = status;
		this.code = code;
		this.field = field;
	}
};
function isAdminApiError(value) {
	return typeof value === "object" && value !== null && value.name === "AdminApiError" && Number.isInteger(value.status) && typeof value.code === "string" && typeof value.message === "string" && (value.field === void 0 || typeof value.field === "string");
}
async function apiFetch(url, init) {
	const headers = new Headers(init?.headers);
	if (init?.body != null && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
	const res = await fetch(url, {
		...init,
		credentials: "same-origin",
		headers
	});
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const err = body;
		throw new AdminApiError(res.status, err?.error?.code ?? `http_${res.status}`, err?.error?.message ?? res.statusText, err?.error?.field);
	}
	return body;
}
function listQueryString(query) {
	if (!query) return "";
	const params = new URLSearchParams();
	if (query.status) params.set("status", query.status);
	if (query.type) params.set("type", query.type);
	if (query.limit != null) params.set("limit", String(query.limit));
	if (query.offset != null) params.set("offset", String(query.offset));
	const qs = params.toString();
	return qs ? `?${qs}` : "";
}
function makeAuthClient() {
	return {
		async getCurrentUser() {
			return apiFetch("/api/admin/me");
		},
		async signIn(creds) {
			return apiFetch("/api/admin/session", {
				method: "POST",
				body: JSON.stringify(creds)
			});
		},
		async signOut() {
			await apiFetch("/api/admin/session", { method: "DELETE" });
		},
		async signUp() {
			throw new Error("not supported");
		},
		async requestPasswordReset() {
			throw new Error("not supported");
		},
		async resetPassword() {
			throw new Error("not supported");
		}
	};
}
function makeContentClient() {
	return {
		async list(query) {
			return (await apiFetch(`/api/admin/content${listQueryString(query)}`)).entries;
		},
		async put(input) {
			return apiFetch("/api/admin/content", {
				method: "POST",
				body: JSON.stringify(input)
			});
		},
		async trash(id) {
			return apiFetch("/api/admin/trash", {
				method: "POST",
				body: JSON.stringify({ id })
			});
		},
		async restore(id) {
			return apiFetch("/api/admin/restore", {
				method: "POST",
				body: JSON.stringify({ id })
			});
		},
		async remove(id) {
			return apiFetch("/api/admin/remove", {
				method: "DELETE",
				body: JSON.stringify({ id })
			});
		},
		async publish(id) {
			return apiFetch("/api/admin/publish", {
				method: "POST",
				body: JSON.stringify({ id })
			});
		},
		async unpublish(id) {
			return apiFetch("/api/admin/unpublish", {
				method: "POST",
				body: JSON.stringify({ id })
			});
		},
		async schedule(id, at) {
			return apiFetch("/api/admin/schedule", {
				method: "POST",
				body: JSON.stringify({
					id,
					at
				})
			});
		},
		async setVisibility(id, visibility) {
			return apiFetch("/api/admin/visibility", {
				method: "POST",
				body: JSON.stringify({
					id,
					visibility
				})
			});
		},
		async translate(id) {
			return apiFetch("/api/admin/translate", {
				method: "POST",
				body: JSON.stringify({ id })
			});
		},
		async getBySlug(_type, _slug) {
			throw new Error("getBySlug is not supported in the admin client");
		}
	};
}
//#endregion
//#region src/lib/notification-client.ts
function parseError(body, statusText) {
	const message = body?.error?.message ?? statusText;
	return new Error(message);
}
/** Host NotificationClient — session-scoped inbox routes (never passes userId). */
function makeNotificationClient() {
	return {
		async list(opts) {
			const params = new URLSearchParams();
			if (opts?.cursor) params.set("cursor", opts.cursor);
			if (opts?.limit != null) params.set("limit", String(opts.limit));
			if (opts?.unreadOnly) params.set("unreadOnly", "true");
			const qs = params.toString();
			const res = await fetch(`/api/admin/notifications${qs ? `?${qs}` : ""}`, { credentials: "same-origin" });
			const body = await res.json().catch(() => null);
			if (!res.ok) throw parseError(body, res.statusText);
			const page = body;
			return {
				items: page.items,
				...page.nextCursor ? { nextCursor: page.nextCursor } : {}
			};
		},
		async unreadCount() {
			const res = await fetch("/api/admin/notifications/unread-count", { credentials: "same-origin" });
			const body = await res.json().catch(() => null);
			if (!res.ok) throw parseError(body, res.statusText);
			return body.count;
		},
		async markRead(ids) {
			const res = await fetch("/api/admin/notifications/read", {
				method: "POST",
				credentials: "same-origin",
				headers: {
					"content-type": "application/json",
					origin: window.location.origin
				},
				body: JSON.stringify({ ids })
			});
			const body = await res.json().catch(() => null);
			if (!res.ok) throw parseError(body, res.statusText);
		}
	};
}
//#endregion
//#region ../../packages/notifications-react/dist/index.js
function toError$3(e) {
	return e instanceof Error ? e : new Error(String(e));
}
function useNotifications(client, opts) {
	const [items, setItems] = (0, import_react.useState)([]);
	const [unread, setUnread] = (0, import_react.useState)(0);
	const [loading, setLoading] = (0, import_react.useState)(true);
	const [error, setError] = (0, import_react.useState)(null);
	const [hasMore, setHasMore] = (0, import_react.useState)(false);
	const [reloadToken, setReloadToken] = (0, import_react.useState)(0);
	const clientRef = (0, import_react.useRef)(client);
	clientRef.current = client;
	const nextCursorRef = (0, import_react.useRef)(void 0);
	const reload = (0, import_react.useCallback)(() => {
		setReloadToken((t) => t + 1);
	}, []);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		setLoading(true);
		setError(null);
		nextCursorRef.current = void 0;
		Promise.all([clientRef.current.list(), clientRef.current.unreadCount()]).then(([page, count]) => {
			if (!cancelled) {
				setItems(page.items);
				nextCursorRef.current = page.nextCursor;
				setHasMore(Boolean(page.nextCursor));
				setUnread(count);
				setLoading(false);
			}
		}).catch((e) => {
			if (!cancelled) {
				setError(toError$3(e));
				setLoading(false);
			}
		});
		return () => {
			cancelled = true;
		};
	}, [reloadToken]);
	const loadMore = (0, import_react.useCallback)(async () => {
		const cursor = nextCursorRef.current;
		if (!cursor) return;
		try {
			const page = await clientRef.current.list({ cursor });
			nextCursorRef.current = page.nextCursor;
			setHasMore(Boolean(page.nextCursor));
			setItems((prev) => [...prev, ...page.items]);
		} catch (e) {
			setError(toError$3(e));
		}
	}, []);
	const markRead = (0, import_react.useCallback)(async (ids) => {
		const snapshot = {
			items,
			unread
		};
		if (ids === "all") {
			const now = (/* @__PURE__ */ new Date()).toISOString();
			setItems((prev) => prev.map((item) => ({
				...item,
				readAt: item.readAt ?? now
			})));
			setUnread(0);
		} else {
			const now = (/* @__PURE__ */ new Date()).toISOString();
			let newlyRead = 0;
			setItems((prev) => prev.map((item) => {
				if (ids.includes(item.id) && !item.readAt) {
					newlyRead++;
					return {
						...item,
						readAt: now
					};
				}
				return item;
			}));
			setUnread((u) => Math.max(0, u - newlyRead));
		}
		try {
			await clientRef.current.markRead(ids);
		} catch (e) {
			setItems(snapshot.items);
			setUnread(snapshot.unread);
			const err = toError$3(e);
			setError(err);
			throw err;
		}
	}, [items, unread]);
	(0, import_react.useEffect)(() => {
		const pollMs = opts?.pollMs;
		if (!pollMs) return;
		let cancelled = false;
		const id = setInterval(() => {
			clientRef.current.unreadCount().then((count) => {
				if (!cancelled) setUnread(count);
			}).catch((e) => {
				if (!cancelled) setError(toError$3(e));
			});
		}, pollMs);
		return () => {
			cancelled = true;
			clearInterval(id);
		};
	}, [opts?.pollMs]);
	return {
		items,
		unread,
		loading,
		error,
		hasMore,
		loadMore,
		markRead,
		reload
	};
}
function NotificationBell({ client, onOpen }) {
	const { unread } = useNotifications(client);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
		type: "button",
		"aria-label": `${unread} unread notifications`,
		onClick: onOpen,
		children: ["Notifications", unread > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, { children: unread }) : null]
	});
}
//#endregion
//#region src/components/admin/LoginScreen.tsx
function LoginScreen() {
	const emailId = (0, import_react.useId)();
	const passwordId = (0, import_react.useId)();
	const { signIn, pending, error } = useSignIn();
	const [email, setEmail] = (0, import_react.useState)("");
	const [password, setPassword] = (0, import_react.useState)("");
	async function onSubmit(event) {
		event.preventDefault();
		try {
			await signIn({
				email,
				password
			});
			if (typeof window !== "undefined" && window.location.pathname === "/admin/login") window.location.assign("/admin");
		} catch {}
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", {
		className: "admin-login admin-grid",
		"aria-labelledby": "admin-login-heading",
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
			className: "admin-grid__main admin-login__panel",
			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "admin-login__intro",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
					id: "admin-login-heading",
					className: "admin-display text-2xl text-fg",
					children: "Sign in"
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
					className: "text-sm text-fg-muted",
					children: "Use your admin credentials to open the dashboard."
				})]
			}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
				className: "admin-login__form",
				onSubmit,
				noValidate: true,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Email",
						htmlFor: emailId,
						required: true,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							id: emailId,
							name: "email",
							type: "email",
							autoComplete: "email",
							required: true,
							value: email,
							onChange: (event) => setEmail(event.target.value)
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Password",
						htmlFor: passwordId,
						required: true,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							id: passwordId,
							name: "password",
							type: "password",
							autoComplete: "current-password",
							required: true,
							value: password,
							onChange: (event) => setPassword(event.target.value)
						})
					}),
					error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "admin-login__error",
						role: "alert",
						children: error.message
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "accent",
						radius: "sm",
						size: "base",
						type: "submit",
						disabled: pending,
						children: "Sign in"
					})
				]
			})]
		})
	});
}
//#endregion
//#region src/components/admin/ScreenHeader.tsx
function ScreenHeader({ title, description, actions, className, headingId }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: className ? `admin-screen__header ${className}` : "admin-screen__header",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
			id: headingId || void 0,
			className: "admin-display text-2xl text-fg",
			children: title
		}), description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
			className: "text-sm text-fg-muted",
			children: description
		}) : null] }), actions ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: actions }) : null]
	});
}
//#endregion
//#region src/components/admin/ContentListScreen.tsx
function statusTone$3(status) {
	if (status === "published") return "success";
	if (status === "scheduled") return "warning";
	return "neutral";
}
function translationTone(status) {
	if (status === "complete") return "success";
	if (status === "stale" || status === "partial") return "warning";
	if (status === "failed") return "danger";
	return "neutral";
}
function translationBadges(entry) {
	const locales = Object.entries(entry.translationStatusByLocale ?? {});
	if (locales.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
		className: "text-sm text-fg-muted",
		children: "Default only"
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		className: "flex flex-wrap gap-2",
		children: locales.map(([locale, status]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Badge, {
			tone: translationTone(status),
			children: [
				locale,
				" ",
				status
			]
		}, locale))
	});
}
function ContentListScreen() {
	const client = (0, import_react.useMemo)(() => makeContentClient(), []);
	const { entries, loading, error, reload } = useContentList(client);
	const { toast } = useToast();
	const [trashingId, setTrashingId] = (0, import_react.useState)(null);
	const [translatingId, setTranslatingId] = (0, import_react.useState)(null);
	async function trashEntry(id) {
		setTrashingId(id);
		try {
			await client.trash(id);
			toast({
				title: "Entry moved to trash",
				tone: "success"
			});
			reload();
		} catch (e) {
			toast({
				title: e instanceof Error ? e.message : "Could not move the entry to trash.",
				tone: "danger"
			});
		} finally {
			setTrashingId(null);
		}
	}
	async function translateEntry(id) {
		setTranslatingId(id);
		try {
			await client.translate(id);
			toast({
				title: "Translations updated",
				tone: "success"
			});
			reload();
		} catch (e) {
			toast({
				title: e instanceof Error ? e.message : "Could not translate the entry.",
				tone: "danger"
			});
		} finally {
			setTranslatingId(null);
		}
	}
	const capabilities = (0, import_react.useMemo)(() => [
		withSorting(),
		withSearch({ label: "Search content" }),
		withPagination({ pageSize: 20 })
	], []);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "content-list-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "content-list-heading",
				title: "Content",
				description: "Posts and pages in the editorial queue.",
				actions: !error && !loading && entries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "base",
					asChild: true,
					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
						href: "/admin/content/new",
						children: "New post"
					})
				}) : null
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
				variant: "inline",
				title: "Content couldn't load",
				message: error.message,
				action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "sm",
					type: "button",
					onClick: () => window.location.reload(),
					children: "Try again"
				})
			}) : null,
			!error && !loading && entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "admin-empty",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "No posts yet." }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "base",
					asChild: true,
					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
						href: "/admin/content/new",
						children: "Write the first post"
					})
				})]
			}) : null,
			!error && (loading || entries.length > 0) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DataTable, {
				caption: "Content entries",
				columns: [
					{
						id: "title",
						header: "Title",
						sortable: true,
						sortValue: (entry) => entry.title,
						searchValue: (entry) => entry.title,
						cell: (entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
							className: "admin-table-link",
							href: `/admin/content/${entry.id}`,
							children: entry.title
						})
					},
					{
						id: "type",
						header: "Type",
						sortable: true,
						sortValue: (entry) => entry.type,
						searchValue: (entry) => entry.type,
						cell: (entry) => entry.type
					},
					{
						id: "status",
						header: "Status",
						sortable: true,
						sortValue: (entry) => entry.status,
						searchValue: (entry) => entry.status,
						cell: (entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
							tone: statusTone$3(entry.status),
							children: entry.status
						})
					},
					{
						id: "translations",
						header: "Translations",
						searchValue: () => "",
						cell: (entry) => translationBadges(entry)
					},
					{
						id: "actions",
						header: "Actions",
						searchValue: () => "",
						cell: (entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "flex flex-wrap gap-2",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "surface",
								radius: "sm",
								size: "sm",
								type: "button",
								disabled: translatingId === entry.id,
								onClick: () => void translateEntry(entry.id),
								children: translatingId === entry.id ? "Translating…" : "Translate"
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "surface",
								radius: "sm",
								size: "sm",
								type: "button",
								disabled: trashingId === entry.id,
								onClick: () => void trashEntry(entry.id),
								children: "Trash"
							})]
						})
					}
				],
				rows: entries,
				getRowId: (entry) => entry.id,
				capabilities,
				loading,
				emptyState: "No entries match the search."
			}) : null
		]
	});
}
//#endregion
//#region ../../packages/fields-react/dist/index.js
var FieldsContext = (0, import_react.createContext)(null);
function FieldsProvider({ client, children }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldsContext.Provider, {
		value: client,
		children
	});
}
function useFieldsClient() {
	const ctx = (0, import_react.useContext)(FieldsContext);
	if (!ctx) throw new Error("useFieldsClient must be used within <FieldsProvider>");
	return ctx;
}
function toError$2(e) {
	return e instanceof Error ? e : new Error(String(e));
}
function useFieldGroupBuilder(entityType, opts = {}) {
	const client = useFieldsClient();
	const [groups, setGroups] = (0, import_react.useState)([]);
	const [loading, setLoading] = (0, import_react.useState)(true);
	const [error, setError] = (0, import_react.useState)(null);
	const [reloadToken, setReloadToken] = (0, import_react.useState)(0);
	const clientRef = (0, import_react.useRef)(client);
	clientRef.current = client;
	const refresh = (0, import_react.useCallback)(async () => {
		const next = await clientRef.current.listGroups({
			entityType,
			subType: opts.subType
		});
		setGroups(next);
		return next;
	}, [entityType, opts.subType]);
	const reload = (0, import_react.useCallback)(() => {
		setReloadToken((t) => t + 1);
	}, []);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		setLoading(true);
		setError(null);
		clientRef.current.listGroups({
			entityType,
			subType: opts.subType
		}).then((next) => {
			if (!cancelled) {
				setGroups(next);
				setLoading(false);
			}
		}).catch((e) => {
			if (!cancelled) {
				setError(toError$2(e));
				setLoading(false);
			}
		});
		return () => {
			cancelled = true;
		};
	}, [
		entityType,
		opts.subType,
		reloadToken
	]);
	return {
		groups,
		loading,
		error,
		create: (0, import_react.useCallback)(async (group) => {
			await clientRef.current.createGroup(group);
			await refresh();
		}, [refresh]),
		update: (0, import_react.useCallback)(async (id, patch) => {
			await clientRef.current.updateGroup(id, patch);
			await refresh();
		}, [refresh]),
		remove: (0, import_react.useCallback)(async (id) => {
			await clientRef.current.deleteGroup(id);
			await refresh();
		}, [refresh]),
		reload
	};
}
function Shell({ children }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		style: { containerType: "inline-size" },
		children
	});
}
function TextInput({ field, value, onChange, disabled }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "text",
		"aria-label": field.label,
		value: typeof value === "string" ? value : "",
		disabled,
		onChange: (e) => onChange(e.target.value || void 0)
	}) });
}
function TextAreaInput({ field, value, onChange, disabled }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
		"aria-label": field.label,
		value: typeof value === "string" ? value : "",
		disabled,
		onChange: (e) => onChange(e.target.value || void 0)
	}) });
}
function NumberInput({ field, value, onChange, disabled }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "number",
		"aria-label": field.label,
		value: typeof value === "number" ? value : "",
		disabled,
		onChange: (e) => {
			const raw = e.target.value;
			onChange(raw === "" ? void 0 : Number(raw));
		}
	}) });
}
function BooleanInput({ field, value, onChange, disabled }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "checkbox",
		"aria-label": field.label,
		checked: value === true,
		disabled,
		onChange: (e) => onChange(e.target.checked)
	}) });
}
function SelectInput({ field, value, onChange, disabled }) {
	const options = field.type === "select" ? field.options : [];
	const multiple = field.type === "select" && field.multiple === true;
	const selected = multiple ? Array.isArray(value) ? value.map(String) : [] : typeof value === "string" ? value : "";
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
		"aria-label": field.label,
		multiple,
		disabled,
		value: selected,
		onChange: (e) => {
			if (multiple) onChange(Array.from(e.target.selectedOptions, (o) => o.value));
			else onChange(e.target.value || void 0);
		},
		children: [!multiple ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
			value: "",
			children: "—"
		}) : null, options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
			value: o.value,
			children: o.label
		}, o.value))]
	}) });
}
function DateInput({ field, value, onChange, disabled }) {
	const str = value instanceof Date ? value.toISOString().slice(0, 10) : typeof value === "string" ? value : "";
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "date",
		"aria-label": field.label,
		value: str,
		disabled,
		onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : void 0)
	}) });
}
function ColorInput({ field, value, onChange, disabled }) {
	const hex = typeof value === "string" && value.startsWith("#") ? value.slice(0, 7) : "#000000";
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "color",
		"aria-label": field.label,
		value: hex,
		disabled,
		onChange: (e) => onChange(e.target.value)
	}) });
}
function UrlInput({ field, value, onChange, disabled }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "url",
		"aria-label": field.label,
		value: typeof value === "string" ? value : "",
		disabled,
		onChange: (e) => onChange(e.target.value || void 0)
	}) });
}
function EmailInput({ field, value, onChange, disabled }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "email",
		"aria-label": field.label,
		value: typeof value === "string" ? value : "",
		disabled,
		onChange: (e) => onChange(e.target.value || void 0)
	}) });
}
function MediaInput({ field, value, onChange, disabled }) {
	const media = !Array.isArray(value) && value && typeof value === "object" && "key" in value ? value : void 0;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "text",
		"aria-label": field.label,
		placeholder: "media key",
		value: media?.key ?? "",
		disabled,
		onChange: (e) => {
			const key = e.target.value;
			onChange(key ? {
				key,
				url: media?.url,
				mime: media?.mime,
				meta: media?.meta
			} : void 0);
		}
	}) });
}
function RelationshipInput({ field, value, onChange, disabled }) {
	const rel = !Array.isArray(value) && value && typeof value === "object" && "entityType" in value ? value : void 0;
	const emit = (entityType, entityId) => onChange(entityType || entityId ? {
		entityType,
		entityId
	} : void 0);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Shell, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "text",
		"aria-label": `${field.label} entity type`,
		placeholder: "entityType",
		value: rel?.entityType ?? "",
		disabled,
		onChange: (e) => emit(e.target.value, rel?.entityId ?? "")
	}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
		type: "text",
		"aria-label": `${field.label} entity id`,
		placeholder: "entityId",
		value: rel?.entityId ?? "",
		disabled,
		onChange: (e) => emit(rel?.entityType ?? "", e.target.value)
	})] });
}
var referenceInputs = {
	text: TextInput,
	textarea: TextAreaInput,
	number: NumberInput,
	boolean: BooleanInput,
	select: SelectInput,
	date: DateInput,
	color: ColorInput,
	url: UrlInput,
	email: EmailInput,
	media: MediaInput,
	relationship: RelationshipInput
};
function groupIdOf$1(group) {
	return group.id ?? group.key;
}
function seedValuesByGroup(groups, initialValues) {
	const seeded = {};
	for (const group of groups) {
		const id = groupIdOf$1(group);
		seeded[id] = { ...initialValues?.[id] ?? {} };
	}
	return seeded;
}
function FieldValuesForm({ groups, initialValues, onSubmit, disabled, errors }) {
	const [valuesByGroup, setValuesByGroup] = (0, import_react.useState)(() => seedValuesByGroup(groups, initialValues));
	const setFieldValue = (0, import_react.useCallback)((groupId, key, value) => {
		setValuesByGroup((prev) => ({
			...prev,
			[groupId]: {
				...prev[groupId],
				[key]: value
			}
		}));
	}, []);
	const handleSubmit = (0, import_react.useCallback)((e) => {
		e.preventDefault();
		onSubmit(groups.map((group) => {
			const groupId = groupIdOf$1(group);
			return {
				groupId,
				values: valuesByGroup[groupId] ?? {}
			};
		}));
	}, [
		onSubmit,
		valuesByGroup,
		groups
	]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		className: "fields-values-form",
		style: { containerType: "inline-size" },
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
			onSubmit: handleSubmit,
			children: [groups.map((group) => {
				const groupId = groupIdOf$1(group);
				const groupValues = valuesByGroup[groupId] ?? {};
				return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
					disabled,
					className: "fields-values-form__group",
					children: [group.label ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", {
						className: "fields-values-form__legend",
						children: group.label
					}) : null, group.fields.map((field) => {
						const Input = referenceInputs[field.type];
						const fieldError = errors?.[groupId]?.[field.key];
						return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "fields-values-form__field",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								field,
								value: groupValues[field.key],
								onChange: (v) => setFieldValue(groupId, field.key, v),
								error: fieldError,
								disabled
							}), fieldError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
								role: "alert",
								tabIndex: 0,
								className: "fields-values-form__error",
								children: fieldError
							}) : null]
						}, field.key);
					})]
				}, groupId);
			}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "submit",
				disabled,
				className: "fields-values-form__submit",
				children: "Save fields"
			})]
		})
	});
}
function defaultField$1() {
	return {
		key: "new_field",
		type: "text",
		label: "New field"
	};
}
function isValidKey(key) {
	return FIELD_KEY_RE.test(key);
}
function withTypeDefaults(field, type) {
	const base = {
		...field,
		type
	};
	if (type === "select" && field.type !== "select") return {
		...base,
		type: "select",
		options: [{
			value: "option_a",
			label: "Option A"
		}]
	};
	if (type === "relationship" && field.type !== "relationship") return {
		...base,
		type: "relationship",
		targetEntityType: "content"
	};
	return base;
}
function GroupEditorSection({ groupId, draft, onDraftChange, onSave, saving }) {
	const hasInvalidKeys = draft.fields.filter((f) => !isValidKey(f.key)).length > 0;
	const updateField = (0, import_react.useCallback)((index, patch) => {
		const fields = draft.fields.map((f, i) => i === index ? {
			...f,
			...patch
		} : f);
		onDraftChange({
			...draft,
			fields
		});
	}, [draft, onDraftChange]);
	const setFieldType = (0, import_react.useCallback)((index, type) => {
		const fields = draft.fields.map((f, i) => i === index ? withTypeDefaults(f, type) : f);
		onDraftChange({
			...draft,
			fields
		});
	}, [draft, onDraftChange]);
	const moveField = (0, import_react.useCallback)((index, direction) => {
		const target = index + direction;
		if (target < 0 || target >= draft.fields.length) return;
		const fields = [...draft.fields];
		const tmp = fields[index];
		fields[index] = fields[target];
		fields[target] = tmp;
		onDraftChange({
			...draft,
			fields
		});
	}, [draft, onDraftChange]);
	const removeField = (0, import_react.useCallback)((index) => {
		onDraftChange({
			...draft,
			fields: draft.fields.filter((_, i) => i !== index)
		});
	}, [draft, onDraftChange]);
	const addField = (0, import_react.useCallback)(() => {
		onDraftChange({
			...draft,
			fields: [...draft.fields, defaultField$1()]
		});
	}, [draft, onDraftChange]);
	const updateSelectOption = (0, import_react.useCallback)((fieldIndex, optionIndex, patch) => {
		const field = draft.fields[fieldIndex];
		if (!field || field.type !== "select") return;
		const options = field.options.map((o, i) => i === optionIndex ? {
			...o,
			...patch
		} : o);
		updateField(fieldIndex, {
			type: "select",
			options
		});
	}, [draft.fields, updateField]);
	const addSelectOption = (0, import_react.useCallback)((fieldIndex) => {
		const field = draft.fields[fieldIndex];
		if (!field || field.type !== "select") return;
		const n = field.options.length + 1;
		updateField(fieldIndex, {
			type: "select",
			options: [...field.options, {
				value: `option_${n}`,
				label: `Option ${n}`
			}]
		});
	}, [draft.fields, updateField]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "fields-group-editor__group",
		"aria-label": draft.label,
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
				className: "fields-group-editor__heading",
				children: draft.label
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
				className: "fields-group-editor__fields",
				children: draft.fields.map((field, index) => {
					const isNewRow = field.key === "new_field" && field.label === "New field";
					const keyInvalid = !isValidKey(field.key);
					return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
						className: "fields-group-editor__row",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								type: "text",
								"aria-label": field.label,
								value: field.label,
								className: "fields-group-editor__label",
								onChange: (e) => updateField(index, { label: e.target.value })
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								type: "text",
								id: `field-key-${field.key}`,
								"aria-label": "Field key",
								value: field.key,
								className: "fields-group-editor__key",
								onChange: (e) => updateField(index, { key: e.target.value })
							}),
							keyInvalid ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
								role: "alert",
								tabIndex: 0,
								className: "fields-group-editor__key-error",
								children: "Invalid field key — use lowercase letters, digits, and underscores; must start with a letter."
							}) : null,
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "fields-group-editor__required",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
									type: "checkbox",
									"aria-label": `${field.label} required`,
									checked: field.required === true,
									onChange: (e) => updateField(index, { required: e.target.checked || void 0 })
								}), "Required"]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
								name: isNewRow ? "field-type-new" : `field-type-${field.key}`,
								"aria-label": "Field type",
								value: field.type,
								className: "fields-group-editor__type",
								onChange: (e) => setFieldType(index, e.target.value),
								children: FIELD_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: t,
									children: t
								}, t))
							}),
							field.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
								className: "fields-group-editor__options",
								children: [field.options.map((opt, optIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
									className: "fields-group-editor__option",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
										type: "text",
										"aria-label": `${field.label} option value`,
										value: opt.value,
										onChange: (e) => updateSelectOption(index, optIndex, { value: e.target.value })
									}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
										type: "text",
										"aria-label": `${field.label} option label`,
										value: opt.label,
										onChange: (e) => updateSelectOption(index, optIndex, { label: e.target.value })
									})]
								}, optIndex)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
									type: "button",
									onClick: () => addSelectOption(index),
									children: "Add option"
								})]
							}) : null,
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
								type: "button",
								"aria-label": `Move ${field.label} up`,
								"aria-disabled": index === 0,
								onClick: () => moveField(index, -1),
								children: "Move up"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
								type: "button",
								"aria-label": `Move ${field.label} down`,
								"aria-disabled": index === draft.fields.length - 1,
								onClick: () => moveField(index, 1),
								children: "Move down"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
								type: "button",
								"aria-label": `Remove ${field.label}`,
								onClick: () => removeField(index),
								children: "Remove field"
							})
						]
					}, `${groupId ?? "new"}-${index}`);
				})
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				className: "fields-group-editor__add-field",
				onClick: addField,
				children: "Add field"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				className: "fields-group-editor__save",
				disabled: hasInvalidKeys || saving,
				onClick: onSave,
				children: "Save group"
			})
		]
	});
}
function FieldGroupEditor({ entityType, subType }) {
	const { groups, loading, error, create, update } = useFieldGroupBuilder(entityType, { subType });
	const [drafts, setDrafts] = (0, import_react.useState)({});
	const [saving, setSaving] = (0, import_react.useState)(false);
	(0, import_react.useEffect)(() => {
		if (loading) return;
		setDrafts((prev) => {
			const next = { ...prev };
			for (const g of groups) {
				const id = g.id ?? g.key;
				if (!next[id]) next[id] = {
					key: g.key,
					label: g.label,
					location: g.location,
					fields: g.fields.map((f) => ({ ...f }))
				};
			}
			return next;
		});
	}, [groups, loading]);
	const handleSave = (0, import_react.useCallback)(async (groupId, draft) => {
		setSaving(true);
		try {
			const payload = {
				key: draft.key,
				label: draft.label,
				location: draft.location,
				fields: draft.fields
			};
			if (groupId) await update(groupId, payload);
			else await create(payload);
		} finally {
			setSaving(false);
		}
	}, [create, update]);
	const body = (0, import_react.useMemo)(() => {
		if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
			className: "fields-group-editor__loading",
			children: "Loading groups…"
		});
		if (groups.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
			className: "fields-group-editor__empty",
			children: "No field groups."
		});
		return groups.map((g) => {
			const id = g.id ?? g.key;
			const draft = drafts[id];
			if (!draft) return null;
			return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GroupEditorSection, {
				groupId: g.id,
				draft,
				saving,
				onDraftChange: (next) => setDrafts((prev) => ({
					...prev,
					[id]: next
				})),
				onSave: () => {
					const current = drafts[id];
					if (current) handleSave(g.id, current);
				}
			}, id);
		});
	}, [
		drafts,
		groups,
		handleSave,
		loading,
		saving
	]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "fields-group-editor",
		style: { containerType: "inline-size" },
		children: [error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			role: "alert",
			tabIndex: 0,
			className: "fields-group-editor__error",
			children: error.message
		}) : null, body]
	});
}
createFieldTypeRegistry().builtInTypes;
var COMPLETE_FIELD_TYPES = Object.freeze([...createFieldTypeRegistry().builtInTypes]);
function defaultSettings(type) {
	if (type === "textarea") return { newline: "preserve" };
	if (type === "url" || type === "link") return { schemes: [] };
	if (type === "password") return { hasherKey: "" };
	if ([
		"select",
		"checkbox",
		"radio",
		"buttonGroup"
	].includes(type)) return { choices: {} };
	if (type === "image" || type === "file" || type === "gallery") return { return: "ref" };
	if (type === "entity" || type === "entityLink" || type === "relationship") return { return: "ref" };
	if (type === "taxonomy") return {
		taxonomies: [],
		return: "ref"
	};
	if (type === "user") return { return: "ref" };
	if (type === "date") return {
		inputFormat: "",
		displayFormat: "",
		returnFormat: ""
	};
	if (type === "dateTime") return {
		inputFormat: "",
		displayFormat: "",
		returnFormat: "",
		timezone: "utc"
	};
	if (type === "time") return {
		inputFormat: "",
		displayFormat: "",
		returnFormat: ""
	};
	if (type === "map") return { providerKey: "" };
	if (type === "group" || type === "repeater") return { fields: [] };
	if (type === "flexible") return { layouts: [] };
	if (type === "clone") return { sourceFieldKeys: [] };
	return {};
}
function defaultField(index = 0) {
	const suffix = index + 1;
	return {
		key: `field_${suffix}`,
		name: `field_${suffix}`,
		label: `Field ${suffix}`,
		type: "text",
		settings: {}
	};
}
function parsePath(input) {
	const trimmed = input.trim();
	if (!trimmed) return Object.freeze(["field"]);
	return Object.freeze(trimmed.split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment));
}
function formatPath(path) {
	return path.join(".");
}
function JsonObjectEditor({ label, value, onChange, disabled }) {
	const serialized = (0, import_react.useMemo)(() => JSON.stringify(value ?? {}, null, 2), [value]);
	const [draft, setDraft] = (0, import_react.useState)(serialized);
	const [error, setError] = (0, import_react.useState)(null);
	(0, import_react.useEffect)(() => setDraft(serialized), [serialized]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "fields-definition-builder__json",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [label, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
			rows: 7,
			value: draft,
			disabled,
			onChange: (event) => {
				const next = event.currentTarget.value;
				setDraft(next);
				try {
					const parsed = JSON.parse(next);
					if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("Settings must be a JSON object");
					setError(null);
					onChange(parsed);
				} catch (cause) {
					setError(cause instanceof Error ? cause.message : String(cause));
				}
			}
		})] }), error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			role: "alert",
			tabIndex: 0,
			children: error
		}) : null]
	});
}
function ConditionalLogicBuilder({ value, onChange, disabled }) {
	const groups = value ? value.map((group) => [...group]) : [];
	const replace = (next) => onChange(next.length ? Object.freeze(next.map((group) => Object.freeze(group))) : void 0);
	const updateRule = (groupIndex, ruleIndex, patch) => {
		const next = groups.map((group) => [...group]);
		const current = next[groupIndex]?.[ruleIndex];
		if (!current) return;
		next[groupIndex][ruleIndex] = {
			...current,
			...patch
		};
		replace(next);
	};
	const addRule = (groupIndex) => {
		const next = groups.map((group) => [...group]);
		next[groupIndex] = [...next[groupIndex] ?? [], {
			fieldPath: ["field"],
			operator: "eq",
			value: ""
		}];
		replace(next);
	};
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
		className: "fields-definition-builder__conditions",
		disabled,
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Conditional logic" }),
			groups.map((group, groupIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "fields-definition-builder__condition-group",
				"aria-label": `Conditional OR group ${groupIndex + 1}`,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: groupIndex === 0 ? "Show when" : "OR" }),
					group.map((rule, ruleIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "fields-definition-builder__condition-rule",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": `Condition ${groupIndex + 1}.${ruleIndex + 1} field path`,
								value: formatPath(rule.fieldPath),
								onChange: (event) => updateRule(groupIndex, ruleIndex, { fieldPath: parsePath(event.currentTarget.value) })
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
								"aria-label": `Condition ${groupIndex + 1}.${ruleIndex + 1} operator`,
								value: rule.operator,
								onChange: (event) => {
									const operator = event.currentTarget.value;
									const next = ["empty", "notEmpty"].includes(operator) ? {
										fieldPath: rule.fieldPath,
										operator,
										...rule.quantifier ? { quantifier: rule.quantifier } : {}
									} : operator === "matches" ? {
										fieldPath: rule.fieldPath,
										operator,
										value: { source: "" },
										...rule.quantifier ? { quantifier: rule.quantifier } : {}
									} : {
										fieldPath: rule.fieldPath,
										operator,
										value: "",
										...rule.quantifier ? { quantifier: rule.quantifier } : {}
									};
									updateRule(groupIndex, ruleIndex, next);
								},
								children: [
									"eq",
									"neq",
									"contains",
									"notContains",
									"gt",
									"gte",
									"lt",
									"lte",
									"empty",
									"notEmpty",
									"matches"
								].map((operator) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: operator,
									children: operator
								}, operator))
							}),
							!["empty", "notEmpty"].includes(rule.operator) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": `Condition ${groupIndex + 1}.${ruleIndex + 1} value`,
								type: [
									"gt",
									"gte",
									"lt",
									"lte"
								].includes(rule.operator) ? "number" : "text",
								value: "value" in rule ? rule.operator === "matches" ? rule.value.source : String(rule.value ?? "") : "",
								onChange: (event) => {
									if (rule.operator === "matches") updateRule(groupIndex, ruleIndex, { value: { source: event.currentTarget.value } });
									else if ([
										"gt",
										"gte",
										"lt",
										"lte"
									].includes(rule.operator)) updateRule(groupIndex, ruleIndex, { value: Number(event.currentTarget.value) });
									else updateRule(groupIndex, ruleIndex, { value: event.currentTarget.value });
								}
							}) : null,
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
								"aria-label": `Condition ${groupIndex + 1}.${ruleIndex + 1} quantifier`,
								value: rule.quantifier ?? "any",
								onChange: (event) => updateRule(groupIndex, ruleIndex, { quantifier: event.currentTarget.value }),
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "any",
									children: "any"
								}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "all",
									children: "all"
								})]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
								type: "button",
								onClick: () => {
									const next = groups.map((candidate) => [...candidate]);
									next[groupIndex] = next[groupIndex].filter((_, index) => index !== ruleIndex);
									replace(next.filter((candidate) => candidate.length));
								},
								children: "Remove condition"
							})
						]
					}, ruleIndex)),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
						type: "button",
						onClick: () => addRule(groupIndex),
						children: "Add AND condition"
					})
				]
			}, groupIndex)),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				onClick: () => replace([...groups, [{
					fieldPath: ["field"],
					operator: "eq",
					value: ""
				}]]),
				children: "Add OR group"
			})
		]
	});
}
function LocationRulesBuilder({ value, onChange, disabled }) {
	const groups = value.map((group) => [...group]);
	const replace = (next) => onChange(Object.freeze(next.map((group) => Object.freeze(group))));
	const update = (groupIndex, ruleIndex, patch) => {
		const next = groups.map((group) => [...group]);
		next[groupIndex][ruleIndex] = {
			...next[groupIndex][ruleIndex],
			...patch
		};
		replace(next);
	};
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
		disabled,
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Location rules" }),
			groups.map((group, groupIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				"aria-label": `Location OR group ${groupIndex + 1}`,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: groupIndex === 0 ? "Match" : "OR" }),
					group.map((rule, ruleIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": `Location ${groupIndex + 1}.${ruleIndex + 1} parameter`,
							value: rule.parameter,
							onChange: (event) => update(groupIndex, ruleIndex, { parameter: event.currentTarget.value })
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
							"aria-label": `Location ${groupIndex + 1}.${ruleIndex + 1} operator`,
							value: rule.operator,
							onChange: (event) => update(groupIndex, ruleIndex, { operator: event.currentTarget.value }),
							children: [
								"eq",
								"neq",
								"in",
								"notIn",
								"contains"
							].map((operator) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: operator,
								children: operator
							}, operator))
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": `Location ${groupIndex + 1}.${ruleIndex + 1} value`,
							value: Array.isArray(rule.value) ? rule.value.join(",") : String(rule.value),
							onChange: (event) => update(groupIndex, ruleIndex, { value: rule.operator === "in" || rule.operator === "notIn" ? event.currentTarget.value.split(",").map((item) => item.trim()).filter(Boolean) : event.currentTarget.value })
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
							type: "button",
							onClick: () => {
								const next = groups.map((candidate) => [...candidate]);
								next[groupIndex] = next[groupIndex].filter((_, index) => index !== ruleIndex);
								replace(next.filter((candidate) => candidate.length));
							},
							children: "Remove location rule"
						})
					] }, ruleIndex)),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
						type: "button",
						onClick: () => {
							const next = groups.map((candidate) => [...candidate]);
							next[groupIndex] = [...next[groupIndex] ?? [], {
								parameter: "entityType",
								operator: "eq",
								value: "content"
							}];
							replace(next);
						},
						children: "Add AND location rule"
					})
				]
			}, groupIndex)),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				onClick: () => replace([...groups, [{
					parameter: "entityType",
					operator: "eq",
					value: "content"
				}]]),
				children: "Add OR location group"
			})
		]
	});
}
function FieldDefinitionRow({ value, onChange, onMove, onRemove, index, length, disabled }) {
	let validationError = null;
	try {
		parseFieldDefinition(value);
	} catch (cause) {
		validationError = cause instanceof Error ? cause.message : String(cause);
	}
	const updateBase = (patch) => onChange({
		...value,
		...patch
	});
	const setType = (type) => onChange({
		...value,
		type,
		settings: defaultSettings(type),
		...type === "password" || type === "message" || type === "accordion" || type === "tab" ? { defaultValue: void 0 } : {}
	});
	const settings = value.settings;
	const nestedFields = value.type === "group" || value.type === "repeater" ? settings.fields ?? [] : null;
	const layouts = value.type === "flexible" ? settings.layouts ?? [] : null;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", {
		className: "fields-definition-builder__field-row",
		style: { containerType: "inline-size" },
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
			disabled,
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: value.label || value.key || `Field ${index + 1}` }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "fields-definition-builder__grid",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Label", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": `Field ${index + 1} label`,
							value: value.label,
							onChange: (event) => updateBase({ label: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Key", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": `Field ${index + 1} key`,
							value: value.key,
							onChange: (event) => updateBase({ key: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Name", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": `Field ${index + 1} name`,
							value: value.name,
							onChange: (event) => updateBase({ name: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Type", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
							"aria-label": `Field ${index + 1} type`,
							value: value.type,
							onChange: (event) => setType(event.currentTarget.value),
							children: COMPLETE_FIELD_TYPES.map((type) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: type,
								children: type
							}, type))
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							type: "checkbox",
							checked: value.required === true,
							onChange: (event) => updateBase({ required: event.currentTarget.checked || void 0 })
						}), " Required"] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							type: "checkbox",
							checked: value.readOnly === true,
							onChange: (event) => updateBase({ readOnly: event.currentTarget.checked || void 0 })
						}), " Read-only"] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "fields-definition-builder__wide",
							children: ["Instructions", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
								"aria-label": `Field ${index + 1} instructions`,
								value: value.instructions ?? "",
								onChange: (event) => updateBase({ instructions: event.currentTarget.value || void 0 })
							})]
						})
					]
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(JsonObjectEditor, {
					label: "Settings JSON",
					value: value.settings,
					disabled,
					onChange: (next) => updateBase({ settings: next })
				}),
				nestedFields ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldDefinitionListBuilder, {
					value: nestedFields,
					onChange: (fields) => updateBase({ settings: {
						...settings,
						fields
					} }),
					disabled,
					label: `${value.label} child fields`
				}) : null,
				layouts ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "fields-definition-builder__layouts",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { children: "Flexible layouts" }),
						layouts.map((layout, layoutIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: layout.label }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": `Layout ${layoutIndex + 1} key`,
								value: layout.key,
								onChange: (event) => {
									const next = layouts.map((candidate, candidateIndex) => candidateIndex === layoutIndex ? {
										...candidate,
										key: event.currentTarget.value
									} : candidate);
									updateBase({ settings: {
										...settings,
										layouts: next
									} });
								}
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": `Layout ${layoutIndex + 1} name`,
								value: layout.name,
								onChange: (event) => {
									const next = layouts.map((candidate, candidateIndex) => candidateIndex === layoutIndex ? {
										...candidate,
										name: event.currentTarget.value
									} : candidate);
									updateBase({ settings: {
										...settings,
										layouts: next
									} });
								}
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": `Layout ${layoutIndex + 1} label`,
								value: layout.label,
								onChange: (event) => {
									const next = layouts.map((candidate, candidateIndex) => candidateIndex === layoutIndex ? {
										...candidate,
										label: event.currentTarget.value
									} : candidate);
									updateBase({ settings: {
										...settings,
										layouts: next
									} });
								}
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldDefinitionListBuilder, {
								value: layout.fields,
								onChange: (fields) => {
									const next = layouts.map((candidate, candidateIndex) => candidateIndex === layoutIndex ? {
										...candidate,
										fields
									} : candidate);
									updateBase({ settings: {
										...settings,
										layouts: next
									} });
								},
								disabled,
								label: `${layout.label} fields`
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
								type: "button",
								onClick: () => updateBase({ settings: {
									...settings,
									layouts: layouts.filter((_, candidateIndex) => candidateIndex !== layoutIndex)
								} }),
								children: "Remove layout"
							})
						] }, layoutIndex)),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
							type: "button",
							onClick: () => {
								const suffix = layouts.length + 1;
								updateBase({ settings: {
									...settings,
									layouts: [...layouts, {
										key: `layout_${suffix}`,
										name: `layout_${suffix}`,
										label: `Layout ${suffix}`,
										fields: []
									}]
								} });
							},
							children: "Add layout"
						})
					]
				}) : null,
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConditionalLogicBuilder, {
					value: value.conditionalLogic,
					onChange: (conditionalLogic) => updateBase({ conditionalLogic }),
					disabled
				}),
				validationError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					role: "alert",
					tabIndex: 0,
					children: validationError
				}) : null,
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "fields-definition-builder__actions",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
							type: "button",
							"aria-label": `Move ${value.label} up`,
							"aria-disabled": index === 0,
							onClick: () => {
								if (index > 0) onMove(-1);
							},
							children: "Move up"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
							type: "button",
							"aria-label": `Move ${value.label} down`,
							"aria-disabled": index === length - 1,
							onClick: () => {
								if (index < length - 1) onMove(1);
							},
							children: "Move down"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
							type: "button",
							"aria-label": `Remove ${value.label}`,
							onClick: onRemove,
							children: "Remove field"
						})
					]
				})
			]
		})
	});
}
function FieldDefinitionListBuilder({ value, onChange, disabled, label = "Fields" }) {
	const listId = (0, import_react.useId)(), idsRef = (0, import_react.useRef)([]), serialRef = (0, import_react.useRef)(0);
	while (idsRef.current.length < value.length) idsRef.current.push(`${listId}-field-${serialRef.current++}`);
	if (idsRef.current.length > value.length) idsRef.current.length = value.length;
	const replace = (index, next) => onChange(value.map((field, candidateIndex) => candidateIndex === index ? next : field));
	const move = (index, direction) => {
		const target = index + direction;
		if (target < 0 || target >= value.length) return;
		const next = [...value];
		[next[index], next[target]] = [next[target], next[index]];
		[idsRef.current[index], idsRef.current[target]] = [idsRef.current[target], idsRef.current[index]];
		onChange(next);
	};
	const remove = (index) => {
		idsRef.current.splice(index, 1);
		onChange(value.filter((_, candidateIndex) => candidateIndex !== index));
	};
	const add = () => {
		idsRef.current.push(`${listId}-field-${serialRef.current++}`);
		onChange([...value, defaultField(value.length)]);
	};
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "fields-definition-builder__list",
		"aria-label": label,
		style: { containerType: "inline-size" },
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { children: value.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldDefinitionRow, {
			value: field,
			index,
			length: value.length,
			disabled,
			onChange: (next) => replace(index, next),
			onMove: (direction) => move(index, direction),
			onRemove: () => remove(index)
		}, idsRef.current[index])) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
			type: "button",
			disabled,
			onClick: add,
			children: "Add field"
		})]
	});
}
function FieldGroupDefinitionBuilder({ value, onChange, disabled }) {
	let validationError = null;
	try {
		parseFieldGroupDefinition(value);
	} catch (cause) {
		validationError = cause instanceof Error ? cause.message : String(cause);
	}
	const update = (patch) => onChange({
		...value,
		...patch
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "fields-definition-builder",
		style: {
			containerType: "inline-size",
			containerName: "fields-definition-builder"
		},
		"aria-label": `Field group ${value.title}`,
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `.fields-definition-builder__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem}.fields-definition-builder__wide{grid-column:1/-1}.fields-definition-builder__field-row{display:grid;gap:.5rem}.fields-definition-builder__actions{display:flex;gap:.4rem;flex-wrap:wrap}@container fields-definition-builder (max-width:36rem){.fields-definition-builder__grid{grid-template-columns:minmax(0,1fr)}.fields-definition-builder__wide{grid-column:1}}` }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
			disabled,
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Group definition" }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "fields-definition-builder__grid",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Title", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Group title",
							value: value.title,
							onChange: (event) => update({ title: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Key", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Group key",
							value: value.key,
							onChange: (event) => update({ key: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Position", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							"aria-label": "Group position",
							value: value.position ?? "normal",
							onChange: (event) => update({ position: event.currentTarget.value }),
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "normal",
									children: "normal"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "side",
									children: "side"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "afterTitle",
									children: "afterTitle"
								})
							]
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Style", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							"aria-label": "Group style",
							value: value.style ?? "default",
							onChange: (event) => update({ style: event.currentTarget.value }),
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: "default",
								children: "default"
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: "seamless",
								children: "seamless"
							})]
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							type: "checkbox",
							checked: value.active,
							onChange: (event) => update({ active: event.currentTarget.checked })
						}), " Active"] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Order", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Group order",
							type: "number",
							value: value.order ?? "",
							onChange: (event) => update({ order: event.currentTarget.value === "" ? void 0 : Number(event.currentTarget.value) })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "fields-definition-builder__wide",
							children: ["Description", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
								"aria-label": "Group description",
								value: value.description ?? "",
								onChange: (event) => update({ description: event.currentTarget.value || void 0 })
							})]
						})
					]
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LocationRulesBuilder, {
					value: value.location,
					onChange: (location) => update({ location }),
					disabled
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldDefinitionListBuilder, {
					value: value.fields,
					onChange: (fields) => update({ fields }),
					disabled
				}),
				validationError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					role: "alert",
					tabIndex: 0,
					children: validationError
				}) : null
			]
		})]
	});
}
function OptionsPageDefinitionEditor({ value, onChange, availableParents = [], disabled }) {
	const update = (patch) => onChange({
		...value,
		...patch
	});
	const issues = [];
	if (!/^[a-z][a-z0-9_-]*$/.test(value.key)) issues.push("Key must be normalized");
	if (!value.title.trim()) issues.push("Title is required");
	for (const [label, capability] of [
		["Read capability", value.readCapability],
		["Write capability", value.writeCapability],
		["Manage capability", value.manageCapability]
	]) if (!capability.trim()) issues.push(`${label} is required`);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "fields-options-editor",
		style: {
			containerType: "inline-size",
			containerName: "fields-options"
		},
		"aria-label": `Options Page ${value.title || value.key}`,
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `.fields-options-editor__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem}.fields-options-editor__wide{grid-column:1/-1}@container fields-options (max-width:36rem){.fields-options-editor__grid{grid-template-columns:minmax(0,1fr)}.fields-options-editor__wide{grid-column:1}}` }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
			disabled,
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Options Page definition" }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "fields-options-editor__grid",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Title", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page title",
							value: value.title,
							onChange: (event) => update({ title: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Key", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page key",
							value: value.key,
							onChange: (event) => update({ key: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Menu title", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page menu title",
							value: value.menuTitle ?? "",
							onChange: (event) => update({ menuTitle: event.currentTarget.value || void 0 })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Parent", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							"aria-label": "Options Page parent",
							value: value.parentKey ?? "",
							onChange: (event) => update({ parentKey: event.currentTarget.value || void 0 }),
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: "",
								children: "—"
							}), availableParents.filter((page) => page.key !== value.key).map((page) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: page.key,
								children: page.title
							}, page.key))]
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Read capability", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page read capability",
							value: value.readCapability,
							onChange: (event) => update({ readCapability: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Write capability", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page write capability",
							value: value.writeCapability,
							onChange: (event) => update({ writeCapability: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Manage capability", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page manage capability",
							value: value.manageCapability,
							onChange: (event) => update({ manageCapability: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Position", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page position",
							type: "number",
							value: value.position ?? "",
							onChange: (event) => update({ position: event.currentTarget.value === "" ? void 0 : Number(event.currentTarget.value) })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Icon", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Options Page icon",
							value: value.icon ?? "",
							onChange: (event) => update({ icon: event.currentTarget.value || void 0 })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							type: "checkbox",
							checked: value.redirectToFirstChild === true,
							onChange: (event) => update({ redirectToFirstChild: event.currentTarget.checked || void 0 })
						}), " Redirect to first child"] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							type: "checkbox",
							checked: value.autoload === true,
							onChange: (event) => update({ autoload: event.currentTarget.checked || void 0 })
						}), " Autoload"] })
					]
				}),
				issues.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					role: "alert",
					tabIndex: 0,
					children: issues.join(". ")
				}) : null
			]
		})]
	});
}
var ALIGNMENTS = [
	"left",
	"center",
	"right",
	"wide",
	"full"
];
var SUPPORT_KEYS = [
	"anchor",
	"className",
	"multiple",
	"reusable",
	"innerBlocks",
	"jsx"
];
function uniqueList(raw) {
	return Object.freeze([...new Set(raw.split(",").map((item) => item.trim()).filter(Boolean))]);
}
function JsonEditor$1({ label, value, onChange, disabled }) {
	const serialized = (0, import_react.useMemo)(() => JSON.stringify(value ?? {}, null, 2), [value]), [draft, setDraft] = (0, import_react.useState)(serialized), [error, setError] = (0, import_react.useState)(null);
	(0, import_react.useEffect)(() => setDraft(serialized), [serialized]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [label, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
		rows: 6,
		value: draft,
		disabled,
		onChange: (event) => {
			const next = event.currentTarget.value;
			setDraft(next);
			try {
				const parsed = JSON.parse(next);
				setError(null);
				onChange(parsed);
			} catch (cause) {
				setError(cause instanceof Error ? cause.message : String(cause));
			}
		}
	})] }), error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		role: "alert",
		tabIndex: 0,
		children: error
	}) : null] });
}
function FieldBlockDefinitionEditor({ value, onChange, availableGroupKeys = [], availableBlockKeys = [], disabled }) {
	const update = (patch) => onChange({
		...value,
		...patch
	});
	const support = value.supports ?? {};
	const issues = [];
	if (!/^[a-z][a-z0-9_-]*$/.test(value.key)) issues.push("Block key must be normalized");
	if (!value.title.trim()) issues.push("Block title is required");
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "fields-block-definition",
		style: {
			containerType: "inline-size",
			containerName: "fields-block-definition"
		},
		"aria-label": `Block ${value.title || value.key}`,
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `.fields-block-definition__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem}.fields-block-definition__wide{grid-column:1/-1}.fields-block-definition__checks{display:flex;gap:.7rem;flex-wrap:wrap}@container fields-block-definition (max-width:36rem){.fields-block-definition__grid{grid-template-columns:minmax(0,1fr)}.fields-block-definition__wide{grid-column:1}}` }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
			disabled,
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Block definition" }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "fields-block-definition__grid",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Title", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Block title",
							value: value.title,
							onChange: (event) => update({ title: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Key", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Block key",
							value: value.key,
							onChange: (event) => update({ key: event.currentTarget.value })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Category", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Block category",
							value: value.category ?? "",
							onChange: (event) => update({ category: event.currentTarget.value || void 0 })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Icon", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
							"aria-label": "Block icon",
							value: value.icon ?? "",
							onChange: (event) => update({ icon: event.currentTarget.value || void 0 })
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Mode", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							"aria-label": "Block mode",
							value: value.mode ?? "auto",
							onChange: (event) => update({ mode: event.currentTarget.value }),
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "auto",
									children: "auto"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "preview",
									children: "preview"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "edit",
									children: "edit"
								})
							]
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: ["Template lock", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							"aria-label": "Block template lock",
							value: value.templateLock === false ? "false" : value.templateLock ?? "false",
							onChange: (event) => update({ templateLock: event.currentTarget.value === "false" ? false : event.currentTarget.value }),
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "false",
									children: "unlocked"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "insert",
									children: "insert"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "all",
									children: "all"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "contentOnly",
									children: "contentOnly"
								})
							]
						})] }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "fields-block-definition__wide",
							children: ["Description", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
								"aria-label": "Block description",
								value: value.description ?? "",
								onChange: (event) => update({ description: event.currentTarget.value || void 0 })
							})]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "fields-block-definition__wide",
							children: ["Keywords", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": "Block keywords",
								value: (value.keywords ?? []).join(", "),
								onChange: (event) => update({ keywords: uniqueList(event.currentTarget.value) })
							})]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "fields-block-definition__wide",
							children: ["Parent blocks", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": "Block parents",
								value: (value.parent ?? []).join(", "),
								onChange: (event) => update({ parent: uniqueList(event.currentTarget.value) })
							})]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "fields-block-definition__wide",
							children: ["Ancestor blocks", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								"aria-label": "Block ancestors",
								value: (value.ancestor ?? []).join(", "),
								onChange: (event) => update({ ancestor: uniqueList(event.currentTarget.value) })
							})]
						})
					]
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Field groups" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					className: "fields-block-definition__checks",
					children: availableGroupKeys.map((key) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
						type: "checkbox",
						checked: value.fieldGroupKeys.includes(key),
						onChange: (event) => update({ fieldGroupKeys: event.currentTarget.checked ? [...value.fieldGroupKeys, key] : value.fieldGroupKeys.filter((candidate) => candidate !== key) })
					}), key] }, key))
				})] }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Alignment" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					className: "fields-block-definition__checks",
					children: ALIGNMENTS.map((align) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
						type: "checkbox",
						checked: (value.align ?? []).includes(align),
						onChange: (event) => update({ align: event.currentTarget.checked ? [...value.align ?? [], align] : (value.align ?? []).filter((candidate) => candidate !== align) })
					}), align] }, align))
				})] }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "Supports" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					className: "fields-block-definition__checks",
					children: SUPPORT_KEYS.map((key) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
						type: "checkbox",
						checked: support[key] === true,
						onChange: (event) => update({ supports: {
							...support,
							[key]: event.currentTarget.checked || void 0
						} })
					}), key] }, key))
				})] }),
				availableBlockKeys.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					role: "note",
					children: ["Available block keys: ", availableBlockKeys.join(", ")]
				}) : null,
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(JsonEditor$1, {
					label: "Template JSON",
					value: value.template ?? [],
					disabled,
					onChange: (template) => update({ template: Array.isArray(template) ? template : void 0 })
				}),
				issues.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					role: "alert",
					tabIndex: 0,
					children: issues.join(". ")
				}) : null
			]
		})]
	});
}
//#endregion
//#region ../../packages/ui-primitives/dist/editor-widget/index.js
function createEditorWidgetError(code, message) {
	return Object.assign(new Error(message), {
		name: "EditorWidgetError",
		code
	});
}
function isEditorWidgetError(value) {
	if (typeof value !== "object" || value === null) return false;
	const candidate = value;
	return candidate.name === "EditorWidgetError" && (candidate.code === "invalid_media" || candidate.code === "media_insert_failed") && typeof candidate.message === "string";
}
var PREVIEW_STYLE = `
:root { color-scheme: light dark; }
html, body { min-block-size: 100%; }
html { overflow: auto; }
body {
  box-sizing: border-box;
  margin: 0;
  padding: 1rem;
  overflow-wrap: anywhere;
  font: 1rem/1.6 sans-serif;
}
body > :first-child { margin-block-start: 0; }
body > :last-child { margin-block-end: 0; }
h2 { margin-block: 1.5rem 0.75rem; font-size: 1.5rem; line-height: 1.25; }
p, ul { margin-block: 0 1rem; }
ul { padding-inline-start: 1.5rem; list-style: disc; }
li + li { margin-block-start: 0.5rem; }
img { max-inline-size: 100%; block-size: auto; }
`;
var DROP_WITH_CONTENT = /* @__PURE__ */ new Set([
	"SCRIPT",
	"STYLE",
	"IFRAME",
	"OBJECT",
	"EMBED",
	"TEMPLATE",
	"NOSCRIPT",
	"SVG",
	"MATH"
]);
var DROP_ELEMENT = /* @__PURE__ */ new Set([
	"INPUT",
	"BUTTON",
	"SELECT",
	"TEXTAREA",
	"OPTION"
]);
var SAFE_CONTAINER = /* @__PURE__ */ new Set([
	"P",
	"H1",
	"H2",
	"STRONG",
	"EM",
	"UL",
	"LI",
	"BR"
]);
function safeImageSource(value) {
	try {
		const url = new URL(value);
		return url.protocol === "https:" && url.username === "" && url.password === "";
	} catch {
		return false;
	}
}
function positiveFiniteAttribute(value) {
	if (value === null || value.trim() === "") return null;
	const parsed = Number(value);
	return Number.isFinite(parsed) && parsed > 0 ? value : null;
}
function copyDirection(source, target) {
	const dir = source.getAttribute("dir");
	if (dir === "ltr" || dir === "rtl") target.setAttribute("dir", dir);
}
function safeNode(source, targetDocument) {
	if (source.nodeType === Node.TEXT_NODE) return targetDocument.createTextNode(source.textContent ?? "");
	if (source.nodeType !== Node.ELEMENT_NODE) return targetDocument.createDocumentFragment();
	const element = source;
	const tagName = element.tagName.toUpperCase();
	if (DROP_WITH_CONTENT.has(tagName) || DROP_ELEMENT.has(tagName)) return targetDocument.createDocumentFragment();
	if (tagName === "IMG") {
		const src = element.getAttribute("src") ?? "";
		if (!safeImageSource(src)) return targetDocument.createDocumentFragment();
		const image = targetDocument.createElement("img");
		image.setAttribute("src", src);
		image.setAttribute("alt", element.getAttribute("alt") ?? "");
		const width = positiveFiniteAttribute(element.getAttribute("width"));
		const height = positiveFiniteAttribute(element.getAttribute("height"));
		if (width !== null) image.setAttribute("width", width);
		if (height !== null) image.setAttribute("height", height);
		copyDirection(element, image);
		return image;
	}
	const normalizedTag = tagName === "B" ? "STRONG" : tagName === "I" ? "EM" : tagName;
	const target = SAFE_CONTAINER.has(normalizedTag) ? targetDocument.createElement(normalizedTag.toLowerCase()) : targetDocument.createDocumentFragment();
	if (target.nodeType === Node.ELEMENT_NODE) copyDirection(element, target);
	for (const child of Array.from(element.childNodes)) target.appendChild(safeNode(child, targetDocument));
	return target;
}
function constrainPreviewHtml(sourceHtml) {
	if (typeof DOMParser === "undefined") return sourceHtml.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
	const sourceDocument = new DOMParser().parseFromString(sourceHtml, "text/html");
	const targetDocument = document.implementation.createHTMLDocument("");
	for (const node of Array.from(sourceDocument.body.childNodes)) targetDocument.body.appendChild(safeNode(node, targetDocument));
	return targetDocument.body.innerHTML;
}
function buildPreviewDocument(sourceHtml, dir) {
	return `<!doctype html>
<html dir="${dir}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="referrer" content="no-referrer">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src https:; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'; object-src 'none'">
<style>${PREVIEW_STYLE}</style>
</head>
<body>${constrainPreviewHtml(sourceHtml)}</body>
</html>`;
}
var FORMAT_BUTTON_CLASSES = "EditorWidget-formatButton inline-flex min-h-[var(--mod-touch-min)] min-w-[var(--mod-touch-min)] flex-none items-center justify-center border border-[var(--mod-color-border)] bg-[var(--mod-color-surface)] px-3 text-sm text-[var(--mod-color-fg)] hover:bg-[var(--mod-color-surface-raised)] active:border-[var(--mod-color-border-strong)] active:bg-[var(--mod-color-surface-raised)] aria-[pressed=true]:border-[var(--mod-color-border-strong)] aria-[pressed=true]:bg-[var(--mod-color-surface-raised)] aria-[pressed=true]:outline aria-[pressed=true]:outline-current focus-visible:z-10 focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)] disabled:cursor-not-allowed disabled:opacity-[var(--mod-opacity-disabled)]";
var TAB_CLASSES = "EditorWidget-tab inline-flex min-h-[var(--mod-touch-min)] items-center justify-center rounded-md border border-transparent px-3 text-sm text-[var(--mod-color-fg)] data-[state=inactive]:bg-[var(--mod-color-surface)] data-[state=inactive]:hover:bg-[var(--mod-color-surface-raised)] data-[state=active]:bg-[var(--mod-color-accent)] data-[state=active]:text-[var(--mod-color-accent-fg)] forced-colors:data-[state=active]:border-current forced-colors:data-[state=active]:outline forced-colors:data-[state=active]:outline-2 focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]";
var EDITOR_SURFACE_CLASSES = "EditorWidget-surface min-w-0 rounded-md border border-[var(--mod-color-border)] bg-[var(--mod-color-surface)] text-[var(--mod-color-fg)] focus-within:outline-[var(--mod-focus-ring-width)] focus-within:outline-[var(--mod-focus-ring-color)] focus-within:outline-offset-[var(--mod-focus-ring-offset)] [&_[role=textbox]]:min-h-[calc(var(--mod-touch-min)*6)] [&_[role=textbox]]:[overflow-wrap:anywhere] [&_[role=textbox]]:p-4 [&_[role=textbox]]:outline-none [&_[role=textbox]>*:first-child]:mt-0 [&_[role=textbox]>*:last-child]:mb-0 [&_[role=textbox]_h2]:my-4 [&_[role=textbox]_h2]:text-xl [&_[role=textbox]_h2]:font-semibold [&_[role=textbox]_h2]:leading-tight [&_[role=textbox]_p]:mb-3 [&_[role=textbox]_ul]:mb-3 [&_[role=textbox]_ul]:list-disc [&_[role=textbox]_ul]:ps-6 [&_[role=textbox]_li+li]:mt-1 [&_[role=textbox]_img]:h-auto [&_[role=textbox]_img]:max-w-full";
var FORMATTING_ITEMS = [
	{
		label: "Bold",
		text: "B",
		shortcut: "Control+B Meta+B"
	},
	{
		label: "Italic",
		text: "I",
		shortcut: "Control+I Meta+I"
	},
	{
		label: "Heading 2",
		text: "H2"
	},
	{
		label: "Bullet list",
		text: "List"
	}
];
function positiveFinite(value) {
	return value === void 0 || Number.isFinite(value) && value > 0;
}
function safeMediaSource(value) {
	if (typeof value !== "string" || value.trim() !== value || value.length === 0) return false;
	try {
		const url = new URL(value);
		return url.protocol === "https:" && url.username === "" && url.password === "";
	} catch {
		return false;
	}
}
function validMediaItem(value) {
	if (typeof value !== "object" || value === null) return false;
	const item = value;
	return safeMediaSource(item.src) && typeof item.alt === "string" && positiveFinite(item.width) && positiveFinite(item.height);
}
function FormattingToolbar({ state, ariaLabel, dir, media, reportError, reportStatus }) {
	const buttons = (0, import_react.useRef)([]);
	const [tabStop, setTabStop] = (0, import_react.useState)(0);
	const editor = state.editor;
	const items = [
		{
			...FORMATTING_ITEMS[0],
			pressed: state.isBold,
			run: () => {
				if (editor?.can().toggleBold()) editor.chain().focus().toggleBold().run();
			}
		},
		{
			...FORMATTING_ITEMS[1],
			pressed: state.isItalic,
			run: () => {
				if (editor?.can().toggleItalic()) editor.chain().focus().toggleItalic().run();
			}
		},
		{
			...FORMATTING_ITEMS[2],
			pressed: state.isH2,
			run: () => {
				if (editor?.can().toggleHeading({ level: 2 })) editor.chain().focus().toggleHeading({ level: 2 }).run();
			}
		},
		{
			...FORMATTING_ITEMS[3],
			pressed: state.isBullet,
			run: () => {
				if (editor?.can().toggleBulletList()) editor.chain().focus().toggleBulletList().run();
			}
		}
	];
	function moveFocus(event) {
		const forward = dir === "rtl" ? -1 : 1;
		let next = tabStop;
		if (event.key === "ArrowRight") next = (tabStop + forward + items.length) % items.length;
		else if (event.key === "ArrowLeft") next = (tabStop - forward + items.length) % items.length;
		else if (event.key === "Home") next = 0;
		else if (event.key === "End") next = items.length - 1;
		else return;
		event.preventDefault();
		setTabStop(next);
		buttons.current[next]?.focus();
	}
	function preserveEditorFocus(event) {
		event.preventDefault();
	}
	function activateWithKeyboard(event, run) {
		if (event.key !== "Enter" && event.key !== " ") return;
		event.preventDefault();
		run();
	}
	function insertMedia(item) {
		if (!validMediaItem(item)) {
			reportError(createEditorWidgetError("invalid_media", "The selected image is invalid."));
			return false;
		}
		if (!editor || editor.schema.nodes.image === void 0) {
			reportError(createEditorWidgetError("media_insert_failed", "The selected image could not be inserted."));
			return false;
		}
		try {
			if (!editor.chain().insertContent({
				type: "image",
				attrs: {
					src: item.src,
					alt: item.alt,
					...item.width === void 0 ? {} : { width: item.width },
					...item.height === void 0 ? {} : { height: item.height }
				}
			}).run()) {
				reportError(createEditorWidgetError("media_insert_failed", "The selected image could not be inserted."));
				return false;
			}
			reportStatus("Image inserted.");
			return true;
		} catch {
			reportError(createEditorWidgetError("media_insert_failed", "The selected image could not be inserted."));
			return false;
		}
	}
	const mediaDisabled = editor === null || editor.schema.nodes.image === void 0;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "EditorWidget-toolbarRow flex min-w-0 flex-col gap-2 @md:flex-row @md:items-start @md:justify-between",
		"data-editor-widget-part": "toolbar-row",
		"data-editor-ready": editor === null ? "false" : "true",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			className: "EditorWidget-toolbar flex max-w-full overflow-x-auto rounded-md",
			"data-editor-widget-part": "formatting-toolbar",
			role: "toolbar",
			"aria-label": `${ariaLabel} formatting`,
			"aria-orientation": "horizontal",
			onKeyDown: moveFocus,
			children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				ref: (node) => {
					buttons.current[index] = node;
				},
				className: FORMAT_BUTTON_CLASSES,
				"data-editor-widget-part": "format-button",
				type: "button",
				"aria-label": item.label,
				"aria-keyshortcuts": item.shortcut,
				"aria-pressed": item.pressed,
				disabled: editor === null,
				tabIndex: tabStop === index ? 0 : -1,
				onFocus: () => setTabStop(index),
				onMouseDown: preserveEditorFocus,
				onPointerDown: preserveEditorFocus,
				onKeyDown: (event) => activateWithKeyboard(event, item.run),
				onClick: item.run,
				children: item.text
			}, item.label))
		}), media ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			className: "EditorWidget-media min-w-0",
			"data-editor-widget-part": "media-picker",
			children: media.renderPicker({
				disabled: mediaDisabled,
				onSelect: insertMedia
			})
		}) : null]
	});
}
function sameOptionValue(left, right, seen = /* @__PURE__ */ new WeakMap()) {
	if (Object.is(left, right)) return true;
	if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) return false;
	if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) return false;
	if (seen.get(left) === right) return true;
	seen.set(left, right);
	const leftKeys = Object.keys(left);
	const rightKeys = Object.keys(right);
	if (leftKeys.length !== rightKeys.length) return false;
	return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && sameOptionValue(left[key], right[key], seen));
}
function sameExtensionImplementation(left, right) {
	const leftKeys = Object.keys(left);
	const rightKeys = Object.keys(right);
	if (leftKeys.length !== rightKeys.length) return false;
	return leftKeys.every((key) => {
		if (!Object.prototype.hasOwnProperty.call(right, key)) return false;
		const leftValue = Reflect.get(left, key);
		const rightValue = Reflect.get(right, key);
		if (typeof leftValue === "function" || typeof rightValue === "function") return typeof leftValue === "function" && typeof rightValue === "function" && Function.prototype.toString.call(leftValue) === Function.prototype.toString.call(rightValue);
		return sameOptionValue(leftValue, rightValue);
	});
}
function sameExtensionConfig(left, right) {
	if (left === right) return true;
	if (!left || !right || left.extensions.length !== right.extensions.length) return false;
	return left.extensions.every((extension, index) => {
		const candidate = right.extensions[index];
		return candidate !== void 0 && extension.name === candidate.name && sameOptionValue(extension.options, candidate.options) && sameExtensionImplementation(extension.config, candidate.config);
	});
}
function useStableExtensionConfig(config) {
	const stable = (0, import_react.useRef)(config);
	if (!sameExtensionConfig(stable.current, config)) stable.current = config;
	return stable.current;
}
function editorExtensions(mediaExtensions) {
	const extensionsByName = new Map(createDefaultExtensions().map((extension) => [extension.name, extension]));
	for (const extension of mediaExtensions?.extensions ?? []) extensionsByName.set(extension.name, extension);
	return { extensions: [...extensionsByName.values()] };
}
function EditorWidget({ value, onChange, dir = "ltr", readOnly = false, ariaLabel, ariaDescribedBy, media, onError, className }) {
	const instanceId = (0, import_react.useId)();
	const labelId = `${instanceId}-label`;
	const writeTabId = `${instanceId}-write-tab`;
	const previewTabId = `${instanceId}-preview-tab`;
	const writePanelId = `${instanceId}-write-panel`;
	const previewPanelId = `${instanceId}-preview-panel`;
	const writeTab = (0, import_react.useRef)(null);
	const previewTab = (0, import_react.useRef)(null);
	const [activeTab, setActiveTab] = (0, import_react.useState)("write");
	const announcementId = (0, import_react.useRef)(0);
	const [announcement, setAnnouncement] = (0, import_react.useState)(null);
	const mediaExtensions = useStableExtensionConfig(media?.extensions);
	const extensions = (0, import_react.useMemo)(() => editorExtensions(mediaExtensions), [mediaExtensions]);
	const previewSource = (0, import_react.useMemo)(() => activeTab === "preview" ? buildPreviewDocument(value, dir) : void 0, [
		activeTab,
		value,
		dir
	]);
	const announce = (0, import_react.useCallback)((message) => {
		announcementId.current += 1;
		setAnnouncement({
			id: announcementId.current,
			message
		});
	}, []);
	const reportError = (0, import_react.useCallback)((error) => {
		announce(error.message);
		onError?.(error);
	}, [announce, onError]);
	function onTabKeyDown(event) {
		if (![
			"ArrowLeft",
			"ArrowRight",
			"Home",
			"End"
		].includes(event.key)) return;
		event.preventDefault();
		const order = dir === "rtl" ? ["preview", "write"] : ["write", "preview"];
		const current = order.indexOf(activeTab);
		const next = (event.key === "Home" ? "write" : event.key === "End" ? "preview" : event.key === "ArrowRight" ? order[(current + 1) % order.length] : order[(current - 1 + order.length) % order.length]) ?? activeTab;
		setActiveTab(next);
		(next === "write" ? writeTab : previewTab).current?.focus();
	}
	const writeInactive = activeTab !== "write";
	const previewInactive = activeTab !== "preview";
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: cn("EditorWidget @container grid min-w-0 gap-2 text-[var(--mod-color-fg)]", className),
		"data-editor-widget": "",
		"data-read-only": readOnly ? "true" : "false",
		dir,
		"aria-labelledby": labelId,
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
				id: labelId,
				className: "sr-only",
				children: ariaLabel
			}),
			!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "EditorWidget-hint m-0 text-sm text-[var(--mod-color-fg-muted)]",
				children: "Shortcuts: Control/Command+B and Control/Command+I."
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "EditorWidget-tabs grid min-w-0 gap-2",
				"data-editor-widget-part": "tabs",
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "EditorWidget-tabList inline-flex w-fit max-w-full gap-1 rounded-md bg-[var(--mod-color-surface)] p-1",
						role: "tablist",
						"aria-label": `${ariaLabel} view`,
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
							ref: writeTab,
							id: writeTabId,
							className: TAB_CLASSES,
							"data-editor-widget-part": "tab",
							"data-editor-widget-view": "write",
							"data-state": activeTab === "write" ? "active" : "inactive",
							type: "button",
							role: "tab",
							"aria-selected": activeTab === "write",
							"aria-controls": writePanelId,
							tabIndex: activeTab === "write" ? 0 : -1,
							onClick: () => setActiveTab("write"),
							onKeyDown: onTabKeyDown,
							children: "Write"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
							ref: previewTab,
							id: previewTabId,
							className: TAB_CLASSES,
							"data-editor-widget-part": "tab",
							"data-editor-widget-view": "preview",
							"data-state": activeTab === "preview" ? "active" : "inactive",
							type: "button",
							role: "tab",
							"aria-selected": activeTab === "preview",
							"aria-controls": previewPanelId,
							tabIndex: activeTab === "preview" ? 0 : -1,
							onClick: () => setActiveTab("preview"),
							onKeyDown: onTabKeyDown,
							children: "Preview"
						})]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						ref: (node) => {
							node?.toggleAttribute("inert", writeInactive);
						},
						id: writePanelId,
						className: "EditorWidget-panel EditorWidget-panel--write min-w-0",
						"data-editor-widget-part": "write-panel",
						role: "tabpanel",
						"aria-labelledby": writeTabId,
						"aria-hidden": writeInactive || void 0,
						hidden: writeInactive,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RichTextEditor, {
							value,
							onChange,
							dir,
							"aria-label": ariaLabel,
							"aria-describedby": ariaDescribedBy,
							readOnly,
							className: EDITOR_SURFACE_CLASSES,
							extensions,
							renderToolbar: readOnly ? () => null : (state) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormattingToolbar, {
								state,
								ariaLabel,
								dir,
								media,
								reportError,
								reportStatus: announce
							})
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						ref: (node) => {
							node?.toggleAttribute("inert", previewInactive);
						},
						id: previewPanelId,
						className: "EditorWidget-panel EditorWidget-panel--preview min-w-0",
						"data-editor-widget-part": "preview-panel",
						role: "tabpanel",
						"aria-labelledby": previewTabId,
						"aria-hidden": previewInactive || void 0,
						hidden: previewInactive,
						children: previewSource !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("iframe", {
							className: "EditorWidget-preview block min-h-[calc(var(--mod-touch-min)*8)] w-full rounded-md border border-[var(--mod-color-border)] bg-[var(--mod-color-surface)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]",
							"data-editor-widget-part": "preview",
							title: `${ariaLabel} preview`,
							sandbox: "",
							referrerPolicy: "no-referrer",
							tabIndex: 0,
							srcDoc: previewSource
						}) : null
					})
				]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "sr-only",
				role: "status",
				"aria-live": "polite",
				"aria-atomic": "true",
				children: announcement ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: announcement.message }, announcement.id) : null
			})
		]
	});
}
//#endregion
//#region ../../node_modules/.pnpm/@tiptap+extension-image@3.30.2_@tiptap+core@3.30.2_@tiptap+pm@3.30.2_/node_modules/@tiptap/extension-image/dist/index.js
var inputRegex = /(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/;
//#endregion
//#region src/lib/editor-image.ts
var ImageWithDimensions = Node3.create({
	name: "image",
	addOptions() {
		return {
			inline: false,
			allowBase64: false,
			HTMLAttributes: {},
			resize: false
		};
	},
	inline() {
		return this.options.inline;
	},
	group() {
		return this.options.inline ? "inline" : "block";
	},
	draggable: true,
	addAttributes() {
		return {
			src: { default: null },
			alt: { default: null },
			title: { default: null },
			width: { default: null },
			height: { default: null }
		};
	},
	parseHTML() {
		return [{ tag: this.options.allowBase64 ? "img[src]" : "img[src]:not([src^=\"data:\"])" }];
	},
	renderHTML({ HTMLAttributes }) {
		return ["img", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
	},
	parseMarkdown: (token, helpers) => {
		return helpers.createNode("image", {
			src: token.href,
			title: token.title,
			alt: token.text
		});
	},
	renderMarkdown: (node) => {
		var _a, _b, _c, _d, _e, _f;
		const src = (_b = (_a = node.attrs) == null ? void 0 : _a.src) != null ? _b : "";
		const alt = (_d = (_c = node.attrs) == null ? void 0 : _c.alt) != null ? _d : "";
		const title = (_f = (_e = node.attrs) == null ? void 0 : _e.title) != null ? _f : "";
		return title ? `![${alt}](${src} "${title}")` : `![${alt}](${src})`;
	},
	addNodeView() {
		if (!this.options.resize || !this.options.resize.enabled || typeof document === "undefined") return null;
		const { directions, minWidth, minHeight, alwaysPreserveAspectRatio } = this.options.resize;
		const resizeManagedAttributes = /* @__PURE__ */ new Set([
			"src",
			"width",
			"height"
		]);
		return ({ node, getPos, HTMLAttributes, editor }) => {
			const el = document.createElement("img");
			el.draggable = false;
			const mergedAttributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes);
			Object.entries(mergedAttributes).forEach(([key, value]) => {
				if (value != null) switch (key) {
					case "src":
					case "width":
					case "height": break;
					default: el.setAttribute(key, value);
				}
			});
			if (mergedAttributes.src !== null) el.src = mergedAttributes.src;
			let previousHTMLAttributes = { ...HTMLAttributes };
			const syncImageSource = (src) => {
				if (typeof src === "string" && src !== "") {
					if (el.getAttribute("src") !== src) el.src = src;
					return;
				}
				if (el.hasAttribute("src")) el.removeAttribute("src");
				if (el.src !== "") el.src = "";
			};
			syncImageSource(HTMLAttributes.src);
			const onUpdate = (updatedNode) => {
				if (updatedNode.type !== node.type) return false;
				const newHTMLAttributes = getRenderedAttributes(updatedNode, editor.extensionManager.attributes.filter((attribute) => attribute.type === updatedNode.type.name));
				Object.keys(previousHTMLAttributes).forEach((key) => {
					if (!resizeManagedAttributes.has(key) && !(key in newHTMLAttributes)) el.removeAttribute(key);
				});
				Object.entries(newHTMLAttributes).forEach(([key, value]) => {
					if (resizeManagedAttributes.has(key)) return;
					if (value != null) el.setAttribute(key, value);
					else el.removeAttribute(key);
				});
				syncImageSource(newHTMLAttributes.src);
				previousHTMLAttributes = newHTMLAttributes;
				return true;
			};
			const nodeView = new ResizableNodeView({
				element: el,
				editor,
				node,
				getPos,
				onResize: (width, height) => {
					el.style.width = `${width}px`;
					el.style.height = `${height}px`;
				},
				onCommit: (width, height) => {
					const pos = getPos();
					if (pos === void 0) return;
					this.editor.chain().setNodeSelection(pos).updateAttributes(this.name, {
						width,
						height
					}).run();
				},
				onUpdate,
				options: {
					directions,
					min: {
						width: minWidth,
						height: minHeight
					},
					preserveAspectRatio: alwaysPreserveAspectRatio === true
				}
			});
			const dom = nodeView.dom;
			const showNodeView = () => {
				dom.style.visibility = "";
				dom.style.pointerEvents = "";
			};
			dom.style.visibility = "hidden";
			dom.style.pointerEvents = "none";
			if (el.complete && el.naturalWidth > 0) showNodeView();
			else {
				el.onload = showNodeView;
				el.onerror = showNodeView;
			}
			return nodeView;
		};
	},
	addCommands() {
		return { setImage: (options) => ({ commands }) => {
			return commands.insertContent({
				type: this.name,
				attrs: options
			});
		} };
	},
	addInputRules() {
		return [nodeInputRule({
			find: inputRegex,
			type: this.type,
			getAttributes: (match) => {
				const [, , alt, src, title] = match;
				return {
					src,
					alt,
					title
				};
			}
		})];
	}
}).extend({ addAttributes() {
	return {
		...this.parent?.(),
		width: {
			default: null,
			parseHTML: (el) => el.getAttribute("width"),
			renderHTML: (attrs) => attrs.width ? { width: attrs.width } : {}
		},
		height: {
			default: null,
			parseHTML: (el) => el.getAttribute("height"),
			renderHTML: (attrs) => attrs.height ? { height: attrs.height } : {}
		}
	};
} });
function createEditorImageExtension() {
	return { extensions: [ImageWithDimensions.configure({ allowBase64: false })] };
}
//#endregion
//#region src/components/admin/RadioField.tsx
function RadioOption({ option }) {
	const id = (0, import_react.useId)();
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex items-center gap-2",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Radio, {
			value: option.value,
			id
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
			htmlFor: id,
			className: "text-sm text-fg",
			children: option.label
		})]
	});
}
function RadioField({ label, value, onValueChange, options, disabled }) {
	const labelId = (0, import_react.useId)();
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-2",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
			id: labelId,
			className: "text-sm font-medium text-fg",
			children: label
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroup, {
			value,
			onValueChange,
			"aria-labelledby": labelId,
			disabled,
			children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioOption, { option }, option.value))
		})]
	});
}
//#endregion
//#region src/components/MediaPickerDialog.tsx
var client = createHostMediaClient();
function MediaPickerDialog({ disabled = false, onSelect }) {
	const [open, setOpen] = (0, import_react.useState)(false);
	const [pending, setPending] = (0, import_react.useState)(null);
	const [alt, setAlt] = (0, import_react.useState)("");
	const altInput = (0, import_react.useRef)(null);
	const mediaSelection = (0, import_react.useRef)(null);
	const focusUploadAfterReset = (0, import_react.useRef)(false);
	(0, import_react.useEffect)(() => {
		if (pending) {
			altInput.current?.focus();
			return;
		}
		if (focusUploadAfterReset.current) {
			focusUploadAfterReset.current = false;
			mediaSelection.current?.querySelector("input[type=\"file\"]")?.focus();
		}
	}, [pending]);
	function reset() {
		setPending(null);
		setAlt("");
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Dialog, {
		open,
		onOpenChange: (next) => {
			setOpen(next);
			if (!next) reset();
		},
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTrigger, {
			asChild: true,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				tone: "surface",
				radius: "sm",
				size: "sm",
				type: "button",
				disabled,
				children: "Insert media"
			})
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle, { children: "Insert media" }), pending === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: "Choose an uploaded image to insert into the post body." }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			ref: mediaSelection,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MediaLibrary, {
				client,
				onSelect: (item) => setPending(item),
				allowDelete: false
			})
		})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: "Describe the image for screen readers, then insert it. Leave the description empty only for a decorative image." }),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
				src: pending.url,
				alt,
				width: pending.width,
				height: pending.height,
				className: "media-picker__preview"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
				label: "Alt text",
				hint: "A short description of the image.",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
					ref: altInput,
					value: alt,
					onChange: (e) => setAlt(e.target.value)
				})
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				tone: "surface",
				radius: "sm",
				size: "sm",
				type: "button",
				onClick: () => {
					focusUploadAfterReset.current = true;
					reset();
				},
				children: "Choose a different image"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				tone: "accent",
				radius: "sm",
				size: "sm",
				type: "button",
				onClick: () => {
					if (onSelect(pending, alt)) setOpen(false);
				},
				children: "Insert image"
			})
		] })] })]
	});
}
//#endregion
//#region src/components/admin/block-editor/BlockDocumentEditor.tsx
function BlockDocumentEditor({ current, definitions, disabled, onChange }) {
	const initial = current?.document ?? {
		version: 1,
		roots: []
	};
	const [text, setText] = (0, import_react.useState)(() => JSON.stringify(initial, null, 2)), [error, setError] = (0, import_react.useState)(null);
	(0, import_react.useEffect)(() => {
		const next = current?.document ?? {
			version: 1,
			roots: []
		};
		setText(JSON.stringify(next, null, 2));
		setError(null);
		onChange(next, true);
	}, [current?.version]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "admin-form__section",
		"aria-labelledby": "block-document-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
				id: "block-document-heading",
				className: "text-lg font-medium text-fg",
				children: "Blocks"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
				className: "text-sm text-fg-muted",
				children: [
					"Canonical block document. Available blocks: ",
					definitions.length ? definitions.map((item) => item.key).join(", ") : "none",
					"."
				]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
				"aria-label": "Block document JSON",
				className: "min-h-72 w-full rounded-[2px] border border-border bg-canvas p-3 font-mono text-xs text-fg",
				disabled,
				value: text,
				onChange: (event) => {
					const next = event.currentTarget.value;
					setText(next);
					try {
						const parsed = JSON.parse(next);
						setError(null);
						onChange(parsed, true);
					} catch {
						setError("Block document must be valid JSON.");
						onChange(initial, false);
					}
				}
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "admin-form__error",
				role: "alert",
				children: error
			}) : null
		]
	});
}
//#endregion
//#region src/components/admin/revisions/LinkedRevisionsPanel.tsx
function LinkedRevisionsPanel({ revisions, busy, onRestore }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "admin-form__section",
		"aria-labelledby": "revisions-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
			id: "revisions-heading",
			className: "text-lg font-medium text-fg",
			children: "Revisions"
		}), revisions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
			className: "text-sm text-fg-muted",
			children: "No revisions yet."
		}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			className: "flex flex-col gap-2",
			children: revisions.map((revision) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex items-center justify-between gap-3 rounded-[2px] border border-border bg-surface p-3",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
					className: "text-sm font-medium text-fg",
					children: ["Revision ", revision.seq]
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
					className: "text-xs text-fg-muted",
					children: [
						revision.createdAt,
						" · ",
						revision.editor,
						revision.fieldsRevisionId ? " · linked fields" : " · content only"
					]
				})] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					radius: "sm",
					size: "sm",
					type: "button",
					disabled: busy || !revision.fieldsRevisionId,
					onClick: () => onRestore(revision),
					children: "Restore"
				})]
			}, `${revision.id}:${revision.fieldsRevisionId ?? "none"}`))
		})]
	});
}
//#endregion
//#region src/components/admin/content-editor/FieldGroupsEditor.tsx
function FieldGroupsEditor({ groups, texts, disabled, onText }) {
	if (groups.length === 0) return null;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "admin-form__section",
		"aria-labelledby": "content-fields-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
			id: "content-fields-heading",
			className: "text-lg font-medium text-fg",
			children: "Custom fields"
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			className: "flex flex-col gap-4",
			children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
				className: "flex flex-col gap-2 text-sm text-fg",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
					className: "font-medium",
					children: [
						group.definition.title,
						" ",
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
							className: "font-normal text-fg-muted",
							children: [
								"· ",
								group.definition.key,
								" · revision ",
								group.valueRevision
							]
						})
					]
				}), group.writable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
					"aria-label": `${group.definition.title} values JSON`,
					className: "min-h-36 rounded-[2px] border border-border bg-canvas p-3 font-mono text-xs",
					disabled,
					value: texts[group.definition.key] ?? "{}",
					onChange: (event) => onText(group.definition.key, event.currentTarget.value)
				}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
					"aria-label": `${group.definition.title} values JSON`,
					className: "min-h-28 rounded-[2px] border border-border bg-surface p-3 font-mono text-xs",
					disabled: true,
					value: texts[group.definition.key] ?? "{}"
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
					className: "text-xs text-warning",
					children: [
						"Read-only: ",
						group.disabledReason ?? "unsupported field capability",
						"."
					]
				})] })]
			}, `${group.definition.key}:${group.valueRevision}`))
		})]
	});
}
//#endregion
//#region src/components/admin/content-editor/content-model-editor-client.ts
var ContentModelEditorClientError = class extends Error {
	code;
	constructor(code, message) {
		super(message);
		this.code = code;
		this.name = "ContentModelEditorClientError";
	}
};
function record(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
function string(value) {
	return typeof value === "string";
}
function editorSnapshotShape(value) {
	if (!record(value) || !record(value.entry) || !record(value.type) || !record(value.blocks)) return false;
	const entry = value.entry, type = value.type, labels = type.labels;
	if (!record(labels)) return false;
	return string(entry.id) && string(entry.title) && string(entry.slug) && string(entry.body) && string(entry.status) && string(entry.author) && string(entry.updatedAt) && [
		"public",
		"private",
		"members"
	].includes(String(entry.visibility)) && Array.isArray(entry.terms) && string(type.key) && string(labels.singularName) && typeof type.revision === "number" && typeof type.hierarchical === "boolean" && Array.isArray(type.supports) && type.supports.every(string) && Array.isArray(type.taxonomies) && type.taxonomies.every(string) && string(value.fieldsVersion) && Array.isArray(value.statuses) && Array.isArray(value.fields) && Array.isArray(value.revisions) && typeof value.blocks.enabled === "boolean";
}
async function request(url, init) {
	const headers = new Headers(init?.headers);
	if (init?.body && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
	if (init?.method && init.method !== "GET" && !headers.has("origin")) headers.set("origin", window.location.origin);
	const response = await fetch(url, {
		...init,
		headers,
		credentials: "same-origin"
	}), body = await response.json().catch(() => null);
	if (!response.ok) {
		const error = body;
		throw new ContentModelEditorClientError(error?.error?.code ?? "request_failed", error?.error?.message ?? response.statusText);
	}
	return body;
}
async function editorSnapshot(id) {
	const value = await request(`/api/admin/content-model/editor?id=${encodeURIComponent(id)}`);
	if (!editorSnapshotShape(value)) throw new ContentModelEditorClientError("invalid_response", "Editor snapshot response is malformed.");
	return value;
}
function editorSave(id, input) {
	return request("/api/admin/content-model/editor", {
		method: "POST",
		body: JSON.stringify({
			action: "save",
			id,
			...input
		})
	});
}
function editorRestore(id, input) {
	return request("/api/admin/content-model/editor", {
		method: "POST",
		body: JSON.stringify({
			action: "restore",
			id,
			...input
		})
	});
}
function editorTransition(id, input) {
	return request("/api/admin/content-model/editor", {
		method: "POST",
		body: JSON.stringify({
			action: "transition",
			id,
			...input
		})
	});
}
//#endregion
//#region src/components/admin/content-editor/TypeAwareContentEditor.tsx
var VISIBILITY = [
	"public",
	"private",
	"members"
];
function asIso(value) {
	return value instanceof Date ? value.toISOString() : String(value);
}
function operationId$1(kind) {
	return `editor:${kind}:${globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`}`;
}
function jsonValues(snapshot) {
	return Object.fromEntries(snapshot.fields.map((group) => [group.definition.key, JSON.stringify(group.values, null, 2)]));
}
function supports(snapshot, key) {
	return snapshot.type.supports.includes(key);
}
function dateInputIso(value) {
	if (!value) return void 0;
	const date = new Date(value);
	return Number.isNaN(date.getTime()) ? void 0 : date.toISOString();
}
function TypeAwareContentEditor({ entryId }) {
	const { toast } = useToast(), [snapshot, setSnapshot] = (0, import_react.useState)(null), [loading, setLoading] = (0, import_react.useState)(true), [busy, setBusy] = (0, import_react.useState)(false), [error, setError] = (0, import_react.useState)(null);
	const [title, setTitle] = (0, import_react.useState)(""), [slug, setSlug] = (0, import_react.useState)(""), [visibility, setVisibility] = (0, import_react.useState)("public"), [body, setBody] = (0, import_react.useState)(""), [excerpt, setExcerpt] = (0, import_react.useState)(""), [author, setAuthor] = (0, import_react.useState)(""), [parentId, setParentId] = (0, import_react.useState)(""), [templateKey, setTemplateKey] = (0, import_react.useState)(""), [menuOrder, setMenuOrder] = (0, import_react.useState)("0"), [featuredMediaId, setFeaturedMediaId] = (0, import_react.useState)(""), [commentStatus, setCommentStatus] = (0, import_react.useState)("open"), [pingStatus, setPingStatus] = (0, import_react.useState)("closed"), [format, setFormat] = (0, import_react.useState)(""), [termIds, setTermIds] = (0, import_react.useState)("");
	const [fieldTexts, setFieldTexts] = (0, import_react.useState)({}), [blockDocument, setBlockDocument] = (0, import_react.useState)({
		version: 1,
		roots: []
	}), [blockValid, setBlockValid] = (0, import_react.useState)(true), [statusTarget, setStatusTarget] = (0, import_react.useState)(""), [transitionAt, setTransitionAt] = (0, import_react.useState)("");
	const hydrate = (0, import_react.useCallback)((next) => {
		setSnapshot(next);
		const entry = next.entry;
		setTitle(entry.title);
		setSlug(entry.slug);
		setVisibility(entry.visibility);
		setBody(entry.body);
		setExcerpt(entry.excerpt ?? "");
		setAuthor(entry.author);
		setParentId(entry.parentId ?? "");
		setTemplateKey(entry.templateKey ?? "");
		setMenuOrder(String(entry.menuOrder ?? 0));
		setFeaturedMediaId(entry.featuredMedia?.id ?? "");
		setCommentStatus(entry.commentStatus ?? "open");
		setPingStatus(entry.pingStatus ?? "closed");
		setFormat(entry.format ?? "");
		setTermIds(entry.terms.map((term) => term.id).join(", "));
		setFieldTexts(jsonValues(next));
		setBlockDocument(next.blocks.document?.document ?? {
			version: 1,
			roots: []
		});
		setBlockValid(true);
		setStatusTarget(entry.status);
		setTransitionAt("");
	}, []);
	const reload = (0, import_react.useCallback)(async () => {
		setLoading(true);
		setError(null);
		try {
			hydrate(await editorSnapshot(entryId));
		} catch (reason) {
			setError(reason instanceof Error ? reason.message : "Editor could not be loaded.");
		} finally {
			setLoading(false);
		}
	}, [entryId, hydrate]);
	(0, import_react.useEffect)(() => {
		reload();
	}, [reload]);
	const targetStatus = (0, import_react.useMemo)(() => snapshot?.statuses.find((status) => status.key === statusTarget), [snapshot, statusTarget]);
	async function save() {
		if (!snapshot || busy) return;
		setBusy(true);
		setError(null);
		try {
			const patch = {
				slug,
				visibility
			};
			if (supports(snapshot, "title")) patch.title = title;
			if (supports(snapshot, "editor") && !supports(snapshot, "blocks")) patch.body = body;
			if (supports(snapshot, "excerpt")) patch.excerpt = excerpt;
			if (supports(snapshot, "author")) patch.author = author;
			if (snapshot.type.hierarchical) patch.parentId = parentId || null;
			if (supports(snapshot, "pageAttributes")) {
				patch.menuOrder = Number(menuOrder);
				patch.templateKey = templateKey || null;
			}
			if (supports(snapshot, "featuredImage")) patch.featuredMedia = featuredMediaId ? { id: featuredMediaId } : null;
			if (supports(snapshot, "comments")) patch.commentStatus = commentStatus;
			if (supports(snapshot, "trackbacks")) patch.pingStatus = pingStatus;
			if (supports(snapshot, "postFormats")) patch.format = format || null;
			if (snapshot.type.taxonomies.length) patch.termIds = termIds.split(",").map((value) => value.trim()).filter(Boolean);
			const fieldValues = {};
			for (const group of snapshot.fields) {
				if (!group.writable) continue;
				try {
					const parsed = JSON.parse(fieldTexts[group.definition.key] ?? "{}");
					if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error();
					fieldValues[group.definition.key] = parsed;
				} catch {
					throw new ContentModelEditorClientError("validation_error", `${group.definition.title} values must be a JSON object.`);
				}
			}
			await editorSave(entryId, {
				operationId: operationId$1("save"),
				expectedUpdatedAt: asIso(snapshot.entry.updatedAt),
				patch,
				...Object.keys(fieldValues).length || snapshot.blocks.enabled ? { expectedFieldsVersion: snapshot.fieldsVersion } : {},
				...Object.keys(fieldValues).length ? { fieldValues } : {},
				...snapshot.blocks.enabled ? {
					blockDocument,
					expectedBlockVersion: snapshot.blocks.document?.version ?? "0"
				} : {}
			});
			toast({
				title: "Content saved",
				tone: "success"
			});
			await reload();
		} catch (reason) {
			setError(reason instanceof Error ? reason.message : "Content could not be saved.");
		} finally {
			setBusy(false);
		}
	}
	async function transition() {
		if (!snapshot || !targetStatus || statusTarget === snapshot.entry.status || busy) return;
		setBusy(true);
		setError(null);
		try {
			const at = dateInputIso(transitionAt), input = {
				operationId: operationId$1("transition"),
				expectedUpdatedAt: asIso(snapshot.entry.updatedAt),
				expectedFieldsVersion: snapshot.fieldsVersion,
				to: statusTarget
			};
			if (targetStatus.transitionInput === "scheduleAt") {
				if (!at) throw new ContentModelEditorClientError("validation_error", "Choose a valid future schedule time.");
				input.scheduleAt = at;
			} else if (targetStatus.transitionInput === "publishedAt" && at) input.publishedAt = at;
			await editorTransition(entryId, input);
			toast({
				title: `Status changed to ${targetStatus.label}`,
				tone: "success"
			});
			await reload();
		} catch (reason) {
			setError(reason instanceof Error ? reason.message : "Status could not be changed.");
		} finally {
			setBusy(false);
		}
	}
	async function restore(revision) {
		if (!snapshot || !revision.fieldsRevisionId || busy) return;
		setBusy(true);
		setError(null);
		try {
			await editorRestore(entryId, {
				operationId: operationId$1("restore"),
				expectedUpdatedAt: asIso(snapshot.entry.updatedAt),
				expectedFieldsVersion: snapshot.fieldsVersion,
				contentRevisionId: revision.id,
				fieldsRevisionId: revision.fieldsRevisionId
			});
			toast({
				title: `Revision ${revision.seq} restored`,
				tone: "success"
			});
			await reload();
		} catch (reason) {
			setError(reason instanceof Error ? reason.message : "Revision could not be restored.");
		} finally {
			setBusy(false);
		}
	}
	async function translate() {
		setBusy(true);
		try {
			if (!(await fetch("/api/admin/content/translate", {
				method: "POST",
				credentials: "same-origin",
				headers: {
					"Content-Type": "application/json",
					origin: window.location.origin
				},
				body: JSON.stringify({ id: entryId })
			})).ok) throw new Error("Translation request failed.");
			toast({
				title: "Translations queued for active locales",
				tone: "success"
			});
		} catch (reason) {
			setError(reason instanceof Error ? reason.message : "Translation request failed.");
		} finally {
			setBusy(false);
		}
	}
	if (loading && !snapshot) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
		className: "text-sm text-fg-muted",
		children: "Loading editor…"
	});
	if (!snapshot) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
		className: "admin-form__error",
		role: "alert",
		children: error ?? "Editor unavailable."
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "editor-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "editor-heading",
				title: `Edit ${snapshot.type.labels.singularName}`,
				description: `${snapshot.type.labels.singularName} · ${snapshot.type.key} · type revision ${snapshot.type.revision}`,
				actions: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					radius: "sm",
					size: "sm",
					type: "button",
					disabled: busy,
					onClick: () => void translate(),
					children: "Translate content"
				})
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "admin-form",
				"aria-busy": busy,
				children: [
					supports(snapshot, "title") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Title",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							"aria-label": "Title",
							value: title,
							disabled: busy,
							onChange: (event) => setTitle(event.currentTarget.value)
						})
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Slug",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							"aria-label": "Slug",
							value: slug,
							disabled: busy,
							onChange: (event) => setSlug(event.currentTarget.value)
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
						className: "flex flex-col gap-2 text-sm text-fg",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							className: "font-medium",
							children: "Visibility"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
							"aria-label": "Visibility",
							className: "rounded-[2px] border border-border bg-canvas p-2",
							disabled: busy,
							value: visibility,
							onChange: (event) => setVisibility(event.currentTarget.value),
							children: VISIBILITY.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: item,
								children: item
							}, item))
						})]
					}),
					supports(snapshot, "editor") && !supports(snapshot, "blocks") ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "admin-form__field",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							className: "text-sm font-medium text-fg",
							children: "Body"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorWidget, {
							value: body,
							onChange: setBody,
							ariaLabel: "Body",
							readOnly: busy
						})]
					}) : null,
					supports(snapshot, "excerpt") ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
						className: "flex flex-col gap-2 text-sm",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							className: "font-medium",
							children: "Excerpt"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
							"aria-label": "Excerpt",
							className: "min-h-24 rounded-[2px] border border-border bg-canvas p-2",
							disabled: busy,
							value: excerpt,
							onChange: (event) => setExcerpt(event.currentTarget.value)
						})]
					}) : null,
					supports(snapshot, "author") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Author",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							"aria-label": "Author",
							disabled: busy,
							value: author,
							onChange: (event) => setAuthor(event.currentTarget.value)
						})
					}) : null,
					snapshot.type.hierarchical ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Parent ID",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							"aria-label": "Parent ID",
							disabled: busy,
							value: parentId,
							onChange: (event) => setParentId(event.currentTarget.value)
						})
					}) : null,
					supports(snapshot, "pageAttributes") ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "grid gap-4 md:grid-cols-2",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Template key",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								"aria-label": "Template key",
								disabled: busy,
								value: templateKey,
								onChange: (event) => setTemplateKey(event.currentTarget.value)
							})
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Menu order",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								"aria-label": "Menu order",
								type: "number",
								disabled: busy,
								value: menuOrder,
								onChange: (event) => setMenuOrder(event.currentTarget.value)
							})
						})]
					}) : null,
					supports(snapshot, "featuredImage") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Featured media ID",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							"aria-label": "Featured media ID",
							disabled: busy,
							value: featuredMediaId,
							onChange: (event) => setFeaturedMediaId(event.currentTarget.value)
						})
					}) : null,
					snapshot.type.taxonomies.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Term IDs",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							"aria-label": "Term IDs",
							disabled: busy,
							value: termIds,
							onChange: (event) => setTermIds(event.currentTarget.value)
						})
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "grid gap-4 md:grid-cols-3",
						children: [
							supports(snapshot, "comments") ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm",
								children: ["Comments", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
									"aria-label": "Comment status",
									className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
									disabled: busy,
									value: commentStatus,
									onChange: (event) => setCommentStatus(event.currentTarget.value),
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: "open",
										children: "open"
									}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: "closed",
										children: "closed"
									})]
								})]
							}) : null,
							supports(snapshot, "trackbacks") ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm",
								children: ["Trackbacks", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
									"aria-label": "Ping status",
									className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
									disabled: busy,
									value: pingStatus,
									onChange: (event) => setPingStatus(event.currentTarget.value),
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: "open",
										children: "open"
									}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: "closed",
										children: "closed"
									})]
								})]
							}) : null,
							supports(snapshot, "postFormats") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
								label: "Format",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									"aria-label": "Format",
									disabled: busy,
									value: format,
									onChange: (event) => setFormat(event.currentTarget.value)
								})
							}) : null
						]
					}),
					snapshot.blocks.enabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlockDocumentEditor, {
						current: snapshot.blocks.document,
						definitions: snapshot.blocks.definitions ?? [],
						disabled: busy,
						onChange: (document, valid) => {
							setBlockDocument(document);
							setBlockValid(valid);
						}
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldGroupsEditor, {
						groups: snapshot.fields,
						texts: fieldTexts,
						disabled: busy,
						onText: (key, value) => setFieldTexts((current) => ({
							...current,
							[key]: value
						}))
					}),
					error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "admin-form__error",
						role: "alert",
						children: error
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						className: "admin-form__actions",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "accent",
							radius: "sm",
							size: "base",
							type: "button",
							disabled: busy || !blockValid,
							onClick: () => void save(),
							children: busy ? "Working…" : "Save changes"
						})
					})
				]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
				className: "admin-form__section",
				"aria-labelledby": "status-heading",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
					id: "status-heading",
					className: "text-lg font-medium text-fg",
					children: "Status"
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "grid gap-3 md:grid-cols-[1fr_1fr_auto]",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "text-sm",
							children: ["Target", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
								"aria-label": "Target status",
								className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
								disabled: busy,
								value: statusTarget,
								onChange: (event) => {
									setStatusTarget(event.currentTarget.value);
									setTransitionAt("");
								},
								children: snapshot.statuses.map((status) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: status.key,
									children: status.label
								}, status.key))
							})]
						}),
						targetStatus?.transitionInput !== "none" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "text-sm",
							children: [targetStatus?.transitionInput === "scheduleAt" ? "Schedule at" : "Publication time (optional)", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								"aria-label": "Transition time",
								type: "datetime-local",
								disabled: busy,
								value: transitionAt,
								onChange: (event) => setTransitionAt(event.currentTarget.value)
							})]
						}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "surface",
							radius: "sm",
							size: "sm",
							type: "button",
							disabled: busy || statusTarget === snapshot.entry.status,
							onClick: () => void transition(),
							children: "Change status"
						})
					]
				})]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LinkedRevisionsPanel, {
				revisions: snapshot.revisions,
				busy,
				onRestore: (revision) => void restore(revision)
			})
		]
	});
}
//#endregion
//#region src/components/admin/EditorScreen.tsx
var VISIBILITY_OPTIONS = [
	{
		value: "public",
		label: "Public"
	},
	{
		value: "private",
		label: "Private"
	},
	{
		value: "members",
		label: "Members"
	}
];
var MAX_CONTENT_BODY_BYTES = 1e6;
var BODY_ENCODER = new TextEncoder();
var FIELD_ORDER = [
	"title",
	"slug",
	"type",
	"visibility",
	"body"
];
async function fieldsApiFetch$1(url, init) {
	const headers = new Headers(init?.headers);
	if (init?.body != null && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
	if (init?.method && init.method !== "GET" && !headers.has("origin")) headers.set("origin", window.location.origin);
	const res = await fetch(url, {
		...init,
		credentials: "same-origin",
		headers
	});
	const body = await res.json().catch(() => null);
	if (!res.ok) throw new Error(body?.error?.message ?? res.statusText);
	return body;
}
function makeFieldsClient$1() {
	return {
		async getEntityValues(ref, opts) {
			const params = new URLSearchParams({
				entityId: ref.entityId,
				entityType: ref.entityType
			});
			if (opts.subType) params.set("subType", opts.subType);
			return (await fieldsApiFetch$1(`/api/admin/fields?${params}`)).values;
		},
		async setEntityValues({ ref, groupId, values }) {
			await fieldsApiFetch$1("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "setValues",
					entityId: ref.entityId,
					groups: [{
						groupId,
						values
					}]
				})
			});
		},
		async resolveGroups(opts) {
			const params = new URLSearchParams({
				resource: "resolve-groups",
				entityType: opts.entityType
			});
			if (opts.subType) params.set("subType", opts.subType);
			return (await fieldsApiFetch$1(`/api/admin/fields?${params}`)).groups;
		},
		async listGroups(opts) {
			const params = new URLSearchParams({ resource: "groups" });
			if (opts.entityType) params.set("entityType", opts.entityType);
			if (opts.subType) params.set("subType", opts.subType);
			return (await fieldsApiFetch$1(`/api/admin/fields?${params}`)).groups;
		},
		async createGroup(group) {
			return (await fieldsApiFetch$1("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "createGroup",
					group
				})
			})).group;
		},
		async updateGroup(id, patch) {
			return (await fieldsApiFetch$1("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "updateGroup",
					id,
					patch
				})
			})).group;
		},
		async deleteGroup(id) {
			await fieldsApiFetch$1("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "deleteGroup",
					id
				})
			});
		}
	};
}
function groupIdOf(group) {
	return group.id ?? group.key;
}
function CustomFieldsPanel({ entry, disabled }) {
	const client = (0, import_react.useMemo)(() => makeFieldsClient$1(), []);
	const [groups, setGroups] = (0, import_react.useState)([]);
	const [initialValues, setInitialValues] = (0, import_react.useState)({});
	const [loading, setLoading] = (0, import_react.useState)(true);
	const [error, setError] = (0, import_react.useState)(null);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		setLoading(true);
		setError(null);
		(async () => {
			try {
				const resolved = await client.resolveGroups({
					entityType: "content",
					subType: entry.type
				});
				const values = await client.getEntityValues({
					entityType: "content",
					entityId: entry.id
				}, { subType: entry.type });
				if (cancelled) return;
				const perGroup = {};
				for (const group of resolved) {
					const id = groupIdOf(group);
					const slice = {};
					for (const field of group.fields) if (values[field.key] !== void 0) slice[field.key] = values[field.key];
					perGroup[id] = slice;
				}
				setGroups(resolved);
				setInitialValues(perGroup);
				setLoading(false);
			} catch (e) {
				if (!cancelled) {
					setError(e instanceof Error ? e.message : "Failed to load custom fields.");
					setLoading(false);
				}
			}
		})();
		return () => {
			cancelled = true;
		};
	}, [
		client,
		entry.id,
		entry.type
	]);
	const handleSave = (0, import_react.useCallback)(async (payload) => {
		await fieldsApiFetch$1("/api/admin/fields", {
			method: "POST",
			body: JSON.stringify({
				action: "setValues",
				entityId: entry.id,
				groups: payload
			})
		});
	}, [entry.id]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "admin-form__section",
		"aria-labelledby": "custom-fields-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
				id: "custom-fields-heading",
				className: "text-lg font-medium text-fg",
				children: "Custom Fields"
			}),
			loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "text-sm text-fg-muted",
				children: "Loading custom fields…"
			}) : null,
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "admin-form__error",
				role: "alert",
				children: error
			}) : null,
			!loading && !error && groups.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldsProvider, {
				client,
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldValuesForm, {
					groups,
					initialValues,
					onSubmit: handleSave,
					disabled
				}, entry.id)
			}) : null
		]
	});
}
function clientFieldErrors(title, slug, type, visibility, body) {
	const errors = {};
	if (!title.trim()) errors.title = "Title is required.";
	if (!slug.trim()) errors.slug = "Slug is required.";
	if (!type.trim()) errors.type = "Type is required.";
	if (!VISIBILITY_OPTIONS.some((option) => option.value === visibility)) errors.visibility = "Choose a valid visibility.";
	if (BODY_ENCODER.encode(body).byteLength > MAX_CONTENT_BODY_BYTES) errors.body = `Body must not exceed ${MAX_CONTENT_BODY_BYTES} UTF-8 bytes.`;
	return errors;
}
function isEditorField(value) {
	return value !== void 0 && FIELD_ORDER.includes(value);
}
function EditorScreenForEntry({ entry }) {
	const titleId = (0, import_react.useId)();
	const slugId = (0, import_react.useId)();
	const typeId = (0, import_react.useId)();
	const visibilityErrorId = (0, import_react.useId)();
	const bodyLabelId = (0, import_react.useId)();
	const bodyErrorId = (0, import_react.useId)();
	const client = (0, import_react.useMemo)(() => makeContentClient(), []);
	const { save, loading } = useContentEntry(client, entry);
	const { toast } = useToast();
	const titleRef = (0, import_react.useRef)(null);
	const slugRef = (0, import_react.useRef)(null);
	const typeRef = (0, import_react.useRef)(null);
	const visibilityRef = (0, import_react.useRef)(null);
	const bodyContainerRef = (0, import_react.useRef)(null);
	const pendingFocusRef = (0, import_react.useRef)(null);
	const [title, setTitle] = (0, import_react.useState)(entry?.title ?? "");
	const [slug, setSlug] = (0, import_react.useState)(entry?.slug ?? "");
	const [type, setType] = (0, import_react.useState)(entry?.type ?? "");
	const [visibility, setVisibility] = (0, import_react.useState)(entry?.visibility ?? "public");
	const [body, setBody] = (0, import_react.useState)(entry?.body ?? "");
	const bodyRef = (0, import_react.useRef)(body);
	const [fieldErrors, setFieldErrors] = (0, import_react.useState)({});
	const [formError, setFormError] = (0, import_react.useState)(null);
	const [saving, setSaving] = (0, import_react.useState)(false);
	const [translating, setTranslating] = (0, import_react.useState)(false);
	const media = (0, import_react.useMemo)(() => ({
		extensions: createEditorImageExtension(),
		renderPicker: ({ disabled, onSelect }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MediaPickerDialog, {
			disabled,
			onSelect: (item, alt) => onSelect({
				src: item.url,
				alt,
				...item.width === void 0 ? {} : { width: item.width },
				...item.height === void 0 ? {} : { height: item.height }
			})
		})
	}), []);
	(0, import_react.useEffect)(() => {
		const visibilityGroup = visibilityRef.current?.querySelector("[role=\"radiogroup\"]");
		if (visibilityGroup) {
			visibilityGroup.setAttribute("aria-invalid", fieldErrors.visibility ? "true" : "false");
			if (fieldErrors.visibility) visibilityGroup.setAttribute("aria-describedby", visibilityErrorId);
			else visibilityGroup.removeAttribute("aria-describedby");
		}
		const bodyTextbox = bodyContainerRef.current?.querySelector("[role=\"textbox\"]");
		if (bodyTextbox) {
			bodyTextbox.setAttribute("aria-labelledby", bodyLabelId);
			bodyTextbox.setAttribute("aria-invalid", fieldErrors.body ? "true" : "false");
			if (fieldErrors.body) bodyTextbox.setAttribute("aria-describedby", bodyErrorId);
			else bodyTextbox.removeAttribute("aria-describedby");
		}
	}, [
		bodyErrorId,
		bodyLabelId,
		entry?.id,
		fieldErrors.body,
		fieldErrors.visibility,
		visibilityErrorId
	]);
	const isEdit = entry != null;
	const savePending = saving || loading;
	(0, import_react.useEffect)(() => {
		const field = pendingFocusRef.current;
		if (!field || savePending || fieldErrors[field] === void 0) return;
		pendingFocusRef.current = null;
		focusField(field);
	}, [fieldErrors, savePending]);
	function clearFieldError(field) {
		setFieldErrors((current) => {
			if (current[field] === void 0) return current;
			const next = { ...current };
			delete next[field];
			return next;
		});
	}
	function focusField(field) {
		const focusVisibleEnabled = (target) => {
			if (!target || target.closest("[hidden], [aria-hidden=\"true\"]")) return false;
			if (target instanceof HTMLInputElement || target instanceof HTMLButtonElement) {
				if (target.disabled) return false;
			}
			target.focus();
			return document.activeElement === target;
		};
		if (field === "title") focusVisibleEnabled(titleRef.current);
		else if (field === "slug") focusVisibleEnabled(slugRef.current);
		else if (field === "type") focusVisibleEnabled(typeRef.current);
		else if (field === "visibility") focusVisibleEnabled(visibilityRef.current?.querySelector("[role=\"radio\"], input[type=\"radio\"]"));
		else {
			const container = bodyContainerRef.current;
			const focusEditor = () => {
				focusVisibleEnabled(container?.querySelector("[role=\"textbox\"]"));
			};
			const writeTab = container?.querySelector("[data-editor-widget-view=\"write\"]");
			if (writeTab?.getAttribute("aria-selected") === "false") {
				writeTab.click();
				window.setTimeout(focusEditor, 0);
			} else focusEditor();
		}
	}
	function applyFieldErrors(errors) {
		pendingFocusRef.current = FIELD_ORDER.find((field) => errors[field] !== void 0) ?? null;
		setFieldErrors(errors);
	}
	function handleBodyChange(nextHtml) {
		bodyRef.current = nextHtml;
		setBody(nextHtml);
		clearFieldError("body");
	}
	async function translateContent() {
		if (!entry) return;
		setTranslating(true);
		try {
			await fieldsApiFetch$1("/api/admin/content/translate", {
				method: "POST",
				body: JSON.stringify({ id: entry.id })
			});
			toast({
				title: "Translations queued for active locales",
				tone: "success"
			});
		} catch (translateError) {
			toast({
				title: translateError instanceof Error ? translateError.message : "Could not translate this content.",
				tone: "danger"
			});
		} finally {
			setTranslating(false);
		}
	}
	async function onSubmit(event) {
		event.preventDefault();
		setFormError(null);
		const currentBody = bodyRef.current;
		const validation = clientFieldErrors(title, slug, type, visibility, currentBody);
		if (Object.keys(validation).length > 0) {
			applyFieldErrors(validation);
			return;
		}
		setFieldErrors({});
		setSaving(true);
		try {
			if (await save({
				...entry?.id ? { id: entry.id } : {},
				slug,
				type,
				title,
				body: currentBody,
				visibility
			})) {
				window.location.assign("/admin");
				return;
			}
			setSaving(false);
		} catch (saveError) {
			setSaving(false);
			if (isAdminApiError(saveError) && isEditorField(saveError.field)) {
				applyFieldErrors({ [saveError.field]: saveError.message });
				return;
			}
			setFormError(saveError instanceof Error ? saveError.message : "The post could not be saved.");
		}
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "editor-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "editor-heading",
				title: isEdit ? "Edit post" : "New post",
				description: isEdit ? "Update this entry and save your changes." : "Draft a new entry for the editorial queue.",
				actions: isEdit ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					radius: "sm",
					size: "sm",
					type: "button",
					disabled: translating || savePending,
					onClick: () => void translateContent(),
					children: translating ? "Translating…" : "Translate content"
				}) : null
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
				className: "admin-form",
				onSubmit,
				noValidate: true,
				"aria-busy": savePending,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Title",
						htmlFor: titleId,
						required: true,
						error: fieldErrors.title,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							ref: titleRef,
							id: titleId,
							value: title,
							onChange: (event) => {
								setTitle(event.target.value);
								clearFieldError("title");
							},
							required: true,
							disabled: savePending
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Slug",
						htmlFor: slugId,
						required: true,
						error: fieldErrors.slug,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							ref: slugRef,
							id: slugId,
							value: slug,
							onChange: (event) => {
								setSlug(event.target.value);
								clearFieldError("slug");
							},
							required: true,
							disabled: savePending
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Type",
						htmlFor: typeId,
						required: true,
						error: fieldErrors.type,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							ref: typeRef,
							id: typeId,
							value: type,
							onChange: (event) => {
								setType(event.target.value);
								clearFieldError("type");
							},
							required: true,
							disabled: savePending
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						ref: visibilityRef,
						"aria-describedby": fieldErrors.visibility ? visibilityErrorId : void 0,
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioField, {
							label: "Visibility",
							value: visibility,
							onValueChange: (value) => {
								setVisibility(value);
								clearFieldError("visibility");
							},
							options: VISIBILITY_OPTIONS,
							disabled: savePending
						}), fieldErrors.visibility ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
							id: visibilityErrorId,
							className: "admin-form__error",
							role: "alert",
							children: fieldErrors.visibility
						}) : null]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						ref: bodyContainerRef,
						className: "admin-form__field",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
								id: bodyLabelId,
								className: "text-sm font-medium text-fg",
								children: "Body"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorWidget, {
								value: body,
								onChange: handleBodyChange,
								ariaLabel: "Body",
								ariaDescribedBy: fieldErrors.body ? bodyErrorId : void 0,
								readOnly: savePending,
								media,
								onError: (widgetError) => {
									if (isEditorWidgetError(widgetError)) setFormError(widgetError.message);
								}
							}),
							fieldErrors.body ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
								id: bodyErrorId,
								className: "admin-form__error",
								role: "alert",
								children: fieldErrors.body
							}) : null
						]
					}),
					formError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "admin-form__error",
						role: "alert",
						children: formError
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						className: "admin-form__actions",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "accent",
							radius: "sm",
							size: "base",
							type: "submit",
							disabled: savePending,
							children: savePending ? "Saving…" : isEdit ? "Save changes" : "Create post"
						})
					})
				]
			}),
			isEdit ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CustomFieldsPanel, {
				entry,
				disabled: savePending
			}) : null
		]
	});
}
function EditorScreen({ entry }) {
	if (entry) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TypeAwareContentEditor, { entryId: entry.id }, entry.id);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorScreenForEntry, { entry: null }, "new");
}
//#endregion
//#region src/components/admin/SettingsScreen.tsx
var MODE_OPTIONS = [
	{
		value: "light",
		label: "Light"
	},
	{
		value: "dark",
		label: "Dark"
	},
	{
		value: "system",
		label: "System"
	}
];
var HOMEPAGE_MODE_OPTIONS = [{
	value: "feed",
	label: "Feed"
}, {
	value: "page",
	label: "Page"
}];
var TOGGLE_VISIBILITY_OPTIONS = [{
	value: "shown",
	label: "Shown"
}, {
	value: "hidden",
	label: "Hidden"
}];
async function fetchSettings$1() {
	const res = await fetch("/api/admin/settings", { credentials: "same-origin" });
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	return body ?? {};
}
async function fetchPublishedPages() {
	return (await makeContentClient().list({
		status: "published",
		type: "page"
	})).filter((entry) => entry.type === "page").map((entry) => ({
		value: entry.slug,
		label: entry.title
	}));
}
async function putSetting$1(key, value) {
	const res = await fetch("/api/admin/settings", {
		method: "PUT",
		credentials: "same-origin",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({
			key,
			value
		})
	});
	if (!res.ok) {
		const message = (await res.json().catch(() => null))?.error?.message ?? res.statusText;
		throw new Error(message);
	}
}
async function fetchServiceTokens() {
	const res = await fetch("/api/admin/service-tokens", { credentials: "same-origin" });
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	return Array.isArray(body?.tokens) ? body.tokens ?? [] : [];
}
async function createServiceToken(label) {
	const res = await fetch("/api/admin/service-tokens", {
		method: "POST",
		credentials: "same-origin",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({ label })
	});
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	const payload = body;
	if (!payload?.id || !payload.token) throw new Error("Token response was incomplete");
	return {
		id: payload.id,
		token: payload.token
	};
}
async function deleteServiceToken(id) {
	const res = await fetch("/api/admin/service-tokens", {
		method: "DELETE",
		credentials: "same-origin",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({ id })
	});
	if (!res.ok) {
		const message = (await res.json().catch(() => null))?.error?.message ?? res.statusText;
		throw new Error(message);
	}
}
function formatDateTime(value) {
	if (!value) return "Never";
	return new Date(value).toLocaleString(void 0, {
		year: "numeric",
		month: "short",
		day: "numeric",
		hour: "2-digit",
		minute: "2-digit"
	});
}
function SettingsScreen() {
	const { toast } = useToast();
	const pageSelectLabelId = (0, import_react.useId)();
	const themeSelectLabelId = (0, import_react.useId)();
	const paletteSelectLabelId = (0, import_react.useId)();
	const issuedTokenRef = (0, import_react.useRef)(null);
	const [status, setStatus] = (0, import_react.useState)("loading");
	const [loadError, setLoadError] = (0, import_react.useState)("");
	const [mode, setMode] = (0, import_react.useState)(DEFAULT_SELECTION.mode);
	const [themeId, setThemeId] = (0, import_react.useState)(DEFAULT_SELECTION.themeId);
	const [paletteId, setPaletteId] = (0, import_react.useState)(DEFAULT_SELECTION.paletteId);
	const [siteName, setSiteName] = (0, import_react.useState)("");
	const [logoUrl, setLogoUrl] = (0, import_react.useState)("");
	const [homepageMode, setHomepageMode] = (0, import_react.useState)("feed");
	const [homepageSlug, setHomepageSlug] = (0, import_react.useState)("");
	const [hideModeToggle, setHideModeToggle] = (0, import_react.useState)(false);
	const [pages, setPages] = (0, import_react.useState)([]);
	const [saving, setSaving] = (0, import_react.useState)(false);
	const [saveError, setSaveError] = (0, import_react.useState)("");
	const [reloadKey, setReloadKey] = (0, import_react.useState)(0);
	const [serviceTokens, setServiceTokens] = (0, import_react.useState)([]);
	const [serviceTokensError, setServiceTokensError] = (0, import_react.useState)("");
	const [serviceTokenLabel, setServiceTokenLabel] = (0, import_react.useState)("");
	const [issuingToken, setIssuingToken] = (0, import_react.useState)(false);
	const [revokingTokenId, setRevokingTokenId] = (0, import_react.useState)(null);
	const [showIssuedToken, setShowIssuedToken] = (0, import_react.useState)(false);
	(0, import_react.useEffect)(() => {
		let active = true;
		setStatus("loading");
		Promise.all([
			fetchSettings$1(),
			fetchPublishedPages(),
			fetchServiceTokens()
		]).then(([settings, pageOptions, tokens]) => {
			if (!active) return;
			const homepage = parseHomepage(settings[SETTINGS_KEYS.homepage]);
			const sel = parseActiveSelection(settings[SETTINGS_KEYS.theme]);
			setMode(sel.mode);
			setThemeId(sel.themeId);
			setPaletteId(sel.paletteId);
			const rawName = settings[SETTINGS_KEYS.siteName];
			const rawLogo = settings[SETTINGS_KEYS.siteLogoUrl];
			setSiteName(typeof rawName === "string" ? rawName : "");
			setLogoUrl(typeof rawLogo === "string" ? rawLogo : "");
			setHomepageMode(homepage.mode);
			setHomepageSlug(homepage.mode === "page" ? homepage.slug : "");
			setHideModeToggle(parseHideModeToggle(settings[SETTINGS_KEYS.hideModeToggle]));
			setPages(pageOptions);
			setServiceTokens(tokens);
			setServiceTokensError("");
			setStatus("ready");
		}).catch((error) => {
			if (!active) return;
			setLoadError(error instanceof Error ? error.message : String(error));
			setStatus("error");
		});
		return () => {
			active = false;
		};
	}, [reloadKey]);
	const logoTrimmed = logoUrl.trim();
	const logoInvalid = logoTrimmed.length > 0 && !isValidLogoUrl(logoTrimmed);
	async function onSubmit(event) {
		event.preventDefault();
		setSaving(true);
		setSaveError("");
		try {
			await putSetting$1(SETTINGS_KEYS.theme, {
				themeId,
				paletteId,
				mode
			});
			await putSetting$1(SETTINGS_KEYS.homepage, homepageMode === "page" ? {
				mode: "page",
				slug: homepageSlug
			} : { mode: "feed" });
			await putSetting$1(SETTINGS_KEYS.siteName, siteName.trim());
			await putSetting$1(SETTINGS_KEYS.siteLogoUrl, logoTrimmed.length > 0 ? logoTrimmed : null);
			await putSetting$1(SETTINGS_KEYS.hideModeToggle, hideModeToggle);
			toast({
				title: "Settings saved",
				tone: "success"
			});
		} catch (error) {
			setSaveError(error instanceof Error ? error.message : String(error));
		} finally {
			setSaving(false);
		}
	}
	const saveDisabled = saving || logoInvalid || homepageMode === "page" && !homepageSlug;
	const createTokenDisabled = issuingToken || serviceTokenLabel.trim().length === 0;
	async function onCreateToken(event) {
		event.preventDefault();
		const label = serviceTokenLabel.trim();
		if (!label) return;
		setIssuingToken(true);
		setServiceTokensError("");
		try {
			const issued = await createServiceToken(label);
			setServiceTokens((current) => [{
				id: issued.id,
				label,
				createdAt: (/* @__PURE__ */ new Date()).toISOString(),
				expiresAt: null,
				lastUsedAt: null,
				status: "active"
			}, ...current]);
			setServiceTokenLabel("");
			if (issuedTokenRef.current) issuedTokenRef.current.value = issued.token;
			setShowIssuedToken(true);
			toast({
				title: "Token created",
				tone: "success"
			});
		} catch (error) {
			const message = error instanceof Error ? error.message : String(error);
			setServiceTokensError(message);
			toast({
				title: message,
				tone: "danger"
			});
		} finally {
			setIssuingToken(false);
		}
	}
	function dismissIssuedToken() {
		setShowIssuedToken(false);
		if (issuedTokenRef.current) issuedTokenRef.current.value = "";
	}
	async function copyIssuedToken() {
		const token = issuedTokenRef.current?.value ?? "";
		if (!token) return;
		await navigator.clipboard.writeText(token);
		toast({
			title: "Token copied",
			tone: "success"
		});
	}
	async function onRevokeToken(id) {
		const previousTokens = serviceTokens;
		setRevokingTokenId(id);
		setServiceTokensError("");
		setServiceTokens((current) => current.filter((token) => token.id !== id));
		try {
			await deleteServiceToken(id);
			toast({
				title: "Token revoked",
				tone: "success"
			});
		} catch (error) {
			const message = error instanceof Error ? error.message : String(error);
			setServiceTokens(previousTokens);
			setServiceTokensError(message);
			toast({
				title: message,
				tone: "danger"
			});
		} finally {
			setRevokingTokenId(null);
		}
	}
	if (status === "loading") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-4",
		"aria-hidden": "true",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
	});
	if (status === "error") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
		variant: "inline",
		title: "Settings couldn't load",
		message: loadError,
		action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
			tone: "accent",
			radius: "sm",
			size: "sm",
			type: "button",
			onClick: () => setReloadKey((k) => k + 1),
			children: "Try again"
		})
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "settings-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "settings-heading",
				title: "Settings",
				description: "Site-wide preferences for this instance."
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
				className: "admin-form",
				onSubmit,
				noValidate: true,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioField, {
						label: "Default theme mode",
						value: mode,
						onValueChange: (value) => setMode(value),
						options: MODE_OPTIONS
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex flex-col gap-2",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							id: themeSelectLabelId,
							className: "text-sm font-medium text-fg",
							children: "Presentation theme"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
							value: themeId,
							onValueChange: setThemeId,
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
								className: surface({
									tone: "surface",
									radius: "md",
									size: "base"
								}),
								"aria-labelledby": themeSelectLabelId,
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { placeholder: "Choose a theme" })
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, {
								className: surface({
									tone: "surface",
									radius: "md"
								}),
								children: THEME_REGISTRY_META.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
									className: surface({
										tone: "fg",
										size: "sm"
									}),
									value: t.id,
									children: t.name
								}, t.id))
							})]
						})]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex flex-col gap-2",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							id: paletteSelectLabelId,
							className: "text-sm font-medium text-fg",
							children: "Color palette"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PalettePicker, {
							value: paletteId,
							onChange: setPaletteId,
							options: paletteOptions(mode === "dark" ? "dark" : "light"),
							"aria-labelledby": paletteSelectLabelId
						})]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioField, {
						label: "Light/dark toggle on the site",
						value: hideModeToggle ? "hidden" : "shown",
						onValueChange: (v) => setHideModeToggle(v === "hidden"),
						options: TOGGLE_VISIBILITY_OPTIONS
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Site name",
						hint: "Shown in the header and footer. Leave blank to use the default.",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							value: siteName,
							onChange: (e) => setSiteName(e.target.value),
							maxLength: 100
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Logo URL",
						hint: "Optional. A full https:// image URL shown in the header in place of the site name.",
						error: logoInvalid ? "Enter a valid https:// URL." : void 0,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							type: "url",
							inputMode: "url",
							value: logoUrl,
							onChange: (e) => setLogoUrl(e.target.value),
							maxLength: 2048
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioField, {
						label: "Homepage",
						value: homepageMode,
						onValueChange: (value) => setHomepageMode(value),
						options: HOMEPAGE_MODE_OPTIONS
					}),
					homepageMode === "page" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex flex-col gap-2",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							id: pageSelectLabelId,
							className: "text-sm font-medium text-fg",
							children: "Homepage page"
						}), pages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
							className: "text-sm text-fg-muted",
							children: "No published pages yet. Publish a page to use it as the homepage."
						}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
							value: homepageSlug,
							onValueChange: setHomepageSlug,
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
								className: surface({
									tone: "surface",
									radius: "md",
									size: "base"
								}),
								"aria-labelledby": pageSelectLabelId,
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { placeholder: "Choose a page" })
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, {
								className: surface({
									tone: "surface",
									radius: "md"
								}),
								children: pages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
									className: surface({
										tone: "fg",
										size: "sm"
									}),
									value: page.value,
									children: page.label
								}, page.value))
							})]
						})]
					}) : null,
					saveError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "admin-form__error",
						role: "alert",
						children: saveError
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						className: "admin-form__actions",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "accent",
							radius: "sm",
							size: "base",
							type: "submit",
							disabled: saveDisabled,
							children: saving ? "Saving…" : "Save settings"
						})
					})
				]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "mt-8 flex flex-col gap-4",
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex flex-col gap-1",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
							className: "text-lg font-semibold text-fg",
							children: "Service tokens"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
							className: "text-sm text-fg-muted",
							children: "Mint bearer tokens for agents, MCP clients, and automation, then revoke them independently."
						})]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
						className: "flex flex-col gap-3 md:max-w-xl",
						onSubmit: onCreateToken,
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Token label",
							hint: "Name the caller or workflow that will use this token.",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								value: serviceTokenLabel,
								onChange: (event) => setServiceTokenLabel(event.target.value),
								maxLength: 200
							})
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
							className: "flex flex-wrap gap-2",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "accent",
								radius: "sm",
								size: "sm",
								type: "submit",
								disabled: createTokenDisabled,
								children: issuingToken ? "Creating…" : "Create token"
							})
						})]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						className: showIssuedToken ? "" : "hidden",
						role: "status",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: `${surface({
								tone: "surface",
								radius: "md",
								size: "base"
							})} flex flex-col gap-3 p-4`,
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
									className: "text-sm text-fg",
									children: "Copy it now. This token is shown only once and cannot be retrieved again after you dismiss this banner."
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									ref: issuedTokenRef,
									readOnly: true,
									defaultValue: "",
									"aria-label": "Issued token"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
									className: "flex flex-wrap gap-2",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
										tone: "surface",
										radius: "sm",
										size: "sm",
										type: "button",
										onClick: () => void copyIssuedToken(),
										children: "Copy token"
									}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
										tone: "surface",
										radius: "sm",
										size: "sm",
										type: "button",
										onClick: dismissIssuedToken,
										children: "Dismiss token"
									})]
								})
							]
						})
					}),
					serviceTokensError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "admin-form__error",
						role: "alert",
						children: serviceTokensError
					}) : null,
					serviceTokens.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						className: "admin-empty",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "No service tokens issued." })
					}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
						caption: "Service tokens",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Label"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Created"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Last used"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Actions"
							})
						] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: serviceTokens.map((token) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: token.label }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: formatDateTime(token.createdAt) }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: formatDateTime(token.lastUsedAt) }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "danger",
								radius: "sm",
								size: "sm",
								type: "button",
								disabled: revokingTokenId === token.id,
								onClick: () => void onRevokeToken(token.id),
								children: "Revoke"
							}) })
						] }, token.id)) })]
					})
				]
			})
		]
	});
}
//#endregion
//#region src/components/admin/MaintenanceScreen.tsx
var NON_OPERATOR_ROLES = [{
	value: "editor",
	label: "Editor"
}, {
	value: "viewer",
	label: "Viewer"
}];
async function fetchSettings() {
	const res = await fetch("/api/admin/settings", { credentials: "same-origin" });
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	return body ?? {};
}
async function putSetting(key, value) {
	const res = await fetch("/api/admin/settings", {
		method: "PUT",
		credentials: "same-origin",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({
			key,
			value
		})
	});
	if (!res.ok) {
		const message = (await res.json().catch(() => null))?.error?.message ?? res.statusText;
		throw new Error(message);
	}
}
function readMaintenanceForm(settings) {
	const m = settings[SETTINGS_KEYS.maintenance] ?? {};
	const allowRoles = Array.isArray(m.allowRoles) ? m.allowRoles.filter((r) => typeof r === "string") : [];
	return {
		enabled: m.enabled === true,
		message: typeof m.message === "string" ? m.message : "",
		allowRoles: allowRoles.filter((r) => NON_OPERATOR_ROLES.some((o) => o.value === r)),
		retryAfterSec: typeof m.retryAfterSec === "number" && Number.isFinite(m.retryAfterSec) ? m.retryAfterSec : 3600
	};
}
function MaintenanceScreen() {
	const { toast } = useToast();
	const [status, setStatus] = (0, import_react.useState)("loading");
	const [loadError, setLoadError] = (0, import_react.useState)("");
	const [enabled, setEnabled] = (0, import_react.useState)(false);
	const [message, setMessage] = (0, import_react.useState)("");
	const [retryAfterSec, setRetryAfterSec] = (0, import_react.useState)(3600);
	const [allowRoles, setAllowRoles] = (0, import_react.useState)([]);
	const [saving, setSaving] = (0, import_react.useState)(false);
	const [saveError, setSaveError] = (0, import_react.useState)("");
	const [reloadKey, setReloadKey] = (0, import_react.useState)(0);
	(0, import_react.useEffect)(() => {
		let active = true;
		setStatus("loading");
		fetchSettings().then((settings) => {
			if (!active) return;
			const form = readMaintenanceForm(settings);
			setEnabled(form.enabled);
			setMessage(form.message);
			setRetryAfterSec(form.retryAfterSec);
			setAllowRoles(form.allowRoles);
			setStatus("ready");
		}).catch((error) => {
			if (!active) return;
			setLoadError(error instanceof Error ? error.message : String(error));
			setStatus("error");
		});
		return () => {
			active = false;
		};
	}, [reloadKey]);
	function toggleRole(role, checked) {
		setAllowRoles((current) => {
			if (checked) return current.includes(role) ? current : [...current, role];
			return current.filter((r) => r !== role);
		});
	}
	async function onSubmit(event) {
		event.preventDefault();
		setSaving(true);
		setSaveError("");
		try {
			await putSetting(SETTINGS_KEYS.maintenance, {
				enabled,
				message,
				allowRoles,
				retryAfterSec
			});
			toast({
				title: "Maintenance settings saved",
				tone: "success"
			});
		} catch (error) {
			setSaveError(error instanceof Error ? error.message : String(error));
		} finally {
			setSaving(false);
		}
	}
	if (status === "loading") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-4",
		"aria-hidden": "true",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
	});
	if (status === "error") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
		variant: "inline",
		title: "Maintenance settings couldn't load",
		message: loadError,
		action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
			tone: "accent",
			radius: "sm",
			size: "sm",
			type: "button",
			onClick: () => setReloadKey((k) => k + 1),
			children: "Try again"
		})
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "maintenance-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "maintenance-heading",
				title: "Maintenance",
				description: "Control visitor access while you work on the site."
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				role: "note",
				className: "mb-6 max-w-2xl rounded-sm border border-border bg-surface p-4 text-sm text-fg",
				children: "Administrators always retain access — turning this on never locks you out."
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
				className: "admin-form",
				onSubmit,
				noValidate: true,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Maintenance mode",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch, {
							checked: enabled,
							onCheckedChange: setEnabled,
							"aria-label": "Enable maintenance mode"
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Visitor message",
						hint: "Shown to visitors while maintenance is on",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
							value: message,
							onChange: (event) => setMessage(event.target.value),
							rows: 4
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Retry after (seconds)",
						hint: "Sent as the Retry-After header on the 503 response",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							type: "number",
							min: 1,
							value: retryAfterSec,
							onChange: (event) => setRetryAfterSec(Number(event.target.value))
						})
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex flex-col gap-2",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
								className: "text-sm font-medium text-fg",
								children: "Additional roles allowed during maintenance"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
								className: "text-sm text-fg-muted",
								children: "Administrator and owner are always allowed and cannot be removed."
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
								className: "flex flex-col gap-3",
								children: NON_OPERATOR_ROLES.map((role) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
									className: "flex items-center gap-2 text-sm text-fg",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Checkbox, {
										"aria-label": role.label,
										checked: allowRoles.includes(role.value),
										onCheckedChange: (checked) => toggleRole(role.value, checked === true)
									}), role.label]
								}, role.value))
							})
						]
					}),
					saveError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "admin-form__error",
						role: "alert",
						children: saveError
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						className: "admin-form__actions",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "accent",
							radius: "sm",
							size: "base",
							type: "submit",
							disabled: saving,
							children: saving ? "Saving…" : "Save maintenance settings"
						})
					})
				]
			})
		]
	});
}
//#endregion
//#region src/components/admin/PrivacyConsentScreen.tsx
var CONSENT_CATEGORIES = [
	{
		value: "analytics",
		label: "Analytics"
	},
	{
		value: "marketing",
		label: "Marketing"
	},
	{
		value: "preferences",
		label: "Preferences"
	}
];
async function fetchPrivacy() {
	const res = await fetch("/api/admin/privacy", { credentials: "same-origin" });
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	return body ?? {};
}
async function savePrivacy(payload) {
	const res = await fetch("/api/admin/privacy", {
		method: "POST",
		credentials: "same-origin",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify(payload)
	});
	if (!res.ok) {
		const message = (await res.json().catch(() => null))?.error?.message ?? res.statusText;
		throw new Error(message);
	}
}
function linesToList(value) {
	return value.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
}
function mapThirdParties(rows) {
	return rows.map((row) => ({
		name: row.name.trim(),
		purpose: row.purpose.trim()
	})).filter((row) => row.name && row.purpose);
}
function mapCookies(rows) {
	return rows.map((row) => ({
		name: row.name.trim(),
		purpose: row.purpose.trim(),
		...Number.isFinite(Number(row.durationDays)) && Number(row.durationDays) > 0 ? { durationDays: Math.floor(Number(row.durationDays)) } : {}
	})).filter((row) => row.name && row.purpose);
}
function PrivacyConsentScreen() {
	const { toast } = useToast();
	const [status, setStatus] = (0, import_react.useState)("loading");
	const [loadError, setLoadError] = (0, import_react.useState)("");
	const [siteName, setSiteName] = (0, import_react.useState)("");
	const [contactEmail, setContactEmail] = (0, import_react.useState)("");
	const [jurisdiction, setJurisdiction] = (0, import_react.useState)("");
	const [dataCollectedText, setDataCollectedText] = (0, import_react.useState)("");
	const [thirdParties, setThirdParties] = (0, import_react.useState)([]);
	const [cookies, setCookies] = (0, import_react.useState)([]);
	const [consentEnabled, setConsentEnabled] = (0, import_react.useState)(false);
	const [categories, setCategories] = (0, import_react.useState)([
		"analytics",
		"marketing",
		"preferences"
	]);
	const [policyHref, setPolicyHref] = (0, import_react.useState)("/privacy");
	const [saving, setSaving] = (0, import_react.useState)(false);
	const [saveError, setSaveError] = (0, import_react.useState)("");
	const [reloadKey, setReloadKey] = (0, import_react.useState)(0);
	(0, import_react.useEffect)(() => {
		let active = true;
		setStatus("loading");
		fetchPrivacy().then((data) => {
			if (!active) return;
			const input = data.privacyInput;
			if (input) {
				setSiteName(typeof input.siteName === "string" ? input.siteName : "");
				setContactEmail(typeof input.contactEmail === "string" ? input.contactEmail : "");
				setJurisdiction(typeof input.jurisdiction === "string" ? input.jurisdiction : "");
				setDataCollectedText(Array.isArray(input.dataCollected) ? input.dataCollected.join("\n") : "");
				setThirdParties(Array.isArray(input.thirdParties) ? input.thirdParties.map((row) => ({
					name: typeof row.name === "string" ? row.name : "",
					purpose: typeof row.purpose === "string" ? row.purpose : ""
				})) : []);
				setCookies(Array.isArray(input.cookies) ? input.cookies.map((row) => ({
					name: typeof row.name === "string" ? row.name : "",
					purpose: typeof row.purpose === "string" ? row.purpose : "",
					durationDays: typeof row.durationDays === "number" && Number.isFinite(row.durationDays) ? String(row.durationDays) : ""
				})) : []);
			}
			const consent = data.consent;
			if (consent?.enabled === true) {
				setConsentEnabled(true);
				setPolicyHref(typeof consent.policyHref === "string" ? consent.policyHref : "/privacy");
				const loaded = Array.isArray(consent.categories) ? consent.categories.filter((c) => CONSENT_CATEGORIES.some((o) => o.value === c)) : [];
				setCategories(loaded.length > 0 ? loaded : [
					"analytics",
					"marketing",
					"preferences"
				]);
			} else {
				setConsentEnabled(false);
				setPolicyHref("/privacy");
				setCategories([
					"analytics",
					"marketing",
					"preferences"
				]);
			}
			setStatus("ready");
		}).catch((error) => {
			if (!active) return;
			setLoadError(error instanceof Error ? error.message : String(error));
			setStatus("error");
		});
		return () => {
			active = false;
		};
	}, [reloadKey]);
	function toggleCategory(category, checked) {
		setCategories((current) => {
			if (checked) return current.includes(category) ? current : [...current, category];
			return current.filter((c) => c !== category);
		});
	}
	const previewInput = (0, import_react.useMemo)(() => {
		return {
			siteName: siteName.trim(),
			contactEmail: contactEmail.trim(),
			...jurisdiction.trim() ? { jurisdiction: jurisdiction.trim() } : {},
			dataCollected: linesToList(dataCollectedText),
			thirdParties: mapThirdParties(thirdParties),
			cookies: mapCookies(cookies)
		};
	}, [
		siteName,
		contactEmail,
		jurisdiction,
		dataCollectedText,
		thirdParties,
		cookies
	]);
	const previewMarkdown = (0, import_react.useMemo)(() => {
		try {
			return generatePrivacyPolicy(previewInput);
		} catch {
			return "";
		}
	}, [previewInput]);
	async function onSubmit(event) {
		event.preventDefault();
		setSaving(true);
		setSaveError("");
		try {
			const dataCollected = linesToList(dataCollectedText);
			await savePrivacy({
				policy: {
					siteName: siteName.trim(),
					contactEmail: contactEmail.trim(),
					...jurisdiction.trim() ? { jurisdiction: jurisdiction.trim() } : {},
					dataCollected,
					thirdParties: mapThirdParties(thirdParties),
					cookies: mapCookies(cookies)
				},
				consent: {
					enabled: consentEnabled,
					categories,
					policyHref: policyHref.trim() || "/privacy"
				}
			});
			toast({
				title: "Privacy & consent saved",
				tone: "success"
			});
		} catch (error) {
			setSaveError(error instanceof Error ? error.message : String(error));
		} finally {
			setSaving(false);
		}
	}
	if (status === "loading") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-4",
		"aria-hidden": "true",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
	});
	if (status === "error") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
		variant: "inline",
		title: "Privacy settings couldn't load",
		message: loadError,
		action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
			tone: "accent",
			radius: "sm",
			size: "sm",
			type: "button",
			onClick: () => setReloadKey((k) => k + 1),
			children: "Try again"
		})
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "privacy-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "privacy-heading",
			title: "Privacy & consent",
			description: "Generate a privacy policy page and configure the cookie consent banner."
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
			className: "admin-form",
			onSubmit,
			noValidate: true,
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
					"aria-labelledby": "policy-section-heading",
					className: "flex flex-col gap-4",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
							id: "policy-section-heading",
							className: "text-lg font-medium text-fg",
							children: "Privacy policy"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Site name",
							required: true,
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								value: siteName,
								onChange: (event) => setSiteName(event.target.value),
								required: true
							})
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Contact email",
							required: true,
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								type: "email",
								value: contactEmail,
								onChange: (event) => setContactEmail(event.target.value),
								required: true
							})
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Jurisdiction",
							hint: "Optional — e.g. EU, California",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								value: jurisdiction,
								onChange: (event) => setJurisdiction(event.target.value)
							})
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Data collected",
							hint: "One item per line",
							required: true,
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
								value: dataCollectedText,
								onChange: (event) => setDataCollectedText(event.target.value),
								rows: 6,
								required: true
							})
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "flex flex-col gap-4",
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
									className: "text-sm font-medium text-fg",
									children: "Third parties"
								}),
								thirdParties.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
									className: "flex flex-col gap-4 rounded-lg border border-border p-4",
									children: [
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
											label: "Name",
											children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
												value: row.name,
												onChange: (event) => {
													const value = event.target.value;
													setThirdParties((current) => {
														const next = [...current];
														const item = next[index];
														if (!item) return current;
														next[index] = {
															...item,
															name: value
														};
														return next;
													});
												}
											})
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
											label: "Purpose",
											children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
												value: row.purpose,
												onChange: (event) => {
													const value = event.target.value;
													setThirdParties((current) => {
														const next = [...current];
														const item = next[index];
														if (!item) return current;
														next[index] = {
															...item,
															purpose: value
														};
														return next;
													});
												}
											})
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
											type: "button",
											tone: "surface",
											radius: "sm",
											size: "sm",
											"aria-label": `Remove third party ${index + 1}`,
											onClick: () => {
												setThirdParties((current) => current.filter((_, i) => i !== index));
											},
											children: "Remove"
										})
									]
								}, index)),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
									type: "button",
									tone: "surface",
									radius: "sm",
									size: "sm",
									onClick: () => {
										setThirdParties((current) => [...current, {
											name: "",
											purpose: ""
										}]);
									},
									children: "Add third party"
								})
							]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "flex flex-col gap-4",
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
									className: "text-sm font-medium text-fg",
									children: "Cookies"
								}),
								cookies.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
									className: "flex flex-col gap-4 rounded-lg border border-border p-4",
									children: [
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
											label: "Name",
											children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
												value: row.name,
												onChange: (event) => {
													const value = event.target.value;
													setCookies((current) => {
														const next = [...current];
														const item = next[index];
														if (!item) return current;
														next[index] = {
															...item,
															name: value
														};
														return next;
													});
												}
											})
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
											label: "Purpose",
											children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
												value: row.purpose,
												onChange: (event) => {
													const value = event.target.value;
													setCookies((current) => {
														const next = [...current];
														const item = next[index];
														if (!item) return current;
														next[index] = {
															...item,
															purpose: value
														};
														return next;
													});
												}
											})
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
											label: "Duration (days)",
											children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
												type: "number",
												value: row.durationDays,
												onChange: (event) => {
													const value = event.target.value;
													setCookies((current) => {
														const next = [...current];
														const item = next[index];
														if (!item) return current;
														next[index] = {
															...item,
															durationDays: value
														};
														return next;
													});
												}
											})
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
											type: "button",
											tone: "surface",
											radius: "sm",
											size: "sm",
											"aria-label": `Remove cookie ${index + 1}`,
											onClick: () => {
												setCookies((current) => current.filter((_, i) => i !== index));
											},
											children: "Remove"
										})
									]
								}, index)),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
									type: "button",
									tone: "surface",
									radius: "sm",
									size: "sm",
									onClick: () => {
										setCookies((current) => [...current, {
											name: "",
											purpose: "",
											durationDays: ""
										}]);
									},
									children: "Add cookie"
								})
							]
						})
					]
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
					header: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
						className: "text-base font-medium text-fg",
						children: "Preview"
					}),
					children: previewMarkdown ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
						className: "whitespace-pre-wrap text-sm text-fg-muted",
						children: previewMarkdown
					}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "text-sm text-fg-muted",
						children: "Fill in the policy fields to preview."
					})
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
					"aria-labelledby": "consent-section-heading",
					className: "flex flex-col gap-4",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
							id: "consent-section-heading",
							className: "text-lg font-medium text-fg",
							children: "Consent banner"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Show consent banner",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch, {
								checked: consentEnabled,
								onCheckedChange: setConsentEnabled,
								"aria-label": "Enable consent banner"
							})
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "flex flex-col gap-2",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
								className: "text-sm font-medium text-fg",
								children: "Banner categories"
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
								className: "flex flex-col gap-3",
								children: CONSENT_CATEGORIES.map((category) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
									className: "flex items-center gap-2 text-sm text-fg",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Checkbox, {
										"aria-label": category.label,
										checked: categories.includes(category.value),
										onCheckedChange: (checked) => toggleCategory(category.value, checked === true)
									}), category.label]
								}, category.value))
							})]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
							label: "Policy link",
							hint: "Relative path or https URL shown in the banner",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
								value: policyHref,
								onChange: (event) => setPolicyHref(event.target.value)
							})
						})
					]
				}),
				saveError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
					className: "admin-form__error",
					role: "alert",
					children: saveError
				}) : null,
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					className: "admin-form__actions",
					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "accent",
						radius: "sm",
						size: "base",
						type: "submit",
						disabled: saving,
						children: saving ? "Saving…" : "Save privacy & consent"
					})
				})
			]
		})]
	});
}
//#endregion
//#region src/components/admin/AuditViewerScreen.tsx
var EMPTY_FILTERS = {
	actor: "",
	action: "",
	entityType: "",
	from: "",
	to: "",
	q: ""
};
function actionTone(action) {
	if (action.includes("delete")) return "danger";
	if (action.includes("publish")) return "success";
	if (action.includes("schedule")) return "warning";
	return "info";
}
function formatTime(value) {
	return (value instanceof Date ? value : new Date(value)).toLocaleString(void 0, {
		year: "numeric",
		month: "short",
		day: "numeric",
		hour: "2-digit",
		minute: "2-digit"
	});
}
function buildQuery(filters, cursor) {
	const params = new URLSearchParams();
	if (filters.actor.trim()) params.set("actor", filters.actor.trim());
	if (filters.action.trim()) params.set("action", filters.action.trim());
	if (filters.entityType.trim()) params.set("entityType", filters.entityType.trim());
	if (filters.from.trim()) params.set("from", filters.from.trim());
	if (filters.to.trim()) params.set("to", filters.to.trim());
	if (filters.q.trim()) params.set("q", filters.q.trim());
	if (cursor) params.set("cursor", cursor);
	const qs = params.toString();
	return qs ? `?${qs}` : "";
}
function toIsoDate(d) {
	return d.toISOString().slice(0, 10);
}
function AuditViewerScreen() {
	const [filters, setFilters] = (0, import_react.useState)(EMPTY_FILTERS);
	const [appliedFilters, setAppliedFilters] = (0, import_react.useState)(EMPTY_FILTERS);
	const [cursorStack, setCursorStack] = (0, import_react.useState)([void 0]);
	const [page, setPage] = (0, import_react.useState)(1);
	const [items, setItems] = (0, import_react.useState)([]);
	const [nextCursor, setNextCursor] = (0, import_react.useState)(null);
	const [status, setStatus] = (0, import_react.useState)("loading");
	const [errorMessage, setErrorMessage] = (0, import_react.useState)("");
	const [reloadKey, setReloadKey] = (0, import_react.useState)(0);
	const activeCursor = cursorStack[page - 1];
	(0, import_react.useEffect)(() => {
		let active = true;
		(async () => {
			setStatus("loading");
			setErrorMessage("");
			try {
				const res = await fetch(`/api/admin/audit${buildQuery(appliedFilters, activeCursor)}`, { credentials: "same-origin" });
				const body = await res.json().catch(() => null);
				if (!res.ok) {
					const message = body?.error?.message ?? res.statusText;
					throw new Error(message);
				}
				if (!active) return;
				const data = body;
				setItems(data.items);
				setNextCursor(data.nextCursor);
				setStatus("idle");
			} catch (error) {
				if (!active) return;
				setItems([]);
				setErrorMessage(error instanceof Error ? error.message : String(error));
				setStatus("error");
			}
		})();
		return () => {
			active = false;
		};
	}, [
		appliedFilters,
		activeCursor,
		reloadKey
	]);
	function onApplyFilters(event) {
		event.preventDefault();
		setAppliedFilters(filters);
		setCursorStack([void 0]);
		setPage(1);
	}
	function onPageChange(nextPage) {
		if (nextPage > page) {
			if (!nextCursor) return;
			setCursorStack((stack) => [...stack, nextCursor]);
			setPage(nextPage);
			return;
		}
		if (nextPage < page) {
			setCursorStack((stack) => stack.slice(0, -1));
			setPage(nextPage);
		}
	}
	const pageCount = Math.max(page, page + (nextCursor ? 1 : 0));
	const rangeFrom = appliedFilters.from ? new Date(appliedFilters.from) : void 0;
	const rangeTo = appliedFilters.to ? new Date(appliedFilters.to) : void 0;
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "audit-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "audit-heading",
				title: "Audit log",
				description: "Admin actions recorded for this site."
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
				className: "admin-form admin-form--filters",
				onSubmit: onApplyFilters,
				noValidate: true,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "admin-form__grid",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
								label: "Actor",
								htmlFor: "audit-filter-actor",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									id: "audit-filter-actor",
									value: filters.actor,
									onChange: (event) => setFilters((f) => ({
										...f,
										actor: event.target.value
									}))
								})
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
								label: "Action",
								htmlFor: "audit-filter-action",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									id: "audit-filter-action",
									value: filters.action,
									onChange: (event) => setFilters((f) => ({
										...f,
										action: event.target.value
									}))
								})
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
								label: "Entity type",
								htmlFor: "audit-filter-entity-type",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									id: "audit-filter-entity-type",
									value: filters.entityType,
									onChange: (event) => setFilters((f) => ({
										...f,
										entityType: event.target.value
									}))
								})
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
								label: "From",
								htmlFor: "audit-filter-from",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									id: "audit-filter-from",
									type: "date",
									value: filters.from,
									onChange: (event) => setFilters((f) => ({
										...f,
										from: event.target.value
									}))
								})
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
								label: "To",
								htmlFor: "audit-filter-to",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									id: "audit-filter-to",
									type: "date",
									value: filters.to,
									onChange: (event) => setFilters((f) => ({
										...f,
										to: event.target.value
									}))
								})
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
								label: "Search",
								htmlFor: "audit-filter-q",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
									id: "audit-filter-q",
									value: filters.q,
									onChange: (event) => setFilters((f) => ({
										...f,
										q: event.target.value
									}))
								})
							})
						]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "admin-form__calendar",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
							className: "text-sm text-fg-muted",
							children: "Date range"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Calendar, {
							mode: "range",
							selected: {
								from: rangeFrom,
								to: rangeTo
							},
							onSelect: (date) => {
								if (!date) return;
								const iso = toIsoDate(date);
								setFilters((f) => {
									if (!f.from || f.from && f.to) return {
										...f,
										from: iso,
										to: ""
									};
									if (iso < f.from) return {
										...f,
										to: f.from,
										from: iso
									};
									return {
										...f,
										to: iso
									};
								});
							}
						})]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
						className: "admin-form__actions",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "accent",
							radius: "sm",
							size: "base",
							type: "submit",
							children: "Apply filters"
						})
					})
				]
			}),
			status === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "flex flex-col gap-4",
				"aria-hidden": "true",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })
			}) : null,
			status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
				variant: "inline",
				title: "Audit log couldn't load",
				message: errorMessage,
				action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "sm",
					type: "button",
					onClick: () => setReloadKey((k) => k + 1),
					children: "Try again"
				})
			}) : null,
			status === "idle" && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "admin-empty",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "No audit events" })
			}) : null,
			status === "idle" && items.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
				caption: "Audit events",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Time"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Actor"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Action"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Entity"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "IP"
					})
				] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: formatTime(item.createdAt) }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: item.actorLabel ?? item.actorId ?? "—" }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
						tone: actionTone(item.action),
						children: item.action
					}) }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Td, { children: [
						item.entityType,
						"/",
						item.entityId
					] }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: item.ip ?? "—" })
				] }, item.id)) })]
			}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pagination, {
				page,
				pageCount,
				onPageChange,
				label: "Audit pagination"
			})] }) : null
		]
	});
}
//#endregion
//#region src/components/admin/HealthScreen.tsx
function statusTone$2(status) {
	if (status === "ok") return "success";
	if (status === "degraded") return "warning";
	return "danger";
}
var STATUS_LABEL = {
	ok: "Operational",
	degraded: "Degraded",
	down: "Down"
};
var OVERALL_SUMMARY = {
	ok: "All systems operational.",
	degraded: "Some systems are degraded.",
	down: "One or more systems are down."
};
function HealthScreen() {
	const [health, setHealth] = (0, import_react.useState)(null);
	const [status, setStatus] = (0, import_react.useState)("loading");
	const [errorMessage, setErrorMessage] = (0, import_react.useState)("");
	const [reloadKey, setReloadKey] = (0, import_react.useState)(0);
	(0, import_react.useEffect)(() => {
		let active = true;
		(async () => {
			setStatus("loading");
			setErrorMessage("");
			try {
				const res = await fetch("/api/admin/health", { credentials: "same-origin" });
				const body = await res.json().catch(() => null);
				if (!res.ok) {
					const message = body?.error?.message ?? res.statusText;
					throw new Error(message);
				}
				if (!active) return;
				setHealth(body);
				setStatus("idle");
			} catch (error) {
				if (!active) return;
				setHealth(null);
				setErrorMessage(error instanceof Error ? error.message : String(error));
				setStatus("error");
			}
		})();
		return () => {
			active = false;
		};
	}, [reloadKey]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "health-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "health-heading",
				title: "Site health",
				description: "Reachability of the services this site depends on.",
				actions: status !== "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "sm",
					type: "button",
					disabled: status === "loading",
					onClick: () => setReloadKey((k) => k + 1),
					children: "Re-check"
				}) : null
			}),
			status === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "flex flex-col gap-4",
				"aria-hidden": "true",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })
			}) : null,
			status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
				variant: "inline",
				title: "Health status couldn't load",
				message: errorMessage,
				action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "sm",
					type: "button",
					onClick: () => setReloadKey((k) => k + 1),
					children: "Try again"
				})
			}) : null,
			status === "idle" && health ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex flex-col gap-6",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Card, {
					header: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex items-center justify-between gap-4",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
							className: "admin-display text-lg text-fg",
							children: "Overall status"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
							tone: statusTone$2(health.status),
							children: STATUS_LABEL[health.status]
						})]
					}),
					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "text-sm text-fg-muted",
						children: OVERALL_SUMMARY[health.status]
					})
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
					caption: "Per-service health checks",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
							scope: "col",
							children: "Service"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
							scope: "col",
							children: "Status"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
							scope: "col",
							children: "Latency"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
							scope: "col",
							children: "Detail"
						})
					] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: health.checks.map((check) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: check.name }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
							tone: statusTone$2(check.status),
							children: STATUS_LABEL[check.status]
						}) }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: check.latencyMs == null ? "—" : `${check.latencyMs} ms` }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: check.detail ?? "—" })
					] }, check.name)) })]
				})]
			}) : null
		]
	});
}
//#endregion
//#region src/components/admin/CalendarScreen.tsx
function statusTone$1(status) {
	if (status === "published") return "success";
	if (status === "scheduled") return "warning";
	return "neutral";
}
function sameMonth(a, b) {
	return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
}
function monthLabel(d) {
	return d.toLocaleDateString("en-GB", {
		month: "long",
		year: "numeric"
	});
}
function dayLabel(d) {
	return d.toLocaleDateString("en-GB", {
		day: "numeric",
		month: "long",
		year: "numeric"
	});
}
function tomorrowIso() {
	const t = /* @__PURE__ */ new Date();
	t.setDate(t.getDate() + 1);
	return t.toISOString().slice(0, 10);
}
function RescheduleControl({ entry, onRescheduled }) {
	const client = (0, import_react.useMemo)(() => makeContentClient(), []);
	const { toast } = useToast();
	const [value, setValue] = (0, import_react.useState)("");
	const [busy, setBusy] = (0, import_react.useState)(false);
	const [error, setError] = (0, import_react.useState)(null);
	const fieldId = `reschedule-${entry.id}`;
	async function submit() {
		if (!value) {
			setError("Choose a date to reschedule to.");
			return;
		}
		setBusy(true);
		setError(null);
		try {
			const at = (/* @__PURE__ */ new Date(`${value}T00:00:00.000Z`)).toISOString();
			await client.schedule(entry.id, at);
			toast({
				title: "Post rescheduled",
				tone: "success"
			});
			setValue("");
			onRescheduled();
		} catch (e) {
			setError(e instanceof Error ? e.message : "Could not reschedule the post.");
		} finally {
			setBusy(false);
		}
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		className: "flex flex-col gap-1",
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
			label: "Reschedule to",
			htmlFor: fieldId,
			error: error ?? void 0,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex items-end gap-2",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
					id: fieldId,
					type: "date",
					size: "sm",
					min: tomorrowIso(),
					value,
					disabled: busy,
					onChange: (e) => setValue(e.target.value)
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					radius: "sm",
					size: "sm",
					type: "button",
					disabled: busy,
					onClick: () => void submit(),
					children: "Reschedule"
				})]
			})
		})
	});
}
function CalendarScreen() {
	const client = (0, import_react.useMemo)(() => makeContentClient(), []);
	const [month, setMonth] = (0, import_react.useState)(() => /* @__PURE__ */ new Date());
	const scheduled = useContentList(client, { status: "scheduled" });
	const published = useContentList(client, { status: "published" });
	const loading = scheduled.loading || published.loading;
	const error = scheduled.error ?? published.error;
	const monthEntries = (0, import_react.useMemo)(() => {
		return [...scheduled.entries, ...published.entries].map((e) => ({
			e,
			at: e.publishedAt == null ? null : new Date(e.publishedAt)
		})).filter((x) => x.at != null && sameMonth(x.at, month)).sort((a, b) => a.at.getTime() - b.at.getTime());
	}, [
		scheduled.entries,
		published.entries,
		month
	]);
	function reload() {
		scheduled.reload();
		published.reload();
	}
	if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-4",
		"aria-hidden": "true",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "calendar-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "calendar-heading",
			title: "Editorial calendar",
			description: `Scheduled and published posts for ${monthLabel(month)}.`,
			actions: !error && monthEntries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				tone: "accent",
				radius: "sm",
				size: "base",
				asChild: true,
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
					href: "/admin/content/new",
					children: "New post"
				})
			}) : null
		}), error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
			variant: "inline",
			title: "Calendar couldn't load",
			message: error.message,
			action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				tone: "accent",
				radius: "sm",
				size: "sm",
				type: "button",
				onClick: () => window.location.reload(),
				children: "Try again"
			})
		}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
			className: "flex flex-col gap-6 md:flex-row",
			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("aside", {
				"aria-label": "Month navigation",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Calendar, {
					mode: "single",
					month,
					onMonthChange: setMonth
				})
			}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "flex-1",
				children: monthEntries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "admin-empty",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
						"No posts scheduled or published in ",
						monthLabel(month),
						"."
					] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "accent",
						radius: "sm",
						size: "base",
						asChild: true,
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
							href: "/admin/content/new",
							children: "Write a post"
						})
					})]
				}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
					className: "flex flex-col gap-4",
					children: monthEntries.map(({ e: entry, at }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
						className: "flex flex-col gap-2 border-b border-border pb-4",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
								className: "flex items-center gap-3",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
									tone: statusTone$1(entry.status),
									children: entry.status
								}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
									className: "text-sm text-fg-muted",
									children: dayLabel(at)
								})]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
								className: "admin-table-link",
								href: `/admin/content/${entry.id}`,
								children: entry.title
							}),
							entry.status === "scheduled" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RescheduleControl, {
								entry,
								onRescheduled: reload
							}) : null
						]
					}, entry.id))
				})
			})]
		})]
	});
}
//#endregion
//#region src/components/admin/BackupRestoreScreen.tsx
async function api(url, init) {
	const headers = new Headers(init?.headers);
	if (init?.body && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
	if (init?.method && init.method !== "GET") headers.set("origin", window.location.origin);
	const response = await fetch(url, {
		...init,
		credentials: "same-origin",
		headers
	}), body = await response.json().catch(() => null);
	if (!response.ok) throw new Error(body?.error?.message ?? response.statusText);
	return body;
}
function BackupRestoreScreen() {
	const { toast } = useToast(), [types, setTypes] = (0, import_react.useState)([]), [typeKey, setTypeKey] = (0, import_react.useState)(""), [selectedFile, setSelectedFile] = (0, import_react.useState)(null), [busy, setBusy] = (0, import_react.useState)(false), [error, setError] = (0, import_react.useState)(""), [result, setResult] = (0, import_react.useState)(null);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		api("/api/admin/content-model/definitions").then((snapshot) => {
			if (cancelled) return;
			const next = snapshot.contentTypes.filter((item) => item.active && item.canExport);
			setTypes(next);
			setTypeKey((current) => current || next[0]?.key || "");
		}).catch((reason) => {
			if (!cancelled) setError(reason instanceof Error ? reason.message : "Transfer definitions could not be loaded.");
		});
		return () => {
			cancelled = true;
		};
	}, []);
	async function exportBundle() {
		if (!typeKey || busy) return;
		setBusy(true);
		setError("");
		try {
			const response = await fetch(`/api/admin/content-model/transfer?type=${encodeURIComponent(typeKey)}`, { credentials: "same-origin" });
			if (!response.ok) {
				const body = await response.json().catch(() => null);
				throw new Error(body?.error?.message ?? response.statusText);
			}
			const blob = await response.blob(), url = URL.createObjectURL(blob), anchor = document.createElement("a");
			anchor.href = url;
			anchor.download = `mod-cms-${typeKey}.json`;
			anchor.click();
			URL.revokeObjectURL(url);
			toast({
				title: "Native content-model export ready",
				tone: "success"
			});
		} catch (reason) {
			setError(reason instanceof Error ? reason.message : "Export failed.");
		} finally {
			setBusy(false);
		}
	}
	async function importBundle() {
		setError("");
		setResult(null);
		if (!selectedFile) {
			setError("Choose a native content-model bundle first.");
			return;
		}
		setBusy(true);
		try {
			const next = await api("/api/admin/content-model/transfer", {
				method: "POST",
				body: await new Response(selectedFile).text()
			});
			setResult(next);
			toast({
				title: "Native staged import published",
				tone: "success"
			});
		} catch (reason) {
			setError(reason instanceof Error ? reason.message : "Import failed.");
		} finally {
			setBusy(false);
		}
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "backup-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "backup-heading",
			title: "Export / import",
			description: "Move one content type and its linked field/block state through the native staged content-model format."
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
			className: "flex flex-col gap-10",
			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
				className: "flex flex-col gap-4",
				"aria-labelledby": "native-export-heading",
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
						id: "native-export-heading",
						className: "text-lg font-medium text-fg",
						children: "Native export"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "max-w-2xl text-sm text-fg",
						children: "Each bundle contains one content type, its immutable content revisions, linked field revisions, block documents, and field definitions. Password credentials are never exported."
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
						className: "flex max-w-md flex-col gap-2 text-sm text-fg",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
							className: "font-medium",
							children: "Content type"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
							"aria-label": "Content type",
							className: "rounded-[2px] border border-border bg-canvas p-2",
							value: typeKey,
							disabled: busy || types.length === 0,
							onChange: (event) => setTypeKey(event.currentTarget.value),
							children: types.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: "",
								children: "No exportable content types"
							}) : types.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
								value: item.key,
								children: [
									item.labels.name,
									" · ",
									item.key
								]
							}, item.key))
						})]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "surface",
						radius: "sm",
						size: "base",
						type: "button",
						disabled: busy || !typeKey,
						onClick: () => void exportBundle(),
						children: "Export native bundle"
					}) })
				]
			}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
				className: "flex flex-col gap-4",
				"aria-labelledby": "native-import-heading",
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
						id: "native-import-heading",
						className: "text-lg font-medium text-fg",
						children: "Native staged import"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "max-w-2xl text-sm text-fg",
						children: "Import validates and stages both content and fields before one publication transition. The current package seams require PostgreSQL callback transactions; unsupported runtimes fail before mutation."
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
						label: "Native bundle (JSON)",
						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
							type: "file",
							accept: "application/json",
							onChange: (event) => {
								setSelectedFile(event.currentTarget.files?.[0] ?? null);
								setError("");
								setResult(null);
							}
						})
					}),
					error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "admin-form__error",
						role: "alert",
						children: error
					}) : null,
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "accent",
						radius: "sm",
						size: "base",
						type: "button",
						disabled: busy,
						onClick: () => void importBundle(),
						children: busy ? "Working…" : "Import and publish bundle"
					}) }),
					result ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
						caption: "Native import result",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
							scope: "col",
							children: "Property"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
							scope: "col",
							children: "Value"
						})] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Body, { children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: "State" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: result.state })] }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: "Session" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: result.sessionId })] }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: "Plan" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: result.planHash })] })
						] })]
					}) : null
				]
			})]
		})]
	});
}
//#endregion
//#region src/components/admin/DiscussionSettingsSection.tsx
var WHO_CAN_COMMENT_OPTIONS = [{
	value: "everyone",
	label: "Anyone"
}, {
	value: "registered",
	label: "Signed-in members only"
}];
async function fetchDiscussion() {
	const res = await fetch("/api/admin/discussion", { credentials: "same-origin" });
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	return body ?? {};
}
async function saveDiscussion(config) {
	const res = await fetch("/api/admin/discussion", {
		method: "POST",
		credentials: "same-origin",
		headers: {
			"Content-Type": "application/json",
			Origin: window.location.origin
		},
		body: JSON.stringify(config)
	});
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	return body ?? {};
}
function DiscussionSettingsSection() {
	const { toast } = useToast();
	const [status, setStatus] = (0, import_react.useState)("loading");
	const [loadError, setLoadError] = (0, import_react.useState)(void 0);
	const [reloadKey, setReloadKey] = (0, import_react.useState)(0);
	const [enabled, setEnabled] = (0, import_react.useState)(false);
	const [whoCanComment, setWhoCanComment] = (0, import_react.useState)("everyone");
	const [nestingDepth, setNestingDepth] = (0, import_react.useState)(3);
	const [blocklistText, setBlocklistText] = (0, import_react.useState)("");
	const [saving, setSaving] = (0, import_react.useState)(false);
	const [saveError, setSaveError] = (0, import_react.useState)(void 0);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		setStatus("loading");
		setLoadError(void 0);
		fetchDiscussion().then((config) => {
			if (cancelled) return;
			setEnabled(config.enabled);
			setWhoCanComment(config.whoCanComment);
			setNestingDepth(config.nestingDepth);
			setBlocklistText(config.blocklist.join("\n"));
			setStatus("idle");
		}).catch((err) => {
			if (cancelled) return;
			setLoadError(err instanceof Error ? err.message : String(err));
			setStatus("error");
		});
		return () => {
			cancelled = true;
		};
	}, [reloadKey]);
	async function onSubmit(event) {
		event.preventDefault();
		setSaving(true);
		setSaveError(void 0);
		const config = {
			enabled,
			whoCanComment,
			nestingDepth,
			blocklist: blocklistText.split("\n").map((t) => t.trim()).filter(Boolean)
		};
		try {
			const updated = await saveDiscussion(config);
			setEnabled(updated.enabled);
			setWhoCanComment(updated.whoCanComment);
			setNestingDepth(updated.nestingDepth);
			setBlocklistText(updated.blocklist.join("\n"));
			toast({
				title: "Discussion settings saved",
				tone: "success"
			});
		} catch (error) {
			setSaveError(error instanceof Error ? error.message : String(error));
		} finally {
			setSaving(false);
		}
	}
	if (status === "loading") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-4",
		"aria-hidden": "true",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
	});
	if (status === "error") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
		variant: "inline",
		title: "Discussion settings couldn't load",
		message: loadError,
		action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
			tone: "accent",
			radius: "sm",
			size: "sm",
			type: "button",
			onClick: () => setReloadKey((k) => k + 1),
			children: "Try again"
		})
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "discussion-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			className: "admin-screen__header",
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
				id: "discussion-heading",
				className: "admin-section-title",
				children: "Discussion settings"
			}) })
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
			className: "admin-form",
			onSubmit,
			noValidate: true,
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "flex flex-col gap-6",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Field, {
						label: "Allow comments",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch, {
							checked: enabled,
							onCheckedChange: setEnabled,
							"aria-label": "Allow comments"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
							className: "text-sm text-fg-muted",
							children: "When off, the comment form is hidden and new submissions are rejected."
						})]
					}), enabled && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioField, {
							label: "Who can comment",
							value: whoCanComment,
							onValueChange: (v) => setWhoCanComment(v),
							options: WHO_CAN_COMMENT_OPTIONS
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "flex flex-col gap-1",
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
									htmlFor: "nesting-depth",
									className: "text-sm font-medium text-fg",
									children: "Thread depth"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
									className: "text-sm text-fg-muted",
									children: "Set to 0 to disable threading (flat list). Maximum 10 levels."
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
									id: "nesting-depth",
									type: "number",
									min: 0,
									max: 10,
									value: nestingDepth,
									onChange: (e) => {
										const parsed = parseInt(e.target.value, 10);
										if (!isNaN(parsed)) setNestingDepth(Math.min(10, Math.max(0, parsed)));
									},
									className: "admin-input w-24"
								})
							]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "flex flex-col gap-1",
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", {
									htmlFor: "blocked-terms",
									className: "text-sm font-medium text-fg",
									children: "Blocked terms"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
									className: "text-sm text-fg-muted",
									children: "Comments containing these words (case-insensitive) are rejected automatically."
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
									id: "blocked-terms",
									value: blocklistText,
									onChange: (e) => setBlocklistText(e.target.value),
									placeholder: "One term per line",
									rows: 6
								})
							]
						})
					] })]
				}),
				saveError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
					role: "alert",
					className: "text-sm text-error mt-4",
					children: saveError
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					className: "mt-6",
					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						type: "submit",
						tone: "accent",
						disabled: saving,
						children: saving ? "Saving…" : "Save discussion settings"
					})
				})
			]
		})]
	});
}
//#endregion
//#region src/components/admin/CommentsScreen.tsx
var TABS = [
	{
		id: "pending",
		label: "Pending"
	},
	{
		id: "spam",
		label: "Spam"
	},
	{
		id: "published",
		label: "Published"
	}
];
function statusTone(status) {
	if (status === "published") return "success";
	if (status === "spam") return "danger";
	return "warning";
}
function authorLabel(comment) {
	if (comment.author.kind === "user") return `Member ${comment.author.userId.slice(0, 8)}`;
	const guest = comment.author;
	return guest.email ? `${guest.name} (${guest.email})` : guest.name;
}
function CommentsScreen() {
	const { toast } = useToast();
	const [status, setStatus] = (0, import_react.useState)("pending");
	const [items, setItems] = (0, import_react.useState)([]);
	const [nextCursor, setNextCursor] = (0, import_react.useState)(null);
	const [loading, setLoading] = (0, import_react.useState)(true);
	const [error, setError] = (0, import_react.useState)("");
	const [busyId, setBusyId] = (0, import_react.useState)(null);
	const load = (0, import_react.useCallback)(async (tab, cursor, append = false) => {
		setLoading(!append);
		setError("");
		try {
			const params = new URLSearchParams({ status: tab });
			if (cursor) params.set("cursor", cursor);
			const res = await fetch(`/api/admin/comments?${params}`, { credentials: "same-origin" });
			const body = await res.json().catch(() => null);
			if (!res.ok) {
				const message = body?.error?.message ?? res.statusText;
				throw new Error(message);
			}
			const data = body;
			setItems((prev) => append ? [...prev, ...data.items] : data.items);
			setNextCursor(data.nextCursor);
		} catch (e) {
			setError(e instanceof Error ? e.message : "Comments could not load.");
			if (!append) setItems([]);
		} finally {
			setLoading(false);
		}
	}, []);
	(0, import_react.useEffect)(() => {
		load(status);
	}, [status, load]);
	async function moderate(action, id) {
		setBusyId(id);
		try {
			const res = await fetch("/api/admin/comments", {
				method: "POST",
				credentials: "same-origin",
				headers: {
					"content-type": "application/json",
					origin: window.location.origin
				},
				body: JSON.stringify({
					action,
					id
				})
			});
			const body = await res.json().catch(() => null);
			if (!res.ok) {
				const message = body?.error?.message ?? res.statusText;
				throw new Error(message);
			}
			toast({
				title: "Comment updated",
				tone: "success"
			});
			await load(status);
		} catch (e) {
			toast({
				title: e instanceof Error ? e.message : "That action could not complete.",
				tone: "danger"
			});
		} finally {
			setBusyId(null);
		}
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
		/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiscussionSettingsSection, {}),
		/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", {
			className: "admin-divider",
			"aria-hidden": "true"
		}),
		/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
			"aria-labelledby": "comments-heading",
			children: [
				loading && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "flex flex-col gap-4",
					"aria-hidden": "true",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
				}) : null,
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
					headingId: "comments-heading",
					title: "Comments",
					description: "Moderate guest and member comments across all posts."
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs, {
					value: status,
					onValueChange: (v) => setStatus(v),
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsList, {
						"aria-label": "Comment status",
						children: TABS.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTrigger, {
							value: tab.id,
							children: tab.label
						}, tab.id))
					}), TABS.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabsContent, {
						value: tab.id,
						children: [
							error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
								variant: "inline",
								title: "Comments couldn't load",
								message: error,
								action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
									tone: "accent",
									radius: "sm",
									size: "sm",
									type: "button",
									onClick: () => void load(status),
									children: "Try again"
								})
							}) : null,
							!error && !loading && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
								className: "admin-empty",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "No comments in this queue." })
							}) : null,
							!error && items.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
								caption: "Comment moderation queue",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
										scope: "col",
										children: "Author"
									}),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
										scope: "col",
										children: "Target"
									}),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
										scope: "col",
										children: "Comment"
									}),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
										scope: "col",
										children: "Status"
									}),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
										scope: "col",
										children: "Actions"
									})
								] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: items.map((comment) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: authorLabel(comment) }),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
										className: "font-mono text-xs",
										children: [
											comment.target.type,
											":",
											comment.target.id.slice(0, 8),
											"…"
										]
									}) }),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: comment.body }),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
										tone: statusTone(comment.status),
										children: comment.status
									}) }),
									/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
										className: "flex flex-wrap gap-2",
										children: [
											comment.status !== "published" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
												tone: "accent",
												radius: "sm",
												size: "sm",
												type: "button",
												disabled: busyId === comment.id,
												onClick: () => void moderate("approve", comment.id),
												children: "Approve"
											}) : null,
											comment.status !== "spam" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
												tone: "surface",
												radius: "sm",
												size: "sm",
												type: "button",
												disabled: busyId === comment.id,
												onClick: () => void moderate("spam", comment.id),
												children: "Spam"
											}) : null,
											comment.status !== "trashed" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
												tone: "surface",
												radius: "sm",
												size: "sm",
												type: "button",
												disabled: busyId === comment.id,
												onClick: () => void moderate("trash", comment.id),
												children: "Trash"
											}) : null,
											/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
												tone: "danger",
												radius: "sm",
												size: "sm",
												type: "button",
												disabled: busyId === comment.id,
												onClick: () => void moderate("delete", comment.id),
												children: "Delete"
											})
										]
									}) })
								] }, comment.id)) })]
							}), nextCursor ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
								className: "mt-6",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
									tone: "surface",
									radius: "sm",
									size: "sm",
									type: "button",
									disabled: loading,
									onClick: () => void load(status, nextCursor, true),
									children: "Load more"
								})
							}) : null] }) : null
						]
					}, tab.id))]
				})
			]
		})
	] });
}
//#endregion
//#region ../../packages/forms-react/dist/index.js
var FormsClientError = class extends Error {
	code;
	constructor(message, code = "FORMS_CLIENT_ERROR") {
		super(message);
		this.name = "FormsClientError";
		this.code = code;
	}
};
function toError$1(e) {
	if (e instanceof FormsClientError) return e;
	if (e instanceof Error) return new FormsClientError(e.message);
	return new FormsClientError(String(e));
}
function useSubmissions(client, formId, opts) {
	const [items, setItems] = (0, import_react.useState)([]);
	const [loading, setLoading] = (0, import_react.useState)(true);
	const [error, setError] = (0, import_react.useState)(null);
	const [hasMore, setHasMore] = (0, import_react.useState)(false);
	const [reloadToken, setReloadToken] = (0, import_react.useState)(0);
	const clientRef = (0, import_react.useRef)(client);
	clientRef.current = client;
	const nextCursorRef = (0, import_react.useRef)(void 0);
	const optsKey = JSON.stringify(opts ?? {});
	const reload = (0, import_react.useCallback)(() => {
		setReloadToken((t) => t + 1);
	}, []);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		setLoading(true);
		setError(null);
		nextCursorRef.current = void 0;
		clientRef.current.list(formId, opts).then((page) => {
			if (!cancelled) {
				setItems(page.items);
				nextCursorRef.current = page.nextCursor;
				setHasMore(Boolean(page.nextCursor));
				setLoading(false);
			}
		}).catch((e) => {
			if (!cancelled) {
				setError(toError$1(e));
				setLoading(false);
			}
		});
		return () => {
			cancelled = true;
		};
	}, [
		formId,
		optsKey,
		reloadToken
	]);
	return {
		items,
		loading,
		error,
		hasMore,
		loadMore: (0, import_react.useCallback)(async () => {
			const cursor = nextCursorRef.current;
			if (!cursor) return;
			try {
				const page = await clientRef.current.list(formId, {
					...opts,
					cursor
				});
				nextCursorRef.current = page.nextCursor;
				setHasMore(Boolean(page.nextCursor));
				setItems((prev) => [...prev, ...page.items]);
			} catch (e) {
				setError(toError$1(e));
			}
		}, [formId, optsKey]),
		remove: (0, import_react.useCallback)(async (id) => {
			const snapshot = items;
			setItems((prev) => prev.filter((item) => item.id !== id));
			try {
				await clientRef.current.delete(formId, id);
			} catch (e) {
				setItems(snapshot);
				const err = toError$1(e);
				setError(err);
				throw err;
			}
		}, [formId, items]),
		reload
	};
}
function defaultFormatDate(iso) {
	try {
		return new Date(iso).toLocaleString();
	} catch {
		return iso;
	}
}
function previewData(data) {
	const email = data.email;
	if (typeof email === "string" && email) return email;
	const first = Object.values(data).find((v) => typeof v === "string" && v);
	return typeof first === "string" ? first : "—";
}
function SubmissionsTable({ client, formId, formatDate = defaultFormatDate }) {
	const [includeSpam, setIncludeSpam] = (0, import_react.useState)(false);
	const { items, loading, error, hasMore, loadMore, remove } = useSubmissions(client, formId, { includeSpam });
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
		/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
			className: "flex items-center gap-2 mb-4 text-sm",
			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
				type: "checkbox",
				checked: includeSpam,
				onChange: (e) => setIncludeSpam(e.target.checked),
				"aria-label": "Show spam"
			}), "Show spam"]
		}),
		error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
			role: "alert",
			className: "text-sm text-danger mb-2",
			children: error.message
		}) : null,
		loading && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "Loading…" }) : null,
		/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
			caption: "Form submissions",
			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
					scope: "col",
					children: "Created"
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
					scope: "col",
					children: "Data"
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
					scope: "col",
					children: "Status"
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
					scope: "col",
					children: "Actions"
				})
			] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: items.map((row) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: formatDate(row.createdAt) }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: previewData(row.data) }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: row.spam ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Spam" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "OK" }) }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
					type: "button",
					onClick: () => void remove(row.id),
					children: "Delete"
				}) })
			] }, row.id)) })]
		}),
		hasMore ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
			type: "button",
			onClick: () => void loadMore(),
			className: "mt-4",
			children: "Load more"
		}) : null
	] });
}
//#endregion
//#region src/components/admin/SubmissionsScreen.tsx
var FORM_ID = "contact";
var DATE_FORMAT$2 = new Intl.DateTimeFormat("en-GB", {
	day: "numeric",
	month: "long",
	year: "numeric",
	hour: "2-digit",
	minute: "2-digit"
});
function formatSubmissionDate(iso) {
	const date = new Date(iso);
	return Number.isNaN(date.getTime()) ? iso : DATE_FORMAT$2.format(date);
}
function makeSubmissionClient() {
	return {
		async list(formId, opts) {
			const params = new URLSearchParams({ formId });
			if (opts?.cursor) params.set("cursor", opts.cursor);
			if (opts?.includeSpam) params.set("includeSpam", "true");
			const res = await fetch(`/api/admin/submissions?${params}`, { credentials: "same-origin" });
			const body = await res.json().catch(() => null);
			if (!res.ok) {
				const message = body?.error?.message ?? res.statusText;
				throw new Error(message);
			}
			return body;
		},
		async get(formId, id) {
			return (await this.list(formId, { includeSpam: true })).items.find((row) => row.id === id) ?? null;
		},
		async delete(formId, id) {
			const res = await fetch("/api/admin/submissions", {
				method: "DELETE",
				credentials: "same-origin",
				headers: {
					"content-type": "application/json",
					origin: window.location.origin
				},
				body: JSON.stringify({
					formId,
					id
				})
			});
			const body = await res.json().catch(() => null);
			if (!res.ok) {
				const message = body?.error?.message ?? res.statusText;
				throw new Error(message);
			}
		}
	};
}
function SubmissionsScreen() {
	const client = (0, import_react.useMemo)(() => makeSubmissionClient(), []);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "submissions-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "submissions-heading",
			title: "Submissions",
			description: "Contact form messages from the public site."
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SubmissionsTable, {
			client,
			formId: FORM_ID,
			formatDate: formatSubmissionDate
		})]
	});
}
//#endregion
//#region src/components/admin/NotificationsScreen.tsx
var DATE_FORMAT$1 = new Intl.DateTimeFormat("en-GB", {
	day: "numeric",
	month: "long",
	year: "numeric",
	hour: "2-digit",
	minute: "2-digit"
});
function formatNotificationDate(iso) {
	const date = new Date(iso);
	return Number.isNaN(date.getTime()) ? iso : DATE_FORMAT$1.format(date);
}
function NotificationRow({ item, onMarkRead }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
		className: "admin-notification-row flex flex-col gap-1 border-b border-border py-3",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex flex-wrap items-baseline justify-between gap-2",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
					className: "font-medium text-fg",
					children: item.title
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("time", {
					className: "text-sm text-fg-muted",
					dateTime: item.createdAt,
					children: formatNotificationDate(item.createdAt)
				})]
			}),
			item.href ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "text-sm text-accent underline",
				href: item.href,
				children: "View"
			}) : null,
			!item.readAt ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				tone: "surface",
				radius: "sm",
				size: "sm",
				type: "button",
				onClick: () => onMarkRead(item.id),
				children: "Mark read"
			}) : null
		]
	});
}
function NotificationsScreen() {
	const { items, loading, error, markRead, reload } = useNotifications((0, import_react.useMemo)(() => makeNotificationClient(), []));
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "notifications-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "notifications-heading",
				title: "Notifications",
				description: "Your admin alerts and moderation signals.",
				actions: items.length > 0 && !loading && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "sm",
					type: "button",
					onClick: () => void markRead("all"),
					children: "Mark all read"
				}) : null
			}),
			loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex flex-col gap-4",
				"aria-hidden": "true",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
			}) : null,
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
				variant: "inline",
				title: "Notifications couldn't load",
				message: error.message,
				action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "sm",
					type: "button",
					onClick: () => reload(),
					children: "Try again"
				})
			}) : null,
			!loading && !error && items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "admin-empty",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "No notifications." })
			}) : null,
			!loading && !error && items.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
				className: "list-none p-0 m-0",
				"aria-live": "polite",
				children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NotificationRow, {
					item,
					onMarkRead: (id) => void markRead([id])
				}, item.id))
			}) : null
		]
	});
}
//#endregion
//#region src/components/admin/TrashScreen.tsx
function formatUpdated(value) {
	return (value instanceof Date ? value : new Date(value)).toLocaleString(void 0, {
		year: "numeric",
		month: "short",
		day: "numeric",
		hour: "2-digit",
		minute: "2-digit"
	});
}
function TrashScreen() {
	const client = (0, import_react.useMemo)(() => makeContentClient(), []);
	const { entries, loading, error, reload } = useContentList(client, { status: "trashed" });
	const { toast } = useToast();
	const [pendingRemove, setPendingRemove] = (0, import_react.useState)(null);
	const [busyId, setBusyId] = (0, import_react.useState)(null);
	async function restoreEntry(id) {
		setBusyId(id);
		try {
			await client.restore(id);
			toast({
				title: "Entry restored to drafts",
				tone: "success"
			});
			reload();
		} catch (e) {
			toast({
				title: e instanceof Error ? e.message : "Could not restore the entry.",
				tone: "danger"
			});
		} finally {
			setBusyId(null);
		}
	}
	async function confirmRemove() {
		if (!pendingRemove) return;
		const id = pendingRemove.id;
		setBusyId(id);
		try {
			await client.remove(id);
			toast({
				title: "Entry permanently deleted",
				tone: "success"
			});
			setPendingRemove(null);
			reload();
		} catch (e) {
			toast({
				title: e instanceof Error ? e.message : "Could not delete the entry.",
				tone: "danger"
			});
		} finally {
			setBusyId(null);
		}
	}
	if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-4",
		"aria-hidden": "true",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "trash-heading",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				headingId: "trash-heading",
				title: "Trash",
				description: "Trashed posts and pages. Restore or delete permanently."
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
				variant: "inline",
				title: "Trash couldn't load",
				message: error.message,
				action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "accent",
					radius: "sm",
					size: "sm",
					type: "button",
					onClick: () => reload(),
					children: "Try again"
				})
			}) : null,
			!error && entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "admin-empty",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "Trash is empty." })
			}) : null,
			!error && entries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
				caption: "Trashed content entries",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Title"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Type"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Trashed"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Actions"
					})
				] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
						className: "text-fg",
						children: entry.title
					}) }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: entry.type }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Badge, {
						tone: "neutral",
						children: formatUpdated(entry.updatedAt)
					}) }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex flex-wrap gap-2",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "surface",
							radius: "sm",
							size: "sm",
							type: "button",
							disabled: busyId === entry.id,
							onClick: () => void restoreEntry(entry.id),
							children: "Restore"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "danger",
							radius: "sm",
							size: "sm",
							type: "button",
							disabled: busyId === entry.id,
							onClick: () => setPendingRemove(entry),
							children: "Delete permanently"
						})]
					}) })
				] }, entry.id)) })]
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog, {
				open: pendingRemove != null,
				onOpenChange: (open) => {
					if (!open) setPendingRemove(null);
				},
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, { children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle, { children: "Permanently delete entry" }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: pendingRemove ? `Permanently delete '${pendingRemove.title}'? This cannot be undone.` : "" }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex gap-2",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "surface",
							radius: "sm",
							size: "sm",
							type: "button",
							onClick: () => setPendingRemove(null),
							children: "Cancel"
						}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "danger",
							radius: "sm",
							size: "sm",
							type: "button",
							disabled: busyId != null,
							onClick: () => void confirmRemove(),
							children: "Delete permanently"
						})]
					})
				] })
			})
		]
	});
}
//#endregion
//#region src/components/admin/UsersScreen.tsx
var DATE_FORMAT = new Intl.DateTimeFormat("en-GB", {
	day: "numeric",
	month: "long",
	year: "numeric"
});
var ROLE_OPTIONS = [
	"viewer",
	"editor",
	"admin"
];
function formatDate$1(iso) {
	const date = new Date(iso);
	return Number.isNaN(date.getTime()) ? iso : DATE_FORMAT.format(date);
}
async function fetchUsers() {
	const res = await fetch("/api/admin/users", { credentials: "same-origin" });
	const body = await res.json().catch(() => null);
	if (!res.ok) {
		const message = body?.error?.message ?? res.statusText;
		throw new Error(message);
	}
	return body;
}
function CreateUserForm({ onCreated }) {
	const emailId = (0, import_react.useId)();
	const passwordId = (0, import_react.useId)();
	const [email, setEmail] = (0, import_react.useState)("");
	const [password, setPassword] = (0, import_react.useState)("");
	const [roles, setRoles] = (0, import_react.useState)(["editor"]);
	const [emailError, setEmailError] = (0, import_react.useState)("");
	const [passwordError, setPasswordError] = (0, import_react.useState)("");
	const [rolesError, setRolesError] = (0, import_react.useState)("");
	const [submitting, setSubmitting] = (0, import_react.useState)(false);
	function toggleRole(role) {
		setRoles((prev) => prev.includes(role) ? prev.filter((r) => r !== role) : [...prev, role]);
	}
	async function onSubmit(event) {
		event.preventDefault();
		setEmailError("");
		setPasswordError("");
		setRolesError("");
		if (!email.trim()) {
			setEmailError("Email is required.");
			return;
		}
		if (password.length < 8) {
			setPasswordError("Password must be at least 8 characters.");
			return;
		}
		if (roles.length === 0) {
			setRolesError("Select at least one role.");
			return;
		}
		setSubmitting(true);
		try {
			const res = await fetch("/api/admin/users", {
				method: "POST",
				credentials: "same-origin",
				headers: {
					"Content-Type": "application/json",
					origin: window.location.origin
				},
				body: JSON.stringify({
					email: email.trim(),
					password,
					roles
				})
			});
			const body = await res.json().catch(() => null);
			if (!res.ok) {
				const message = body?.error?.message ?? res.statusText;
				setEmailError(message);
				return;
			}
			setEmail("");
			setPassword("");
			setRoles(["editor"]);
			onCreated();
		} finally {
			setSubmitting(false);
		}
	}
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
		className: `${surface()} flex flex-col gap-4 p-4`,
		onSubmit: (e) => void onSubmit(e),
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
				className: "text-lg text-fg",
				children: "Create user"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
				label: "Email",
				htmlFor: emailId,
				error: emailError || void 0,
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
					id: emailId,
					type: "email",
					autoComplete: "off",
					value: email,
					onChange: (e) => setEmail(e.target.value)
				})
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Field, {
				label: "Password",
				htmlFor: passwordId,
				error: passwordError || void 0,
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
					id: passwordId,
					type: "password",
					autoComplete: "new-password",
					value: password,
					onChange: (e) => setPassword(e.target.value)
				})
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", {
				className: "flex flex-col gap-2",
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", {
						className: "text-sm text-fg mb-1",
						children: "Roles"
					}),
					ROLE_OPTIONS.map((role) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
						className: "flex items-center gap-2 text-sm text-fg",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Checkbox, {
							checked: roles.includes(role),
							onCheckedChange: (checked) => {
								if (checked === true !== roles.includes(role)) toggleRole(role);
							}
						}), role]
					}, role)),
					rolesError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "text-sm text-destructive",
						children: rolesError
					}) : null
				]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				type: "submit",
				tone: "accent",
				radius: "sm",
				disabled: submitting,
				children: "Create user"
			}) })
		]
	});
}
function RoleEditor({ user, onSaved }) {
	const [roles, setRoles] = (0, import_react.useState)(user.roles);
	const [error, setError] = (0, import_react.useState)("");
	const [saving, setSaving] = (0, import_react.useState)(false);
	(0, import_react.useEffect)(() => {
		setRoles(user.roles);
	}, [user.roles]);
	function toggleRole(role) {
		setRoles((prev) => prev.includes(role) ? prev.filter((r) => r !== role) : [...prev, role]);
	}
	async function saveRoles() {
		setError("");
		setSaving(true);
		try {
			const res = await fetch(`/api/admin/users/${user.id}/roles`, {
				method: "PATCH",
				credentials: "same-origin",
				headers: {
					"Content-Type": "application/json",
					origin: window.location.origin
				},
				body: JSON.stringify({ roles })
			});
			const body = await res.json().catch(() => null);
			if (!res.ok) {
				const message = body?.error?.message ?? res.statusText;
				setError(message);
				return;
			}
			onSaved();
		} finally {
			setSaving(false);
		}
	}
	async function disableUser() {
		if (!window.confirm(`Disable ${user.email}? They will be signed out and cannot sign in again.`)) return;
		setError("");
		setSaving(true);
		try {
			const res = await fetch(`/api/admin/users/${user.id}/disable`, {
				method: "POST",
				credentials: "same-origin",
				headers: { origin: window.location.origin }
			});
			const body = await res.json().catch(() => null);
			if (!res.ok) {
				const message = body?.error?.message ?? res.statusText;
				setError(message);
				return;
			}
			onSaved();
		} finally {
			setSaving(false);
		}
	}
	if (user.status === "disabled") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
		className: "text-sm text-fg-muted",
		children: "Disabled"
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-2",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "flex flex-wrap gap-3",
				children: ROLE_OPTIONS.map((role) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
					className: "flex items-center gap-1 text-sm text-fg",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Checkbox, {
						checked: roles.includes(role),
						onCheckedChange: (checked) => {
							if (checked === true !== roles.includes(role)) toggleRole(role);
						}
					}), role]
				}, role))
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex flex-wrap gap-2",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					type: "button",
					tone: "accent",
					radius: "sm",
					size: "sm",
					disabled: saving,
					onClick: () => void saveRoles(),
					children: "Save roles"
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					type: "button",
					tone: "surface",
					radius: "sm",
					size: "sm",
					disabled: saving,
					onClick: () => void disableUser(),
					children: "Disable user"
				})]
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "text-sm text-destructive",
				children: error
			}) : null
		]
	});
}
function UsersScreen() {
	const [status, setStatus] = (0, import_react.useState)("loading");
	const [loadError, setLoadError] = (0, import_react.useState)("");
	const [users, setUsers] = (0, import_react.useState)([]);
	const [reloadKey, setReloadKey] = (0, import_react.useState)(0);
	const reload = (0, import_react.useCallback)(() => setReloadKey((k) => k + 1), []);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		setStatus("loading");
		fetchUsers().then((data) => {
			if (cancelled) return;
			setUsers(data.users);
			setStatus("ready");
		}).catch((err) => {
			if (cancelled) return;
			setLoadError(err instanceof Error ? err.message : "Failed to load users.");
			setStatus("error");
		});
		return () => {
			cancelled = true;
		};
	}, [reloadKey]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "users-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "users-heading",
			title: "Users",
			description: "Manage accounts and roles for this site."
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
			className: "flex flex-col gap-8",
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CreateUserForm, { onCreated: reload }),
				status === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "flex flex-col gap-2",
					"aria-hidden": "true",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "text" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })]
				}) : null,
				status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorState, {
					variant: "inline",
					title: "Users couldn't load",
					message: loadError,
					action: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "accent",
						radius: "sm",
						size: "sm",
						type: "button",
						onClick: () => reload(),
						children: "Try again"
					})
				}) : null,
				status === "ready" && users.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
					className: "text-sm text-fg-muted",
					children: "No users yet. Create the first account above."
				}) : null,
				status === "ready" && users.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					className: `${surface()} overflow-x-auto`,
					children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
						caption: "Site users",
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Email"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Roles"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Status"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Created"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
								scope: "col",
								children: "Actions"
							})
						] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: users.map((user) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: user.email }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: user.roles.join(", ") || "—" }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: user.status }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: formatDate$1(user.createdAt) }),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleEditor, {
								user,
								onSaved: reload
							}) })
						] }, user.id)) })]
					})
				}) : null
			]
		})]
	});
}
//#endregion
//#region src/components/admin/GroupEditorScreen.tsx
async function fieldsApiFetch(url, init) {
	const headers = new Headers(init?.headers);
	if (init?.body != null && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
	if (init?.method && init.method !== "GET" && !headers.has("origin")) headers.set("origin", window.location.origin);
	const res = await fetch(url, {
		...init,
		credentials: "same-origin",
		headers
	});
	const body = await res.json().catch(() => null);
	if (!res.ok) throw new Error(body?.error?.message ?? res.statusText);
	return body;
}
function makeFieldsClient() {
	return {
		async getEntityValues(ref, opts) {
			const params = new URLSearchParams({
				entityId: ref.entityId,
				entityType: ref.entityType
			});
			if (opts.subType) params.set("subType", opts.subType);
			return (await fieldsApiFetch(`/api/admin/fields?${params}`)).values;
		},
		async setEntityValues({ ref, groupId, values }) {
			await fieldsApiFetch("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "setValues",
					entityId: ref.entityId,
					groups: [{
						groupId,
						values
					}]
				})
			});
		},
		async resolveGroups(opts) {
			const params = new URLSearchParams({
				resource: "resolve-groups",
				entityType: opts.entityType
			});
			if (opts.subType) params.set("subType", opts.subType);
			return (await fieldsApiFetch(`/api/admin/fields?${params}`)).groups;
		},
		async listGroups(opts) {
			const params = new URLSearchParams({ resource: "groups" });
			if (opts.entityType) params.set("entityType", opts.entityType);
			if (opts.subType) params.set("subType", opts.subType);
			return (await fieldsApiFetch(`/api/admin/fields?${params}`)).groups;
		},
		async createGroup(group) {
			return (await fieldsApiFetch("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "createGroup",
					group
				})
			})).group;
		},
		async updateGroup(id, patch) {
			return (await fieldsApiFetch("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "updateGroup",
					id,
					patch
				})
			})).group;
		},
		async deleteGroup(id) {
			await fieldsApiFetch("/api/admin/fields", {
				method: "POST",
				body: JSON.stringify({
					action: "deleteGroup",
					id
				})
			});
		}
	};
}
function GroupEditorScreen() {
	const client = (0, import_react.useMemo)(() => makeFieldsClient(), []);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "field-groups-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "field-groups-heading",
			title: "Field groups",
			description: "Define reusable field groups for content entries."
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldsProvider, {
			client,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldGroupEditor, { entityType: "content" })
		})]
	});
}
//#endregion
//#region ../../packages/menus-react/dist/index.js
var MenuContext = (0, import_react.createContext)(null);
function MenuProvider({ client, children }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuContext.Provider, {
		value: client,
		children
	});
}
function useMenuClient() {
	const ctx = (0, import_react.useContext)(MenuContext);
	if (!ctx) throw new Error("useMenuClient must be used within <MenuProvider>");
	return ctx;
}
function toError(e) {
	return e instanceof Error ? e : new Error(String(e));
}
function removeNodeFromTree(items, itemId) {
	return items.filter((item) => item.id !== itemId).map((item) => ({
		...item,
		children: removeNodeFromTree(item.children, itemId)
	}));
}
function findNodeInTree(items, itemId) {
	for (const item of items) {
		if (item.id === itemId) return item;
		const found = findNodeInTree(item.children, itemId);
		if (found) return found;
	}
	return null;
}
function updateSubtreeDepth(node, parentDepth) {
	const depth = parentDepth + 1;
	return {
		...node,
		depth,
		children: node.children.map((child, index) => ({
			...updateSubtreeDepth(child, depth),
			position: index
		}))
	};
}
function applyReorderToTree(items, parentId, orderedIds) {
	if (parentId === null) {
		const byId = new Map(items.map((item) => [item.id, item]));
		return orderedIds.map((id, position) => {
			return {
				...byId.get(id),
				position,
				parentId: null,
				depth: 0
			};
		});
	}
	return items.map((item) => {
		if (item.id === parentId) {
			const byId = new Map(item.children.map((child) => [child.id, child]));
			const children = orderedIds.map((id, position) => {
				return {
					...byId.get(id),
					position,
					parentId,
					depth: item.depth + 1
				};
			});
			return {
				...item,
				children
			};
		}
		return {
			...item,
			children: applyReorderToTree(item.children, parentId, orderedIds)
		};
	});
}
function applyMoveToTree(items, itemId, newParentId, newPosition) {
	const node = findNodeInTree(items, itemId);
	if (!node) return items;
	const without = removeNodeFromTree(items, itemId);
	if (newParentId === null) {
		const roots = [...without];
		const moved = {
			...node,
			parentId: null,
			depth: 0,
			children: node.children.map((child, index) => ({
				...updateSubtreeDepth(child, 0),
				position: index
			}))
		};
		roots.splice(newPosition, 0, moved);
		return roots.map((item, position) => ({
			...item,
			position
		}));
	}
	return insertNodeUnderParent(without, newParentId, newPosition, node);
}
function insertNodeUnderParent(items, parentId, position, node) {
	return items.map((item) => {
		if (item.id === parentId) {
			const parentDepth = item.depth;
			const moved = {
				...node,
				parentId,
				depth: parentDepth + 1,
				children: node.children.map((child, index) => ({
					...updateSubtreeDepth(child, parentDepth + 1),
					position: index
				}))
			};
			const children = [...item.children];
			children.splice(position, 0, moved);
			return {
				...item,
				children: children.map((child, index) => ({
					...child,
					position: index
				}))
			};
		}
		return {
			...item,
			children: insertNodeUnderParent(item.children, parentId, position, node)
		};
	});
}
function useMenuTree(key, opts = {}) {
	const client = useMenuClient();
	const hasSeed = opts.initialData !== void 0;
	const [tree, setTree] = (0, import_react.useState)(opts.initialData ?? null);
	const [loading, setLoading] = (0, import_react.useState)(!hasSeed);
	const [error, setError] = (0, import_react.useState)(null);
	const [reloadToken, setReloadToken] = (0, import_react.useState)(0);
	const clientRef = (0, import_react.useRef)(client);
	clientRef.current = client;
	const menuKey = key;
	const prevMenuKey = (0, import_react.useRef)(menuKey);
	const reload = (0, import_react.useCallback)(() => {
		setReloadToken((t) => t + 1);
	}, []);
	(0, import_react.useEffect)(() => {
		const keyChanged = prevMenuKey.current !== menuKey;
		prevMenuKey.current = menuKey;
		if (hasSeed && reloadToken === 0 && !keyChanged) return;
		let cancelled = false;
		setLoading(true);
		setError(null);
		clientRef.current.getMenuTree(key).then((next) => {
			if (!cancelled) {
				setTree(next);
				setLoading(false);
			}
		}).catch((e) => {
			if (!cancelled) {
				setError(toError(e));
				setLoading(false);
			}
		});
		return () => {
			cancelled = true;
		};
	}, [
		menuKey,
		hasSeed,
		reloadToken
	]);
	const removeItem = (0, import_react.useCallback)(async (itemId) => {
		const snapshot = tree;
		setError(null);
		setTree((prev) => prev ? {
			...prev,
			items: removeNodeFromTree(prev.items, itemId)
		} : prev);
		try {
			await clientRef.current.removeItem(itemId);
		} catch (e) {
			setTree(snapshot);
			const err = toError(e);
			setError(err);
			throw err;
		}
	}, [tree]);
	return {
		tree,
		loading,
		error,
		reload,
		addItem: (0, import_react.useCallback)(async (menuId, input) => {
			const row = await clientRef.current.addItem(menuId, input);
			reload();
			return row;
		}, [reload]),
		updateItem: (0, import_react.useCallback)(async (itemId, patch) => {
			const row = await clientRef.current.updateItem(itemId, patch);
			reload();
			return row;
		}, [reload]),
		removeItem,
		moveItem: (0, import_react.useCallback)(async (itemId, input) => {
			const snapshot = tree;
			setError(null);
			setTree((prev) => prev ? {
				...prev,
				items: applyMoveToTree(prev.items, itemId, input.newParentId, input.newPosition)
			} : prev);
			try {
				return await clientRef.current.moveItem(itemId, input);
			} catch (e) {
				setTree(snapshot);
				const err = toError(e);
				setError(err);
				throw err;
			}
		}, [tree]),
		reorder: (0, import_react.useCallback)(async (menuId, parentId, orderedIds) => {
			const snapshot = tree;
			setError(null);
			setTree((prev) => prev ? {
				...prev,
				items: applyReorderToTree(prev.items, parentId, orderedIds)
			} : prev);
			try {
				await clientRef.current.reorder(menuId, parentId, orderedIds);
			} catch (e) {
				setTree(snapshot);
				const err = toError(e);
				setError(err);
				throw err;
			}
		}, [tree])
	};
}
function findNode(items, itemId) {
	for (const item of items) {
		if (item.id === itemId) return item;
		const found = findNode(item.children, itemId);
		if (found) return found;
	}
	return null;
}
function targetFromNode(item) {
	if (item.targetKind === "entity" && item.targetEntityType && item.targetEntityId) return `entity:${item.targetEntityType}:${item.targetEntityId}`;
	return "custom";
}
function parseTargetChoice(value, customUrl, availableTargets) {
	if (value === "custom") return {
		kind: "url",
		url: customUrl
	};
	if (value.startsWith("entity:")) {
		const [, entityType, entityId] = value.split(":");
		if (entityType && entityId) return {
			kind: "entity",
			entityType,
			entityId
		};
	}
	const match = availableTargets.find((t) => `entity:${t.entityType}:${t.entityId}` === value);
	if (match) return {
		kind: "entity",
		entityType: match.entityType,
		entityId: match.entityId
	};
	return {
		kind: "url",
		url: customUrl
	};
}
function MenuTreeItem({ item, siblings, index, availableTargets, actions, allItems }) {
	const [label, setLabel] = (0, import_react.useState)(item.label);
	const [targetChoice, setTargetChoice] = (0, import_react.useState)(targetFromNode(item));
	const [customUrl, setCustomUrl] = (0, import_react.useState)(item.url ?? "");
	const commitLabel = (0, import_react.useCallback)(() => {
		if (label !== item.label) actions.updateItem(item.id, { label }).catch(() => {});
	}, [
		actions,
		item.id,
		item.label,
		label
	]);
	const commitTarget = (0, import_react.useCallback)((nextChoice, nextUrl) => {
		actions.updateItem(item.id, { target: parseTargetChoice(nextChoice, nextUrl, availableTargets) }).catch(() => {});
	}, [
		actions,
		availableTargets,
		item.id
	]);
	const handleMoveUp = (0, import_react.useCallback)(() => {
		if (index === 0) return;
		const orderedIds = siblings.map((s) => s.id);
		[orderedIds[index - 1], orderedIds[index]] = [orderedIds[index], orderedIds[index - 1]];
		actions.reorder(actions.menuId, item.parentId, orderedIds).catch(() => {});
	}, [
		actions,
		index,
		item.parentId,
		siblings
	]);
	const handleMoveDown = (0, import_react.useCallback)(() => {
		if (index >= siblings.length - 1) return;
		const orderedIds = siblings.map((s) => s.id);
		[orderedIds[index], orderedIds[index + 1]] = [orderedIds[index + 1], orderedIds[index]];
		actions.reorder(actions.menuId, item.parentId, orderedIds).catch(() => {});
	}, [
		actions,
		index,
		item.parentId,
		siblings
	]);
	const handleIndent = (0, import_react.useCallback)(() => {
		if (index === 0) return;
		const prev = siblings[index - 1];
		actions.moveItem(item.id, {
			newParentId: prev.id,
			newPosition: prev.children.length
		}).catch(() => {});
	}, [
		actions,
		index,
		item.id,
		siblings
	]);
	const handleOutdent = (0, import_react.useCallback)(() => {
		if (item.parentId === null) return;
		const parent = findNode(allItems, item.parentId);
		if (!parent) return;
		actions.moveItem(item.id, {
			newParentId: parent.parentId,
			newPosition: parent.position + 1
		}).catch(() => {});
	}, [
		actions,
		allItems,
		item.id,
		item.parentId
	]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
		role: "treeitem",
		"aria-expanded": item.children.length > 0 ? true : void 0,
		className: "menus-editor__item",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
				type: "text",
				"aria-label": item.label,
				value: label,
				className: "menus-editor__label",
				onChange: (e) => setLabel(e.target.value),
				onBlur: commitLabel
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
				"aria-label": `${item.label} target`,
				value: targetChoice,
				className: "menus-editor__target",
				onChange: (e) => {
					const next = e.target.value;
					setTargetChoice(next);
					commitTarget(next, customUrl);
				},
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
					value: "custom",
					children: "Custom URL"
				}), availableTargets.map((target) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
					value: `entity:${target.entityType}:${target.entityId}`,
					children: target.label
				}, `${target.entityType}:${target.entityId}`))]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
				type: "text",
				"aria-label": `${item.label} custom URL`,
				value: customUrl,
				className: "menus-editor__url",
				onChange: (e) => setCustomUrl(e.target.value),
				onBlur: () => commitTarget(targetChoice, customUrl)
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				"aria-label": `Move ${item.label} up`,
				"aria-disabled": index === 0,
				onClick: handleMoveUp,
				children: "Move up"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				"aria-label": `Move ${item.label} down`,
				"aria-disabled": index === siblings.length - 1,
				onClick: handleMoveDown,
				children: "Move down"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				"aria-label": `Indent ${item.label}`,
				"aria-disabled": index === 0,
				onClick: handleIndent,
				children: "Indent"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				"aria-label": `Outdent ${item.label}`,
				"aria-disabled": item.parentId === null,
				onClick: handleOutdent,
				children: "Outdent"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
				type: "button",
				"aria-label": `Remove ${item.label}`,
				onClick: () => void actions.removeItem(item.id).catch(() => {}),
				children: "Remove"
			}),
			item.children.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
				role: "group",
				className: "menus-editor__children",
				children: item.children.map((child, childIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuTreeItem, {
					item: child,
					siblings: item.children,
					index: childIndex,
					availableTargets,
					actions,
					allItems
				}, child.id))
			}) : null
		]
	});
}
function MenuTreeList({ items, availableTargets, actions, rootItems }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuTreeItem, {
		item,
		siblings: items,
		index,
		availableTargets,
		actions,
		allItems: rootItems
	}, item.id)) });
}
function MenuEditor({ menuKey, availableTargets }) {
	const { tree, loading, error, addItem, updateItem, removeItem, moveItem, reorder } = useMenuTree(menuKey);
	const [newLabel, setNewLabel] = (0, import_react.useState)("");
	const [newTargetChoice, setNewTargetChoice] = (0, import_react.useState)("custom");
	const [newCustomUrl, setNewCustomUrl] = (0, import_react.useState)("");
	const actions = {
		menuId: tree?.menu.id ?? "",
		reorder,
		moveItem,
		removeItem,
		updateItem
	};
	const handleAddItem = (0, import_react.useCallback)((e) => {
		e.preventDefault();
		if (!tree || !newLabel.trim()) return;
		addItem(tree.menu.id, {
			label: newLabel.trim(),
			target: parseTargetChoice(newTargetChoice, newCustomUrl, availableTargets),
			parentId: null
		}).catch(() => {});
		setNewLabel("");
		setNewCustomUrl("");
		setNewTargetChoice("custom");
	}, [
		addItem,
		availableTargets,
		newCustomUrl,
		newLabel,
		newTargetChoice,
		tree
	]);
	if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
		className: "menus-editor__loading",
		children: "Loading menu…"
	});
	if (!tree) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
		className: "menus-editor__empty",
		children: "No menu."
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "menus-editor",
		style: { containerType: "inline-size" },
		children: [
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				role: "alert",
				tabIndex: 0,
				className: "menus-editor__error",
				children: error.message
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
				role: "tree",
				className: "menus-editor__tree",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuTreeList, {
					items: tree.items,
					availableTargets,
					actions,
					rootItems: tree.items
				})
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
				className: "menus-editor__add",
				onSubmit: handleAddItem,
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
						type: "text",
						"aria-label": "New item label",
						value: newLabel,
						className: "menus-editor__new-label",
						onChange: (e) => setNewLabel(e.target.value)
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
						"aria-label": "New item target",
						value: newTargetChoice,
						className: "menus-editor__new-target",
						onChange: (e) => setNewTargetChoice(e.target.value),
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
							value: "custom",
							children: "Custom URL"
						}), availableTargets.map((target) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
							value: `entity:${target.entityType}:${target.entityId}`,
							children: target.label
						}, `new-${target.entityType}:${target.entityId}`))]
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
						type: "text",
						"aria-label": "New item custom URL",
						value: newCustomUrl,
						className: "menus-editor__new-url",
						onChange: (e) => setNewCustomUrl(e.target.value)
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
						type: "submit",
						className: "menus-editor__add-button",
						children: "Add menu item"
					})
				]
			})
		]
	});
}
//#endregion
//#region src/components/admin/MenuEditorScreen.tsx
async function menusApiFetch(url, init) {
	const headers = new Headers(init?.headers);
	if (init?.body != null && !headers.has("Content-Type")) headers.set("Content-Type", "application/json");
	if (init?.method && init.method !== "GET" && !headers.has("origin")) headers.set("origin", window.location.origin);
	const res = await fetch(url, {
		...init,
		credentials: "same-origin",
		headers
	});
	const body = await res.json().catch(() => null);
	if (!res.ok) throw new Error(body?.error?.message ?? res.statusText);
	return body;
}
function makeMenuClient() {
	return {
		async listMenus() {
			return (await menusApiFetch("/api/admin/menus")).menus;
		},
		async getMenuTree(key) {
			return (await menusApiFetch(`/api/admin/menus?key=${encodeURIComponent(key)}`)).tree;
		},
		async createMenu(input) {
			return (await menusApiFetch("/api/admin/menus", {
				method: "POST",
				body: JSON.stringify({
					action: "createMenu",
					key: input.key,
					label: input.label
				})
			})).menu;
		},
		async updateMenu(menuId, patch) {
			return (await menusApiFetch("/api/admin/menus", {
				method: "PATCH",
				body: JSON.stringify({
					resource: "menu",
					menuId,
					patch
				})
			})).menu;
		},
		async deleteMenu(menuId) {
			await menusApiFetch("/api/admin/menus", {
				method: "DELETE",
				body: JSON.stringify({
					resource: "menu",
					menuId
				})
			});
		},
		async addItem(menuId, input) {
			return (await menusApiFetch("/api/admin/menus", {
				method: "POST",
				body: JSON.stringify({
					action: "addItem",
					menuId,
					label: input.label,
					target: input.target,
					...input.parentId ? { parentId: input.parentId } : {}
				})
			})).item;
		},
		async updateItem(itemId, patch) {
			return (await menusApiFetch("/api/admin/menus", {
				method: "PATCH",
				body: JSON.stringify({
					resource: "item",
					itemId,
					patch
				})
			})).item;
		},
		async removeItem(itemId) {
			await menusApiFetch("/api/admin/menus", {
				method: "DELETE",
				body: JSON.stringify({
					resource: "item",
					itemId
				})
			});
		},
		async moveItem(itemId, input) {
			return (await menusApiFetch("/api/admin/menus", {
				method: "POST",
				body: JSON.stringify({
					action: "moveItem",
					itemId,
					...input
				})
			})).item;
		},
		async reorder(menuId, parentId, orderedIds) {
			await menusApiFetch("/api/admin/menus", {
				method: "POST",
				body: JSON.stringify({
					action: "reorderItems",
					menuId,
					parentId,
					orderedIds
				})
			});
		}
	};
}
function MenuEditorBody({ availableTargets }) {
	const client = useMenuClient();
	const [seeding, setSeeding] = (0, import_react.useState)(false);
	const [seedError, setSeedError] = (0, import_react.useState)(null);
	const [hasPrimary, setHasPrimary] = (0, import_react.useState)(null);
	const refreshPrimaryExists = (0, import_react.useCallback)(async () => {
		const tree = await client.getMenuTree("primary");
		setHasPrimary(tree != null);
	}, [client]);
	(0, import_react.useEffect)(() => {
		refreshPrimaryExists();
	}, [refreshPrimaryExists]);
	const seedPrimaryFromDefaults = (0, import_react.useCallback)(async () => {
		setSeeding(true);
		setSeedError(null);
		try {
			const menu = await client.createMenu({
				key: "primary",
				label: "Primary"
			});
			for (const item of DEFAULT_PRIMARY) await client.addItem(menu.id, {
				label: item.label,
				target: {
					kind: "url",
					url: item.href
				},
				parentId: null
			});
			setHasPrimary(true);
			window.location.reload();
		} catch (error) {
			setSeedError(error instanceof Error ? error.message : "Could not create primary menu.");
		} finally {
			setSeeding(false);
		}
	}, [client]);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [hasPrimary === false ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "mb-4 flex flex-col gap-2",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
			tone: "surface",
			radius: "sm",
			size: "sm",
			type: "button",
			disabled: seeding,
			onClick: () => void seedPrimaryFromDefaults(),
			children: "Create primary menu from defaults"
		}), seedError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
			role: "alert",
			className: "text-sm text-fg-muted",
			children: seedError
		}) : null]
	}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuEditor, {
		menuKey: "primary",
		availableTargets
	})] });
}
function MenuEditorScreen() {
	const client = (0, import_react.useMemo)(() => makeMenuClient(), []);
	const [availableTargets, setAvailableTargets] = (0, import_react.useState)([]);
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		makeContentClient().list({ status: "published" }).then((entries) => {
			if (cancelled) return;
			setAvailableTargets(entries.map((entry) => ({
				entityType: "content",
				entityId: entry.id,
				label: entry.title
			})));
		}).catch(() => {
			if (!cancelled) setAvailableTargets([]);
		});
		return () => {
			cancelled = true;
		};
	}, []);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "menus-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "menus-heading",
			title: "Menus",
			description: "Manage site navigation links for the public header."
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuProvider, {
			client,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuEditorBody, { availableTargets })
		})]
	});
}
//#endregion
//#region src/components/admin/content-types/definition-admin-client.ts
async function responseJson(response) {
	const body = await response.json().catch(() => null);
	if (!response.ok) {
		const error = body?.error;
		throw new Error(error?.message ?? (response.statusText || "Definition operation failed"));
	}
	return body;
}
async function fetchDefinitionSnapshot() {
	return await responseJson(await fetch("/api/admin/content-model/definitions", { credentials: "same-origin" }));
}
async function postDefinitionAction(body) {
	return await responseJson(await fetch("/api/admin/content-model/definitions", {
		method: "POST",
		credentials: "same-origin",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify(body)
	}));
}
function operationId(prefix) {
	return `${prefix}:${crypto.randomUUID()}`;
}
function parseJsonObject(source, label) {
	let value;
	try {
		value = JSON.parse(source);
	} catch {
		throw new Error(`${label} must be valid JSON`);
	}
	if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${label} must be a JSON object`);
	return value;
}
//#endregion
//#region src/components/admin/content-types/DefinitionBackupRecoveryPanel.tsx
var DATE_FORMATTER = new Intl.DateTimeFormat("en-GB", {
	day: "numeric",
	month: "long",
	year: "numeric",
	timeZone: "UTC"
});
function formatDate(value) {
	const date = new Date(value);
	return Number.isNaN(date.getTime()) ? "Unknown date" : DATE_FORMATTER.format(date);
}
function DefinitionBackupRecoveryPanel({ kind, backups, onRestored }) {
	const available = (0, import_react.useMemo)(() => backups.filter((backup) => backup.kind === kind), [backups, kind]);
	const [selectedId, setSelectedId] = (0, import_react.useState)("");
	const [preview, setPreview] = (0, import_react.useState)(null);
	const [confirmed, setConfirmed] = (0, import_react.useState)(false);
	const [busy, setBusy] = (0, import_react.useState)(false);
	const [error, setError] = (0, import_react.useState)(null);
	const selected = available.find((backup) => backup.manifest.id === selectedId) ?? null;
	const run = async (operation) => {
		setBusy(true);
		setError(null);
		try {
			await operation();
		} catch (caught) {
			setError(caught instanceof Error ? caught.message : "Definition backup operation failed");
		} finally {
			setBusy(false);
		}
	};
	const previewRestore = () => run(async () => {
		if (!selected) throw new Error("Select a definition backup");
		const next = await postDefinitionAction({
			action: "previewBackupRestore",
			kind,
			manifest: selected.manifest
		});
		setPreview(next);
		setConfirmed(false);
	});
	const restore = () => run(async () => {
		if (!preview) throw new Error("Preview the restore first");
		await postDefinitionAction({
			action: kind === "content" ? "restoreContentBackup" : "restoreFieldsBackup",
			manifest: preview.manifest,
			destinationCorpusHash: preview.destinationCorpusHash,
			operationId: operationId(`admin:${kind}:backup-restore`)
		});
		setPreview(null);
		setConfirmed(false);
		setSelectedId("");
		await onRestored();
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		className: "flex flex-col gap-4 border-t border-border pt-6",
		"aria-labelledby": `${kind}-definition-backups-heading`,
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
				id: `${kind}-definition-backups-heading`,
				className: "font-semibold text-fg",
				children: "Definition backups"
			}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "mt-2 text-sm text-fg-muted",
				children: "Restore an immutable backup only after checking the current destination corpus."
			})] }),
			available.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "flex flex-wrap items-center gap-4",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
					className: "text-sm text-fg-muted",
					children: [
						"No immutable ",
						kind,
						" definition backups have been created yet."
					]
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					size: "sm",
					onClick: () => void onRestored(),
					disabled: busy,
					children: "Refresh backups"
				})]
			}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
					className: "flex max-w-2xl flex-col gap-2 text-sm text-fg",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
						className: "font-medium",
						children: "Backup"
					}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
						className: "rounded-[2px] border border-border bg-canvas p-2",
						value: selectedId,
						onChange: (event) => {
							setSelectedId(event.currentTarget.value);
							setPreview(null);
							setConfirmed(false);
						},
						disabled: busy,
						children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
							value: "",
							children: "Select backup…"
						}), available.map((backup) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
							value: backup.manifest.id,
							children: [
								formatDate(backup.createdAt),
								" · ",
								backup.manifest.id,
								" · ",
								backup.manifest.byteCount,
								" bytes"
							]
						}, backup.manifest.id))]
					})]
				}),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					onClick: () => void previewRestore(),
					disabled: busy || !selected,
					children: "Preview restore"
				}) }),
				preview ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "max-w-3xl rounded-[2px] border border-border bg-surface p-4",
					role: "status",
					"aria-live": "polite",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
							className: "font-medium text-fg",
							children: "Restore preview"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", {
							className: "mt-4 grid gap-2 sm:grid-cols-2",
							children: Object.entries(preview.manifest.itemCounts).map(([name, count]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
								className: "text-sm text-fg-muted",
								children: name
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
								className: "text-sm text-fg",
								children: count
							})] }, name))
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
							className: "mt-4 text-sm text-fg-muted",
							children: "The destination corpus was checked after this backup was selected. Any later drift will reject the restore."
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "mt-4 flex items-start gap-2 text-sm text-fg",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								type: "checkbox",
								checked: confirmed,
								onChange: (event) => setConfirmed(event.currentTarget.checked)
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "I reviewed this backup and confirm restoring its affected definition data." })]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
							className: "mt-4",
							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "danger",
								onClick: () => void restore(),
								disabled: busy || !confirmed,
								children: "Restore reviewed backup"
							})
						})
					]
				}) : null
			] }),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				role: "alert",
				className: "text-sm text-danger",
				children: error
			}) : null
		]
	});
}
//#endregion
//#region src/components/admin/content-types/ContentTypesAdminScreen.tsx
function editable(value) {
	const { origin: _origin, version: _version, revision: _revision, canonicalHash: _canonicalHash, shadowedDbVersion: _shadowed, ...definition } = value;
	return definition;
}
function JsonEditor({ label, value, onChange, disabled = false }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
		className: "flex flex-col gap-2 text-sm text-fg",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
			className: "font-medium",
			children: label
		}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
			className: "min-h-52 rounded-[2px] border border-border bg-surface p-4 font-mono text-sm text-fg",
			value,
			onChange: (event) => onChange(event.currentTarget.value),
			disabled,
			spellCheck: false
		})]
	});
}
function Impact$1({ impact }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "rounded-[2px] border border-border bg-surface p-4",
		role: "status",
		"aria-live": "polite",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "font-medium text-fg",
				children: "Impact preview"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", {
				className: "mt-2 grid grid-cols-2 gap-2 text-sm",
				children: Object.entries(impact.affectedCounts).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
					className: "text-fg-muted",
					children: key
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
					className: "text-fg",
					children: value
				})] }, key))
			}),
			impact.incompatibilities.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
				className: "mt-4 list-disc pl-6 text-sm text-danger",
				children: impact.incompatibilities.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: item }, item))
			}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "mt-4 text-sm text-fg-muted",
				children: "No incompatibilities detected."
			})
		]
	});
}
function ContentTypesAdminScreen() {
	const [snapshot, setSnapshot] = (0, import_react.useState)(null), [error, setError] = (0, import_react.useState)(null), [busy, setBusy] = (0, import_react.useState)(false);
	const [typeKey, setTypeKey] = (0, import_react.useState)(""), [typeJson, setTypeJson] = (0, import_react.useState)("{}"), [typeDelete, setTypeDelete] = (0, import_react.useState)(false), [typeStrategy, setTypeStrategy] = (0, import_react.useState)("reject"), [typePreview, setTypePreview] = (0, import_react.useState)(null), [typeConfirmed, setTypeConfirmed] = (0, import_react.useState)(false);
	const [statusKey, setStatusKey] = (0, import_react.useState)(""), [statusJson, setStatusJson] = (0, import_react.useState)("{}"), [statusDelete, setStatusDelete] = (0, import_react.useState)(false), [statusTarget, setStatusTarget] = (0, import_react.useState)(""), [statusPreview, setStatusPreview] = (0, import_react.useState)(null), [statusConfirmed, setStatusConfirmed] = (0, import_react.useState)(false);
	const load = async () => {
		setError(null);
		try {
			setSnapshot(await fetchDefinitionSnapshot());
		} catch (e) {
			setError(e instanceof Error ? e.message : "Failed to load definitions");
		}
	};
	(0, import_react.useEffect)(() => {
		load();
	}, []);
	const selectedType = (0, import_react.useMemo)(() => snapshot?.contentTypes.find((item) => item.key === typeKey) ?? null, [snapshot, typeKey]);
	const selectedStatus = (0, import_react.useMemo)(() => snapshot?.contentStatuses.find((item) => item.key === statusKey) ?? null, [snapshot, statusKey]);
	(0, import_react.useEffect)(() => {
		if (selectedType) setTypeJson(JSON.stringify(editable(selectedType), null, 2));
		setTypePreview(null);
		setTypeConfirmed(false);
	}, [selectedType]);
	(0, import_react.useEffect)(() => {
		if (selectedStatus) setStatusJson(JSON.stringify(editable(selectedStatus), null, 2));
		setStatusPreview(null);
		setStatusConfirmed(false);
	}, [selectedStatus]);
	const run = async (fn, reload = true) => {
		setBusy(true);
		setError(null);
		try {
			await fn();
			if (reload) await load();
		} catch (e) {
			setError(e instanceof Error ? e.message : "Definition operation failed");
		} finally {
			setBusy(false);
		}
	};
	const typeStrategies = () => {
		if (typeStrategy === "deactivate") return [{ kind: "deactivate" }];
		if (typeStrategy === "flattenHierarchy") return [{ kind: "flattenHierarchy" }];
		if (typeStrategy === "purgeExcerpt") return [{
			kind: "purgeFeatureData",
			features: ["excerpt"],
			backupId: ""
		}];
		return [{ kind: "reject" }];
	};
	const previewType = () => run(async () => {
		if (!selectedType) throw new Error("Select a content type");
		const patch = parseJsonObject(typeJson, "Content type definition");
		const preview = await postDefinitionAction({
			action: "previewContentType",
			key: selectedType.key,
			expectedVersion: selectedType.version,
			patch,
			deactivate: typeStrategy === "deactivate",
			delete: typeDelete,
			strategies: typeStrategies()
		});
		setTypePreview(preview);
		setTypeConfirmed(false);
	}, false);
	const applyType = () => run(async () => {
		if (!typePreview) throw new Error("Preview the change first");
		await postDefinitionAction({
			action: "applyContentType",
			impactToken: typePreview.impact.token,
			strategies: typePreview.strategies,
			operationId: operationId("admin:type")
		});
		setTypePreview(null);
		setTypeConfirmed(false);
	});
	const createType = () => run(async () => {
		await postDefinitionAction({
			action: "createContentType",
			definition: parseJsonObject(typeJson, "Content type definition"),
			operationId: operationId("admin:type:create")
		});
	});
	const statusStrategy = () => statusTarget ? {
		kind: "map",
		targetStatusKey: statusTarget
	} : { kind: "reject" };
	const previewStatus = () => run(async () => {
		if (!selectedStatus) throw new Error("Select a content status");
		const patch = parseJsonObject(statusJson, "Content status definition");
		setStatusPreview(await postDefinitionAction({
			action: "previewContentStatus",
			key: selectedStatus.key,
			expectedVersion: selectedStatus.version,
			patch,
			deactivate: false,
			delete: statusDelete,
			strategy: statusStrategy()
		}));
		setStatusConfirmed(false);
	}, false);
	const applyStatus = () => run(async () => {
		if (!statusPreview) throw new Error("Preview the change first");
		await postDefinitionAction({
			action: "applyContentStatus",
			impactToken: statusPreview.token,
			strategy: statusStrategy(),
			operationId: operationId("admin:status")
		});
		setStatusPreview(null);
		setStatusConfirmed(false);
	});
	const createStatus = () => run(async () => {
		await postDefinitionAction({
			action: "createContentStatus",
			definition: parseJsonObject(statusJson, "Content status definition"),
			operationId: operationId("admin:status:create")
		});
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-6",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				title: "Content types & statuses",
				description: "Manage database-owned definitions. Code-owned definitions are visible but deploy-owned and read-only.",
				actions: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					size: "sm",
					onClick: () => void load(),
					disabled: busy,
					children: "Refresh"
				})
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				role: "alert",
				className: "rounded-[2px] border border-danger p-4 text-sm text-danger",
				children: error
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
				className: "grid gap-4 xl:grid-cols-[18rem_1fr]",
				"aria-labelledby": "types-heading",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "rounded-[2px] border border-border bg-surface p-4",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
							id: "types-heading",
							className: "font-semibold text-fg",
							children: "Content types"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "mt-4 flex flex-col gap-2 text-sm text-fg",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
								className: "font-medium",
								children: "Content type"
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
								className: "w-full rounded-[2px] border border-border bg-canvas p-2 text-sm",
								value: typeKey,
								onChange: (e) => setTypeKey(e.currentTarget.value),
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "",
									children: "New type…"
								}), snapshot?.contentTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
									value: item.key,
									children: [
										item.labels.singularName,
										" · ",
										item.key,
										" · ",
										item.origin
									]
								}, item.key))]
							})]
						}),
						selectedType?.origin === "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
							className: "mt-2 text-sm text-warning",
							children: ["Deploy-owned code definition. Change it through code reconciliation, not the admin UI.", selectedType.shadowedDbVersion ? ` Database shadow version ${selectedType.shadowedDbVersion} is retained for diagnostics.` : ""]
						}) : null
					]
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "flex flex-col gap-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(JsonEditor, {
						label: selectedType ? "Definition patch / replacement" : "New content type JSON",
						value: typeJson,
						onChange: (v) => {
							setTypeJson(v);
							setTypePreview(null);
						},
						disabled: selectedType?.origin === "code"
					}), selectedType && selectedType.origin !== "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "grid gap-4 md:grid-cols-3",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm",
								children: ["Strategy", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
									className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
									value: typeStrategy,
									onChange: (e) => {
										setTypeStrategy(e.currentTarget.value);
										setTypePreview(null);
									},
									children: [
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "reject",
											children: "Reject incompatible change"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "deactivate",
											children: "Deactivate"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "flattenHierarchy",
											children: "Flatten hierarchy"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "purgeExcerpt",
											children: "Purge excerpt with backup"
										})
									]
								})]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "flex items-center gap-2 self-end text-sm",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
									type: "checkbox",
									checked: typeDelete,
									onChange: (e) => {
										setTypeDelete(e.currentTarget.checked);
										setTypePreview(null);
									}
								}), " Delete definition"]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "surface",
								onClick: () => void previewType(),
								disabled: busy,
								children: "Preview impact"
							})
						]
					}), typePreview ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Impact$1, { impact: typePreview.impact }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "flex items-center gap-2 text-sm",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								type: "checkbox",
								checked: typeConfirmed,
								onChange: (e) => setTypeConfirmed(e.currentTarget.checked)
							}), " I reviewed the impact and confirm this definition change."]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: typeDelete || typeStrategy === "deactivate" || typeStrategy === "flattenHierarchy" || typeStrategy === "purgeExcerpt" ? "danger" : "accent",
							onClick: () => void applyType(),
							disabled: busy || !typeConfirmed,
							children: "Apply reviewed change"
						})
					] }) : null] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						onClick: () => void createType(),
						disabled: busy,
						children: "Create content type"
					})]
				})]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
				className: "grid gap-4 xl:grid-cols-[18rem_1fr]",
				"aria-labelledby": "statuses-heading",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "rounded-[2px] border border-border bg-surface p-4",
					children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
							id: "statuses-heading",
							className: "font-semibold text-fg",
							children: "Statuses"
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "mt-4 flex flex-col gap-2 text-sm text-fg",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
								className: "font-medium",
								children: "Status"
							}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
								className: "w-full rounded-[2px] border border-border bg-canvas p-2 text-sm",
								value: statusKey,
								onChange: (e) => setStatusKey(e.currentTarget.value),
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
									value: "",
									children: "New status…"
								}), snapshot?.contentStatuses.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
									value: item.key,
									children: [
										item.label,
										" · ",
										item.key,
										" · ",
										item.origin
									]
								}, item.key))]
							})]
						}),
						selectedStatus?.origin === "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
							className: "mt-2 text-sm text-warning",
							children: ["Deploy-owned code status.", selectedStatus.shadowedDbVersion ? ` Database shadow version ${selectedStatus.shadowedDbVersion} is retained for diagnostics.` : ""]
						}) : null
					]
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
					className: "flex flex-col gap-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(JsonEditor, {
						label: selectedStatus ? "Definition patch / replacement" : "New status JSON",
						value: statusJson,
						onChange: (v) => {
							setStatusJson(v);
							setStatusPreview(null);
						},
						disabled: selectedStatus?.origin === "code"
					}), selectedStatus && selectedStatus.origin !== "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "grid gap-4 md:grid-cols-3",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm",
								children: ["Map references to", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
									className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
									value: statusTarget,
									onChange: (e) => {
										setStatusTarget(e.currentTarget.value);
										setStatusPreview(null);
									},
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: "",
										children: "Reject if referenced"
									}), snapshot?.contentStatuses.filter((item) => item.key !== selectedStatus.key && item.active).map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: item.key,
										children: item.label
									}, item.key))]
								})]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "flex items-center gap-2 self-end text-sm",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
									type: "checkbox",
									checked: statusDelete,
									onChange: (e) => {
										setStatusDelete(e.currentTarget.checked);
										setStatusPreview(null);
									}
								}), " Delete status"]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "surface",
								onClick: () => void previewStatus(),
								disabled: busy,
								children: "Preview impact"
							})
						]
					}), statusPreview ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Impact$1, { impact: statusPreview }),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
							className: "flex items-center gap-2 text-sm",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
								type: "checkbox",
								checked: statusConfirmed,
								onChange: (e) => setStatusConfirmed(e.currentTarget.checked)
							}), " I reviewed the affected entries and confirm this status change."]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: statusDelete ? "danger" : "surface",
							onClick: () => void applyStatus(),
							disabled: busy || !statusConfirmed,
							children: "Apply reviewed change"
						})
					] }) : null] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "surface",
						onClick: () => void createStatus(),
						disabled: busy,
						children: "Create status"
					})]
				})]
			})
		]
	});
}
//#endregion
//#region src/components/admin/fields/FieldsAdminScreen.tsx
var NEW_GROUP = Object.freeze({
	key: "new_group",
	title: "New field group",
	active: true,
	location: Object.freeze([Object.freeze([{
		parameter: "entityType",
		operator: "eq",
		value: "content"
	}])]),
	fields: Object.freeze([])
});
function stripResolved$2(group) {
	const { origin: _origin, version: _version, revision: _revision, shadowedDbVersion: _shadowed, ...definition } = group;
	return definition;
}
function parseMappings(source) {
	if (!source.trim()) return Object.freeze([]);
	const value = JSON.parse(source);
	if (!Array.isArray(value)) throw new Error("Migration mappings must be a JSON array");
	return value;
}
function Impact({ impact }) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "rounded-[2px] border border-border bg-surface p-4",
		role: "status",
		"aria-live": "polite",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
				className: "font-medium text-fg",
				children: "Impact preview"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", {
				className: "mt-2 grid gap-2 sm:grid-cols-2",
				children: Object.entries(impact.affectedCounts).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
					className: "text-sm text-fg-muted",
					children: key
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
					className: "text-sm text-fg",
					children: value
				})] }, key))
			}),
			impact.incompatibilities.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
				className: "mt-4 list-disc pl-6 text-sm text-danger",
				children: impact.incompatibilities.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: item }, item))
			}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
				className: "mt-4 text-sm text-fg-muted",
				children: "No incompatibilities detected."
			})
		]
	});
}
function FieldsAdminScreen() {
	const [snapshot, setSnapshot] = (0, import_react.useState)(null), [selectedKey, setSelectedKey] = (0, import_react.useState)(""), [draft, setDraft] = (0, import_react.useState)(NEW_GROUP), [strategyKind, setStrategyKind] = (0, import_react.useState)("reject"), [mappings, setMappings] = (0, import_react.useState)("[]"), [preview, setPreview] = (0, import_react.useState)(null), [confirmed, setConfirmed] = (0, import_react.useState)(false), [busy, setBusy] = (0, import_react.useState)(false), [error, setError] = (0, import_react.useState)(null);
	const load = async () => {
		setError(null);
		try {
			setSnapshot(await fetchDefinitionSnapshot());
		} catch (e) {
			setError(e instanceof Error ? e.message : "Failed to load field definitions");
		}
	};
	(0, import_react.useEffect)(() => {
		load();
	}, []);
	const selected = (0, import_react.useMemo)(() => snapshot?.fieldGroups.find((group) => group.key === selectedKey) ?? null, [snapshot, selectedKey]);
	(0, import_react.useEffect)(() => {
		setDraft(selected ? stripResolved$2(selected) : NEW_GROUP);
		setPreview(null);
		setConfirmed(false);
	}, [selected]);
	const run = async (fn, reload = true) => {
		setBusy(true);
		setError(null);
		try {
			await fn();
			if (reload) await load();
		} catch (e) {
			setError(e instanceof Error ? e.message : "Field definition operation failed");
		} finally {
			setBusy(false);
		}
	};
	const strategy = () => {
		if (strategyKind === "migrateValues") return {
			kind: "migrateValues",
			mappings: parseMappings(mappings)
		};
		if (strategyKind === "purgeValues") return {
			kind: "purgeValues",
			backupId: ""
		};
		return { kind: strategyKind };
	};
	const create = () => run(async () => {
		await postDefinitionAction({
			action: "createFieldGroup",
			definition: draft,
			operationId: operationId("admin:field-group:create")
		});
	});
	const previewChange = () => run(async () => {
		if (!selected) throw new Error("Select a field group");
		const response = await postDefinitionAction({
			action: "previewFieldGroup",
			key: selected.key,
			expectedVersion: selected.version,
			patch: draft,
			strategy: strategy()
		});
		setPreview(response);
		setConfirmed(false);
	}, false);
	const apply = () => run(async () => {
		if (!preview) throw new Error("Preview the field-group change first");
		await postDefinitionAction({
			action: "applyFieldGroup",
			impactToken: preview.impact.token,
			strategy: preview.strategy,
			operationId: operationId("admin:field-group")
		});
		setPreview(null);
		setConfirmed(false);
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-6",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				title: "Field groups",
				description: "Build complete field groups, preview value migrations, and keep code-owned groups deploy-controlled.",
				actions: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					size: "sm",
					onClick: () => void load(),
					disabled: busy,
					children: "Refresh"
				})
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				role: "alert",
				className: "rounded-[2px] border border-danger p-4 text-sm text-danger",
				children: error
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "grid gap-4 xl:grid-cols-[18rem_1fr]",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
					className: "rounded-[2px] border border-border bg-surface p-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
						className: "text-sm font-medium text-fg",
						children: ["Field group", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
							value: selectedKey,
							onChange: (e) => setSelectedKey(e.currentTarget.value),
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: "",
								children: "New group…"
							}), snapshot?.fieldGroups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
								value: group.key,
								children: [
									group.title,
									" · ",
									group.key,
									" · ",
									group.origin
								]
							}, group.key))]
						})]
					}), selected?.origin === "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
						className: "mt-4 text-sm text-warning",
						children: ["This key is deploy-owned. The effective definition is read-only here.", selected.shadowedDbVersion ? ` Database shadow version ${selected.shadowedDbVersion} is retained for diagnostics.` : " No database shadow is active."]
					}) : null]
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", {
					className: "flex min-w-0 flex-col gap-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldGroupDefinitionBuilder, {
						value: draft,
						onChange: (next) => {
							setDraft(next);
							setPreview(null);
						},
						disabled: selected?.origin === "code"
					}), selected && selected.origin !== "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "grid gap-4 md:grid-cols-2",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm text-fg",
								children: ["Migration strategy", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
									className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
									value: strategyKind,
									onChange: (e) => {
										setStrategyKind(e.currentTarget.value);
										setPreview(null);
									},
									children: [
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "reject",
											children: "Reject incompatible changes"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "deactivate",
											children: "Deactivate group"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "retainValues",
											children: "Retain existing values"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "migrateValues",
											children: "Map field paths"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "purgeValues",
											children: "Purge values with immutable backup"
										})
									]
								})]
							}), strategyKind === "migrateValues" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm text-fg",
								children: ["Path mappings JSON", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
									className: "mt-2 min-h-24 w-full rounded-[2px] border border-border bg-canvas p-2 font-mono text-sm",
									value: mappings,
									onChange: (e) => {
										setMappings(e.currentTarget.value);
										setPreview(null);
									}
								})]
							}) : null]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
							tone: "surface",
							onClick: () => void previewChange(),
							disabled: busy,
							children: "Preview impact"
						}),
						preview ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Impact, { impact: preview.impact }),
							preview.backup ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
								className: "text-sm text-fg-muted",
								children: "An immutable backup was created for this exact preview before the destructive token was sealed."
							}) : null,
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "flex items-center gap-2 text-sm",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
									type: "checkbox",
									checked: confirmed,
									onChange: (e) => setConfirmed(e.currentTarget.checked)
								}), " I reviewed the affected values and confirm this field-group change."]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: preview.strategy.kind === "purgeValues" ? "danger" : "accent",
								onClick: () => void apply(),
								disabled: busy || !confirmed,
								children: "Apply reviewed change"
							})
						] }) : null
					] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						onClick: () => void create(),
						disabled: busy,
						children: "Create field group"
					})]
				})]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DefinitionBackupRecoveryPanel, {
				kind: "fields",
				backups: snapshot?.backups ?? [],
				onRestored: load
			})
		]
	});
}
//#endregion
//#region src/components/admin/options/OptionsAdminScreen.tsx
var NEW_PAGE = Object.freeze({
	key: "site_options",
	title: "Site options",
	menuTitle: "Site options",
	readCapability: "fields.manage",
	writeCapability: "fields.manage",
	manageCapability: "fields.manage",
	position: 50,
	autoload: false
});
function stripResolved$1(page) {
	const { origin: _origin, version: _version, active: _active, shadowedDbVersion: _shadowed, ...definition } = page;
	return definition;
}
function OptionsAdminScreen() {
	const [snapshot, setSnapshot] = (0, import_react.useState)(null), [selectedKey, setSelectedKey] = (0, import_react.useState)(""), [draft, setDraft] = (0, import_react.useState)(NEW_PAGE), [preview, setPreview] = (0, import_react.useState)(null), [purge, setPurge] = (0, import_react.useState)(false), [confirmed, setConfirmed] = (0, import_react.useState)(false), [busy, setBusy] = (0, import_react.useState)(false), [error, setError] = (0, import_react.useState)(null);
	const load = async () => {
		setError(null);
		try {
			setSnapshot(await fetchDefinitionSnapshot());
		} catch (e) {
			setError(e instanceof Error ? e.message : "Failed to load options pages");
		}
	};
	(0, import_react.useEffect)(() => {
		load();
	}, []);
	const selected = (0, import_react.useMemo)(() => snapshot?.optionsPages.find((item) => item.key === selectedKey) ?? null, [snapshot, selectedKey]);
	(0, import_react.useEffect)(() => {
		setDraft(selected ? stripResolved$1(selected) : NEW_PAGE);
		setPreview(null);
		setConfirmed(false);
	}, [selected]);
	const run = async (fn, reload = true) => {
		setBusy(true);
		setError(null);
		try {
			await fn();
			if (reload) await load();
		} catch (e) {
			setError(e instanceof Error ? e.message : "Options operation failed");
		} finally {
			setBusy(false);
		}
	};
	const create = () => run(async () => {
		await postDefinitionAction({
			action: "createOptionsPage",
			definition: draft,
			operationId: operationId("admin:options:create")
		});
	});
	const update = () => run(async () => {
		if (!selected) throw new Error("Select an options page");
		const { key: _key, ...patch } = draft;
		await postDefinitionAction({
			action: "updateOptionsPage",
			key: selected.key,
			expectedVersion: selected.version,
			patch,
			operationId: operationId("admin:options:update")
		});
	});
	const previewDeactivate = () => run(async () => {
		if (!selected) throw new Error("Select an options page");
		setPreview(await postDefinitionAction({
			action: "previewOptionsDeactivate",
			key: selected.key,
			expectedVersion: selected.version,
			preparePurge: purge
		}));
		setConfirmed(false);
	}, false);
	const applyDeactivate = () => run(async () => {
		if (!preview || !selected) throw new Error("Preview deactivation first");
		await postDefinitionAction({
			action: "applyOptionsDeactivate",
			key: selected.key,
			impactToken: preview.impact.token,
			strategy: preview.strategy,
			operationId: operationId("admin:options:deactivate")
		});
		setPreview(null);
		setConfirmed(false);
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-6",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				title: "Options pages",
				description: "Manage global settings surfaces and their value retention policy.",
				actions: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					size: "sm",
					onClick: () => void load(),
					disabled: busy,
					children: "Refresh"
				})
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				role: "alert",
				className: "rounded-[2px] border border-danger p-4 text-sm text-danger",
				children: error
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "grid gap-4 xl:grid-cols-[18rem_1fr]",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
					className: "rounded-[2px] border border-border bg-surface p-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
						className: "text-sm font-medium text-fg",
						children: ["Options page", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
							value: selectedKey,
							onChange: (e) => setSelectedKey(e.currentTarget.value),
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: "",
								children: "New page…"
							}), snapshot?.optionsPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
								value: page.key,
								children: [
									page.title,
									" · ",
									page.key,
									" · ",
									page.origin,
									page.active ? "" : " · inactive"
								]
							}, page.key))]
						})]
					}), selected?.origin === "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
						className: "mt-4 text-sm text-warning",
						children: "Deploy-owned options page. Change the code registry instead of the database definition."
					}) : null]
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", {
					className: "flex min-w-0 flex-col gap-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(OptionsPageDefinitionEditor, {
						value: draft,
						onChange: (next) => {
							setDraft(next);
							setPreview(null);
						},
						availableParents: snapshot?.optionsPages.filter((page) => page.key !== selectedKey).map((page) => ({
							key: page.key,
							title: page.title
						})),
						disabled: selected?.origin === "code"
					}), selected && selected.origin !== "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "flex flex-wrap gap-4",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								onClick: () => void update(),
								disabled: busy,
								children: "Save definition"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "flex items-center gap-2 text-sm",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
									type: "checkbox",
									checked: purge,
									onChange: (e) => {
										setPurge(e.currentTarget.checked);
										setPreview(null);
									}
								}), " Purge stored values with immutable backup"]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
								tone: "surface",
								onClick: () => void previewDeactivate(),
								disabled: busy,
								children: "Preview deactivation"
							})
						]
					}), preview ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
						className: "rounded-[2px] border border-border bg-surface p-4",
						role: "status",
						"aria-live": "polite",
						children: [
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
								className: "font-medium text-fg",
								children: "Deactivation impact"
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", {
								className: "mt-2 grid gap-2 sm:grid-cols-2",
								children: Object.entries(preview.impact.affectedCounts).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
									className: "text-sm text-fg-muted",
									children: key
								}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", {
									className: "text-sm text-fg",
									children: value
								})] }, key))
							}),
							preview.backup ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
								className: "mt-4 text-sm text-fg-muted",
								children: "Immutable backup created for this exact purge scope."
							}) : null,
							/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "mt-4 flex items-center gap-2 text-sm",
								children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
									type: "checkbox",
									checked: confirmed,
									onChange: (e) => setConfirmed(e.currentTarget.checked)
								}), " I confirm deactivation and the selected value-retention policy."]
							}),
							/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
								className: "mt-4",
								children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
									tone: "danger",
									onClick: () => void applyDeactivate(),
									disabled: busy || !confirmed,
									children: "Deactivate options page"
								})
							})
						]
					}) : null] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						onClick: () => void create(),
						disabled: busy,
						children: "Create options page"
					})]
				})]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DefinitionBackupRecoveryPanel, {
				kind: "fields",
				backups: snapshot?.backups ?? [],
				onRestored: load
			})
		]
	});
}
//#endregion
//#region src/components/admin/blocks/BlocksAdminScreen.tsx
var NEW_BLOCK = Object.freeze({
	key: "custom_block",
	title: "Custom block",
	fieldGroupKeys: Object.freeze([]),
	mode: "preview",
	supports: Object.freeze({
		anchor: true,
		className: true,
		multiple: true,
		reusable: true,
		innerBlocks: false
	})
});
function stripResolved(block) {
	const { origin: _origin, version: _version, active: _active, shadowedDbVersion: _shadowed, ...definition } = block;
	return definition;
}
function BlocksAdminScreen() {
	const [snapshot, setSnapshot] = (0, import_react.useState)(null), [selectedKey, setSelectedKey] = (0, import_react.useState)(""), [draft, setDraft] = (0, import_react.useState)(NEW_BLOCK), [strategyKind, setStrategyKind] = (0, import_react.useState)("reject"), [replacementKey, setReplacementKey] = (0, import_react.useState)(""), [deactivate, setDeactivate] = (0, import_react.useState)(false), [deleteDefinition, setDeleteDefinition] = (0, import_react.useState)(false), [preview, setPreview] = (0, import_react.useState)(null), [confirmed, setConfirmed] = (0, import_react.useState)(false), [busy, setBusy] = (0, import_react.useState)(false), [error, setError] = (0, import_react.useState)(null);
	const load = async () => {
		setError(null);
		try {
			setSnapshot(await fetchDefinitionSnapshot());
		} catch (e) {
			setError(e instanceof Error ? e.message : "Failed to load blocks");
		}
	};
	(0, import_react.useEffect)(() => {
		load();
	}, []);
	const selected = (0, import_react.useMemo)(() => snapshot?.blocks.find((item) => item.key === selectedKey) ?? null, [snapshot, selectedKey]);
	(0, import_react.useEffect)(() => {
		setDraft(selected ? stripResolved(selected) : NEW_BLOCK);
		setPreview(null);
		setConfirmed(false);
	}, [selected]);
	const run = async (fn, reload = true) => {
		setBusy(true);
		setError(null);
		try {
			await fn();
			if (reload) await load();
		} catch (e) {
			setError(e instanceof Error ? e.message : "Block definition operation failed");
		} finally {
			setBusy(false);
		}
	};
	const strategy = () => strategyKind === "mapDefinition" ? {
		kind: "mapDefinition",
		replacementKey
	} : strategyKind === "purgeWithBackup" ? {
		kind: "purgeWithBackup",
		backupId: ""
	} : { kind: "reject" };
	const create = () => run(async () => {
		await postDefinitionAction({
			action: "createBlock",
			definition: draft,
			operationId: operationId("admin:block:create")
		});
	});
	const previewChange = () => run(async () => {
		if (!selected) throw new Error("Select a block");
		const { key: _key, ...patch } = draft;
		setPreview(await postDefinitionAction({
			action: "previewBlock",
			key: selected.key,
			expectedVersion: selected.version,
			patch,
			deactivate,
			delete: deleteDefinition,
			strategy: strategy()
		}));
		setConfirmed(false);
	}, false);
	const apply = () => run(async () => {
		if (!preview) throw new Error("Preview the block change first");
		await postDefinitionAction({
			action: "applyBlock",
			impactToken: preview.impact.token,
			strategy: preview.strategy,
			operationId: operationId("admin:block")
		});
		setPreview(null);
		setConfirmed(false);
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "flex flex-col gap-6",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
				title: "Blocks",
				description: "Manage native field blocks, structural compatibility, and recoverable destructive changes.",
				actions: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
					tone: "surface",
					size: "sm",
					onClick: () => void load(),
					disabled: busy,
					children: "Refresh"
				})
			}),
			error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				role: "alert",
				className: "rounded-[2px] border border-danger p-4 text-sm text-danger",
				children: error
			}) : null,
			/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "grid gap-4 xl:grid-cols-[18rem_1fr]",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
					className: "rounded-[2px] border border-border bg-surface p-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
						className: "text-sm font-medium text-fg",
						children: ["Block", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
							className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
							value: selectedKey,
							onChange: (e) => setSelectedKey(e.currentTarget.value),
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
								value: "",
								children: "New block…"
							}), snapshot?.blocks.map((block) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
								value: block.key,
								children: [
									block.title,
									" · ",
									block.key,
									" · ",
									block.origin,
									block.active ? "" : " · inactive"
								]
							}, block.key))]
						})]
					}), selected?.origin === "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
						className: "mt-4 text-sm text-warning",
						children: ["Deploy-owned block. Database mutations are disabled for this effective definition.", selected.shadowedDbVersion ? ` Database shadow version ${selected.shadowedDbVersion} is retained for diagnostics.` : ""]
					}) : null]
				}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", {
					className: "flex min-w-0 flex-col gap-4",
					children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldBlockDefinitionEditor, {
						value: draft,
						onChange: (next) => {
							setDraft(next);
							setPreview(null);
						},
						availableGroupKeys: snapshot?.fieldGroups.filter((group) => group.active).map((group) => group.key),
						availableBlockKeys: snapshot?.blocks.filter((block) => block.active && block.key !== selectedKey).map((block) => block.key),
						disabled: selected?.origin === "code"
					}), selected && selected.origin !== "code" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "grid gap-4 md:grid-cols-2",
							children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm text-fg",
								children: ["Compatibility strategy", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
									className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
									value: strategyKind,
									onChange: (e) => {
										setStrategyKind(e.currentTarget.value);
										setPreview(null);
									},
									children: [
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "reject",
											children: "Reject incompatible changes"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "mapDefinition",
											children: "Map documents to another block"
										}),
										/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
											value: "purgeWithBackup",
											children: "Purge affected documents with backup"
										})
									]
								})]
							}), strategyKind === "mapDefinition" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
								className: "text-sm text-fg",
								children: ["Replacement block", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
									className: "mt-2 w-full rounded-[2px] border border-border bg-canvas p-2",
									value: replacementKey,
									onChange: (e) => {
										setReplacementKey(e.currentTarget.value);
										setPreview(null);
									},
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: "",
										children: "Select replacement…"
									}), snapshot?.blocks.filter((block) => block.key !== selected.key && block.active).map((block) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
										value: block.key,
										children: block.title
									}, block.key))]
								})]
							}) : null]
						}),
						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "flex flex-wrap gap-4",
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
									className: "flex items-center gap-2 text-sm",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
										type: "checkbox",
										checked: deactivate,
										onChange: (e) => {
											setDeactivate(e.currentTarget.checked);
											setPreview(null);
										}
									}), " Deactivate block"]
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
									className: "flex items-center gap-2 text-sm",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
										type: "checkbox",
										checked: deleteDefinition,
										onChange: (e) => {
											setDeleteDefinition(e.currentTarget.checked);
											setPreview(null);
										}
									}), " Delete definition"]
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
									tone: "surface",
									onClick: () => void previewChange(),
									disabled: busy,
									children: "Preview impact"
								})
							]
						}),
						preview ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
							className: "rounded-[2px] border border-border bg-surface p-4",
							role: "status",
							"aria-live": "polite",
							children: [
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
									className: "font-medium text-fg",
									children: "Block impact"
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", {
									className: "mt-2 grid gap-2 sm:grid-cols-2",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
										className: "text-sm text-fg-muted",
										children: "Documents"
									}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: preview.impact.affectedDocuments })] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", {
										className: "text-sm text-fg-muted",
										children: "Definition versions"
									}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: preview.impact.affectedDefinitionVersions })] })]
								}),
								preview.impact.incompatibilities.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
									className: "mt-4 list-disc pl-6 text-sm text-danger",
									children: preview.impact.incompatibilities.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: item }, item))
								}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
									className: "mt-4 text-sm text-fg-muted",
									children: "No incompatibilities detected."
								}),
								preview.backup ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
									className: "mt-4 text-sm text-fg-muted",
									children: "Immutable backup created for this exact block-document corpus."
								}) : null,
								/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
									className: "mt-4 flex items-center gap-2 text-sm",
									children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
										type: "checkbox",
										checked: confirmed,
										onChange: (e) => setConfirmed(e.currentTarget.checked)
									}), " I reviewed the affected documents and confirm this block change."]
								}),
								/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
									className: "mt-4",
									children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
										tone: preview.strategy.kind === "purgeWithBackup" ? "danger" : "accent",
										onClick: () => void apply(),
										disabled: busy || !confirmed,
										children: "Apply reviewed change"
									})
								})
							]
						}) : null
					] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						onClick: () => void create(),
						disabled: busy,
						children: "Create block"
					})]
				})]
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DefinitionBackupRecoveryPanel, {
				kind: "fields",
				backups: snapshot?.backups ?? [],
				onRestored: load
			})
		]
	});
}
//#endregion
//#region src/components/admin/HeadlessScreen.tsx
function HeadlessScreen() {
	const [schema, setSchema] = (0, import_react.useState)(null), [error, setError] = (0, import_react.useState)("");
	(0, import_react.useEffect)(() => {
		let cancelled = false;
		fetch("/api/headless/schema", { credentials: "same-origin" }).then(async (response) => {
			const body = await response.json().catch(() => null);
			if (!response.ok) throw new Error(body?.error?.message ?? response.statusText);
			if (!cancelled) setSchema(body);
		}).catch((reason) => {
			if (!cancelled) setError(reason instanceof Error ? reason.message : "Headless schema could not be loaded.");
		});
		return () => {
			cancelled = true;
		};
	}, []);
	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
		"aria-labelledby": "headless-heading",
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScreenHeader, {
			headingId: "headless-heading",
			title: "Headless operations",
			description: "Discover the exact generated operations enabled by each resolved content type and the linked fields schema version."
		}), error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
			className: "admin-form__error",
			role: "alert",
			children: error
		}) : schema ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
			className: "flex flex-col gap-4",
			children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
				className: "text-sm text-fg-muted",
				children: [
					"Combined schema ",
					schema.version,
					" · content ",
					schema.content.version,
					" · fields ",
					schema.fields.version
				]
			}), schema.content.operations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "No headless operations are enabled." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table, {
				caption: "Headless operation discovery",
				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Head, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Content type"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Operation"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {
						scope: "col",
						children: "Capability"
					})
				] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Body, { children: schema.content.operations.map((operation) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Row, { children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: operation.typeKey }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: operation.key }),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: operation.capability })
				] }, `${operation.typeKey}:${operation.key}`)) })]
			})]
		}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
			className: "text-sm text-fg-muted",
			children: "Loading headless schema…"
		})]
	});
}
//#endregion
//#region src/components/admin/AdminApp.tsx
function renderScreen(props) {
	switch (props.screen) {
		case "editor": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorScreen, { entry: props.entry });
		case "settings": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SettingsScreen, {});
		case "maintenance": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MaintenanceScreen, {});
		case "privacy": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PrivacyConsentScreen, {});
		case "audit": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuditViewerScreen, {});
		case "health": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HealthScreen, {});
		case "calendar": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CalendarScreen, {});
		case "backup": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BackupRestoreScreen, {});
		case "trash": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TrashScreen, {});
		case "comments": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommentsScreen, {});
		case "submissions": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SubmissionsScreen, {});
		case "notifications": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NotificationsScreen, {});
		case "users": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UsersScreen, {});
		case "field-groups": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GroupEditorScreen, {});
		case "content-types": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContentTypesAdminScreen, {});
		case "fields": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldsAdminScreen, {});
		case "options": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OptionsAdminScreen, {});
		case "blocks": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlocksAdminScreen, {});
		case "headless": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HeadlessScreen, {});
		case "menus": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenuEditorScreen, {});
		case "list": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContentListScreen, {});
	}
}
function AdminShell({ children }) {
	const { user, loading } = useCurrentUser();
	const { signOut, pending } = useSignOut();
	const [pathname, setPathname] = (0, import_react.useState)("");
	const notificationClient = (0, import_react.useMemo)(() => makeNotificationClient(), []);
	(0, import_react.useEffect)(() => {
		setPathname(window.location.pathname);
	}, []);
	if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		className: "admin-root admin-grid admin-screen",
		"aria-hidden": "true",
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
			className: "admin-grid__main flex flex-col gap-4",
			children: [
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "heading" }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "text" }),
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Skeleton, { variant: "block" })
			]
		})
	});
	if (user == null || !user.roles.includes("admin")) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		className: "admin-root",
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoginScreen, {})
	});
	const sidebar = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
		className: "admin-nav",
		children: [
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "admin-nav__brand",
				children: "mod-cms"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin",
				"aria-current": pathname === "/admin" ? "page" : void 0,
				children: "Content"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/calendar",
				"aria-current": pathname === "/admin/calendar" ? "page" : void 0,
				children: "Calendar"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/comments",
				"aria-current": pathname === "/admin/comments" ? "page" : void 0,
				children: "Comments"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/submissions",
				"aria-current": pathname === "/admin/submissions" ? "page" : void 0,
				children: "Submissions"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/notifications",
				"aria-current": pathname === "/admin/notifications" ? "page" : void 0,
				children: "Notifications"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/trash",
				"aria-current": pathname === "/admin/trash" ? "page" : void 0,
				children: "Trash"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/media",
				"aria-current": pathname === "/admin/media" ? "page" : void 0,
				children: "Media"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/users",
				"aria-current": pathname === "/admin/users" ? "page" : void 0,
				children: "Users"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/content-types",
				"aria-current": pathname.startsWith("/admin/content-types") ? "page" : void 0,
				children: "Content types"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/fields",
				"aria-current": pathname.startsWith("/admin/fields") ? "page" : void 0,
				children: "Fields"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/options",
				"aria-current": pathname.startsWith("/admin/options") ? "page" : void 0,
				children: "Options pages"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/blocks",
				"aria-current": pathname.startsWith("/admin/blocks") ? "page" : void 0,
				children: "Blocks"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/field-groups",
				"aria-current": pathname === "/admin/field-groups" ? "page" : void 0,
				children: "Legacy field groups"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/menus",
				"aria-current": pathname === "/admin/menus" ? "page" : void 0,
				children: "Menus"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/settings",
				"aria-current": pathname === "/admin/settings" ? "page" : void 0,
				children: "Settings"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/maintenance",
				"aria-current": pathname === "/admin/maintenance" ? "page" : void 0,
				children: "Maintenance"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/privacy",
				"aria-current": pathname === "/admin/privacy" ? "page" : void 0,
				children: "Privacy"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/audit",
				"aria-current": pathname === "/admin/audit" ? "page" : void 0,
				children: "Audit"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/health",
				"aria-current": pathname === "/admin/health" ? "page" : void 0,
				children: "Health"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/backup",
				"aria-current": pathname === "/admin/backup" ? "page" : void 0,
				children: "Export / import"
			}),
			/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
				className: "admin-nav__link",
				href: "/admin/headless",
				"aria-current": pathname === "/admin/headless" ? "page" : void 0,
				children: "Headless operations"
			})
		]
	});
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
		className: "admin-root",
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DashboardShell, {
			sidebar,
			topbar: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
				className: "admin-topbar",
				children: [
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(NotificationBell, {
						client: notificationClient,
						onOpen: () => {
							window.location.href = "/admin/notifications";
						}
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
						className: "admin-topbar__user",
						children: "Signed in as admin"
					}),
					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
						tone: "surface",
						radius: "sm",
						size: "sm",
						type: "button",
						disabled: pending,
						onClick: () => void signOut(),
						children: "Sign out"
					})
				]
			}),
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
				className: "admin-screen admin-grid",
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
					className: "admin-grid__main",
					children
				})
			})
		})
	});
}
function AdminApp(props) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthProvider, {
		client: makeAuthClient(),
		children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AdminShell, { children: renderScreen(props) }) })
	});
}
//#endregion
export { AdminApp as t };
