+ *
+ *
+ */
+(function(n, e) {
+ (function(t, o) {
+ n.exports = o();
+ })(window, function() {
+ return function(t) {
+ var o = {};
+ function i(s) {
+ if (o[s])
+ return o[s].exports;
+ var r = o[s] = { i: s, l: !1, exports: {} };
+ return t[s].call(r.exports, r, r.exports, i), r.l = !0, r.exports;
+ }
+ return i.m = t, i.c = o, i.d = function(s, r, a) {
+ i.o(s, r) || Object.defineProperty(s, r, { enumerable: !0, get: a });
+ }, i.r = function(s) {
+ typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(s, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(s, "__esModule", { value: !0 });
+ }, i.t = function(s, r) {
+ if (1 & r && (s = i(s)), 8 & r || 4 & r && typeof s == "object" && s && s.__esModule)
+ return s;
+ var a = /* @__PURE__ */ Object.create(null);
+ if (i.r(a), Object.defineProperty(a, "default", { enumerable: !0, value: s }), 2 & r && typeof s != "string")
+ for (var l in s)
+ i.d(a, l, (function(c) {
+ return s[c];
+ }).bind(null, l));
+ return a;
+ }, i.n = function(s) {
+ var r = s && s.__esModule ? function() {
+ return s.default;
+ } : function() {
+ return s;
+ };
+ return i.d(r, "a", r), r;
+ }, i.o = function(s, r) {
+ return Object.prototype.hasOwnProperty.call(s, r);
+ }, i.p = "", i(i.s = 0);
+ }([function(t, o, i) {
+ t.exports = i(1);
+ }, function(t, o, i) {
+ i.r(o), i.d(o, "default", function() {
+ return s;
+ });
+ class s {
+ constructor() {
+ this.nodes = { wrapper: null, content: null }, this.showed = !1, this.offsetTop = 10, this.offsetLeft = 10, this.offsetRight = 10, this.hidingDelay = 0, this.handleWindowScroll = () => {
+ this.showed && this.hide(!0);
+ }, this.loadStyles(), this.prepare(), window.addEventListener("scroll", this.handleWindowScroll, { passive: !0 });
+ }
+ get CSS() {
+ return { tooltip: "ct", tooltipContent: "ct__content", tooltipShown: "ct--shown", placement: { left: "ct--left", bottom: "ct--bottom", right: "ct--right", top: "ct--top" } };
+ }
+ show(a, l, c) {
+ this.nodes.wrapper || this.prepare(), this.hidingTimeout && clearTimeout(this.hidingTimeout);
+ const u = Object.assign({ placement: "bottom", marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0, delay: 70, hidingDelay: 0 }, c);
+ if (u.hidingDelay && (this.hidingDelay = u.hidingDelay), this.nodes.content.innerHTML = "", typeof l == "string")
+ this.nodes.content.appendChild(document.createTextNode(l));
+ else {
+ if (!(l instanceof Node))
+ throw Error("[CodeX Tooltip] Wrong type of «content» passed. It should be an instance of Node or String. But " + typeof l + " given.");
+ this.nodes.content.appendChild(l);
+ }
+ switch (this.nodes.wrapper.classList.remove(...Object.values(this.CSS.placement)), u.placement) {
+ case "top":
+ this.placeTop(a, u);
+ break;
+ case "left":
+ this.placeLeft(a, u);
+ break;
+ case "right":
+ this.placeRight(a, u);
+ break;
+ case "bottom":
+ default:
+ this.placeBottom(a, u);
+ }
+ u && u.delay ? this.showingTimeout = setTimeout(() => {
+ this.nodes.wrapper.classList.add(this.CSS.tooltipShown), this.showed = !0;
+ }, u.delay) : (this.nodes.wrapper.classList.add(this.CSS.tooltipShown), this.showed = !0);
+ }
+ hide(a = !1) {
+ if (this.hidingDelay && !a)
+ return this.hidingTimeout && clearTimeout(this.hidingTimeout), void (this.hidingTimeout = setTimeout(() => {
+ this.hide(!0);
+ }, this.hidingDelay));
+ this.nodes.wrapper.classList.remove(this.CSS.tooltipShown), this.showed = !1, this.showingTimeout && clearTimeout(this.showingTimeout);
+ }
+ onHover(a, l, c) {
+ a.addEventListener("mouseenter", () => {
+ this.show(a, l, c);
+ }), a.addEventListener("mouseleave", () => {
+ this.hide();
+ });
+ }
+ destroy() {
+ this.nodes.wrapper.remove(), window.removeEventListener("scroll", this.handleWindowScroll);
+ }
+ prepare() {
+ this.nodes.wrapper = this.make("div", this.CSS.tooltip), this.nodes.content = this.make("div", this.CSS.tooltipContent), this.append(this.nodes.wrapper, this.nodes.content), this.append(document.body, this.nodes.wrapper);
+ }
+ loadStyles() {
+ const a = "codex-tooltips-style";
+ if (document.getElementById(a))
+ return;
+ const l = i(2), c = this.make("style", null, { textContent: l.toString(), id: a });
+ this.prepend(document.head, c);
+ }
+ placeBottom(a, l) {
+ const c = a.getBoundingClientRect(), u = c.left + a.clientWidth / 2 - this.nodes.wrapper.offsetWidth / 2, h = c.bottom + window.pageYOffset + this.offsetTop + l.marginTop;
+ this.applyPlacement("bottom", u, h);
+ }
+ placeTop(a, l) {
+ const c = a.getBoundingClientRect(), u = c.left + a.clientWidth / 2 - this.nodes.wrapper.offsetWidth / 2, h = c.top + window.pageYOffset - this.nodes.wrapper.clientHeight - this.offsetTop;
+ this.applyPlacement("top", u, h);
+ }
+ placeLeft(a, l) {
+ const c = a.getBoundingClientRect(), u = c.left - this.nodes.wrapper.offsetWidth - this.offsetLeft - l.marginLeft, h = c.top + window.pageYOffset + a.clientHeight / 2 - this.nodes.wrapper.offsetHeight / 2;
+ this.applyPlacement("left", u, h);
+ }
+ placeRight(a, l) {
+ const c = a.getBoundingClientRect(), u = c.right + this.offsetRight + l.marginRight, h = c.top + window.pageYOffset + a.clientHeight / 2 - this.nodes.wrapper.offsetHeight / 2;
+ this.applyPlacement("right", u, h);
+ }
+ applyPlacement(a, l, c) {
+ this.nodes.wrapper.classList.add(this.CSS.placement[a]), this.nodes.wrapper.style.left = l + "px", this.nodes.wrapper.style.top = c + "px";
+ }
+ make(a, l = null, c = {}) {
+ const u = document.createElement(a);
+ Array.isArray(l) ? u.classList.add(...l) : l && u.classList.add(l);
+ for (const h in c)
+ c.hasOwnProperty(h) && (u[h] = c[h]);
+ return u;
+ }
+ append(a, l) {
+ Array.isArray(l) ? l.forEach((c) => a.appendChild(c)) : a.appendChild(l);
+ }
+ prepend(a, l) {
+ Array.isArray(l) ? (l = l.reverse()).forEach((c) => a.prepend(c)) : a.prepend(l);
+ }
+ }
+ }, function(t, o) {
+ t.exports = `.ct{z-index:999;opacity:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;-webkit-transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1),-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);will-change:opacity,top,left;-webkit-box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);border-radius:9px}.ct,.ct:before{position:absolute;top:0;left:0}.ct:before{content:"";bottom:0;right:0;background-color:#1d202b;z-index:-1;border-radius:4px}@supports(-webkit-mask-box-image:url("")){.ct:before{border-radius:0;-webkit-mask-box-image:url('data:image/svg+xml;charset=utf-8,') 48% 41% 37.9% 53.3%}}@media (--mobile){.ct{display:none}}.ct__content{padding:6px 10px;color:#cdd1e0;font-size:12px;text-align:center;letter-spacing:.02em;line-height:1em}.ct:after{content:"";width:8px;height:8px;position:absolute;background-color:#1d202b;z-index:-1}.ct--bottom{-webkit-transform:translateY(5px);transform:translateY(5px)}.ct--bottom:after{top:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--top{-webkit-transform:translateY(-5px);transform:translateY(-5px)}.ct--top:after{top:auto;bottom:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--left{-webkit-transform:translateX(-5px);transform:translateX(-5px)}.ct--left:after{top:50%;left:auto;right:0;-webkit-transform:translate(41.6%,-50%) rotate(-45deg);transform:translate(41.6%,-50%) rotate(-45deg)}.ct--right{-webkit-transform:translateX(5px);transform:translateX(5px)}.ct--right:after{top:50%;left:0;-webkit-transform:translate(-41.6%,-50%) rotate(-45deg);transform:translate(-41.6%,-50%) rotate(-45deg)}.ct--shown{opacity:1;-webkit-transform:none;transform:none}`;
+ }]).default;
+ });
+})(Vo);
+var ji = Vo.exports;
+const Hi = /* @__PURE__ */ Ke(ji);
+let U = null;
+function Et() {
+ U || (U = new Hi());
+}
+function $i(n, e, t) {
+ Et(), U == null || U.show(n, e, t);
+}
+function $e(n = !1) {
+ Et(), U == null || U.hide(n);
+}
+function ze(n, e, t) {
+ Et(), U == null || U.onHover(n, e, t);
+}
+function zi() {
+ U == null || U.destroy(), U = null;
+}
+class Ui extends E {
+ /**
+ * @class
+ * @param moduleConfiguration - Module Configuration
+ * @param moduleConfiguration.config - Editor's config
+ * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher
+ */
+ constructor({ config: e, eventsDispatcher: t }) {
+ super({
+ config: e,
+ eventsDispatcher: t
+ });
+ }
+ /**
+ * Available methods
+ */
+ get methods() {
+ return {
+ show: (e, t, o) => this.show(e, t, o),
+ hide: () => this.hide(),
+ onHover: (e, t, o) => this.onHover(e, t, o)
+ };
+ }
+ /**
+ * Method show tooltip on element with passed HTML content
+ *
+ * @param {HTMLElement} element - element on which tooltip should be shown
+ * @param {TooltipContent} content - tooltip content
+ * @param {TooltipOptions} options - tooltip options
+ */
+ show(e, t, o) {
+ $i(e, t, o);
+ }
+ /**
+ * Method hides tooltip on HTML page
+ */
+ hide() {
+ $e();
+ }
+ /**
+ * Decorator for showing Tooltip by mouseenter/mouseleave
+ *
+ * @param {HTMLElement} element - element on which tooltip should be shown
+ * @param {TooltipContent} content - tooltip content
+ * @param {TooltipOptions} options - tooltip options
+ */
+ onHover(e, t, o) {
+ ze(e, t, o);
+ }
+}
+class Wi extends E {
+ /**
+ * Available methods / getters
+ */
+ get methods() {
+ return {
+ nodes: this.editorNodes
+ /**
+ * There can be added some UI methods, like toggleThinMode() etc
+ */
+ };
+ }
+ /**
+ * Exported classes
+ */
+ get editorNodes() {
+ return {
+ /**
+ * Top-level editor instance wrapper
+ */
+ wrapper: this.Editor.UI.nodes.wrapper,
+ /**
+ * Element that holds all the Blocks
+ */
+ redactor: this.Editor.UI.nodes.redactor
+ };
+ }
+}
+function qo(n, e) {
+ const t = {};
+ return Object.entries(n).forEach(([o, i]) => {
+ if (D(i)) {
+ const s = e ? `${e}.${o}` : o;
+ Object.values(i).every((a) => te(a)) ? t[o] = s : t[o] = qo(i, s);
+ return;
+ }
+ t[o] = i;
+ }), t;
+}
+const K = qo(Fo);
+function Yi(n, e) {
+ const t = {};
+ return Object.keys(n).forEach((o) => {
+ const i = e[o];
+ i !== void 0 ? t[i] = n[o] : t[o] = n[o];
+ }), t;
+}
+const Zo = class Ee {
+ /**
+ * @param {HTMLElement[]} nodeList — the list of iterable HTML-items
+ * @param {string} focusedCssClass - user-provided CSS-class that will be set in flipping process
+ */
+ constructor(e, t) {
+ this.cursor = -1, this.items = [], this.items = e || [], this.focusedCssClass = t;
+ }
+ /**
+ * Returns Focused button Node
+ *
+ * @returns {HTMLElement}
+ */
+ get currentItem() {
+ return this.cursor === -1 ? null : this.items[this.cursor];
+ }
+ /**
+ * Sets cursor to specified position
+ *
+ * @param cursorPosition - new cursor position
+ */
+ setCursor(e) {
+ e < this.items.length && e >= -1 && (this.dropCursor(), this.cursor = e, this.items[this.cursor].classList.add(this.focusedCssClass));
+ }
+ /**
+ * Sets items. Can be used when iterable items changed dynamically
+ *
+ * @param {HTMLElement[]} nodeList - nodes to iterate
+ */
+ setItems(e) {
+ this.items = e;
+ }
+ /**
+ * Sets cursor next to the current
+ */
+ next() {
+ this.cursor = this.leafNodesAndReturnIndex(Ee.directions.RIGHT);
+ }
+ /**
+ * Sets cursor before current
+ */
+ previous() {
+ this.cursor = this.leafNodesAndReturnIndex(Ee.directions.LEFT);
+ }
+ /**
+ * Sets cursor to the default position and removes CSS-class from previously focused item
+ */
+ dropCursor() {
+ this.cursor !== -1 && (this.items[this.cursor].classList.remove(this.focusedCssClass), this.cursor = -1);
+ }
+ /**
+ * Leafs nodes inside the target list from active element
+ *
+ * @param {string} direction - leaf direction. Can be 'left' or 'right'
+ * @returns {number} index of focused node
+ */
+ leafNodesAndReturnIndex(e) {
+ if (this.items.length === 0)
+ return this.cursor;
+ let t = this.cursor;
+ return t === -1 ? t = e === Ee.directions.RIGHT ? -1 : 0 : this.items[t].classList.remove(this.focusedCssClass), e === Ee.directions.RIGHT ? t = (t + 1) % this.items.length : t = (this.items.length + t - 1) % this.items.length, d.canSetCaret(this.items[t]) && Fe(() => b.setCursor(this.items[t]), 50)(), this.items[t].classList.add(this.focusedCssClass), t;
+ }
+};
+Zo.directions = {
+ RIGHT: "right",
+ LEFT: "left"
+};
+let ke = Zo;
+class ce {
+ /**
+ * @param options - different constructing settings
+ */
+ constructor(e) {
+ this.iterator = null, this.activated = !1, this.flipCallbacks = [], this.onKeyDown = (t) => {
+ if (this.isEventReadyForHandling(t))
+ switch (ce.usedKeys.includes(t.keyCode) && t.preventDefault(), t.keyCode) {
+ case y.TAB:
+ this.handleTabPress(t);
+ break;
+ case y.LEFT:
+ case y.UP:
+ this.flipLeft();
+ break;
+ case y.RIGHT:
+ case y.DOWN:
+ this.flipRight();
+ break;
+ case y.ENTER:
+ this.handleEnterPress(t);
+ break;
+ }
+ }, this.iterator = new ke(e.items, e.focusedItemClass), this.activateCallback = e.activateCallback, this.allowedKeys = e.allowedKeys || ce.usedKeys;
+ }
+ /**
+ * True if flipper is currently activated
+ */
+ get isActivated() {
+ return this.activated;
+ }
+ /**
+ * Array of keys (codes) that is handled by Flipper
+ * Used to:
+ * - preventDefault only for this keys, not all keydowns (@see constructor)
+ * - to skip external behaviours only for these keys, when filler is activated (@see BlockEvents@arrowRightAndDown)
+ */
+ static get usedKeys() {
+ return [
+ y.TAB,
+ y.LEFT,
+ y.RIGHT,
+ y.ENTER,
+ y.UP,
+ y.DOWN
+ ];
+ }
+ /**
+ * Active tab/arrows handling by flipper
+ *
+ * @param items - Some modules (like, InlineToolbar, BlockSettings) might refresh buttons dynamically
+ * @param cursorPosition - index of the item that should be focused once flipper is activated
+ */
+ activate(e, t) {
+ this.activated = !0, e && this.iterator.setItems(e), t !== void 0 && this.iterator.setCursor(t), document.addEventListener("keydown", this.onKeyDown, !0);
+ }
+ /**
+ * Disable tab/arrows handling by flipper
+ */
+ deactivate() {
+ this.activated = !1, this.dropCursor(), document.removeEventListener("keydown", this.onKeyDown);
+ }
+ /**
+ * Focus first item
+ */
+ focusFirst() {
+ this.dropCursor(), this.flipRight();
+ }
+ /**
+ * Focuses previous flipper iterator item
+ */
+ flipLeft() {
+ this.iterator.previous(), this.flipCallback();
+ }
+ /**
+ * Focuses next flipper iterator item
+ */
+ flipRight() {
+ this.iterator.next(), this.flipCallback();
+ }
+ /**
+ * Return true if some button is focused
+ */
+ hasFocus() {
+ return !!this.iterator.currentItem;
+ }
+ /**
+ * Registeres function that should be executed on each navigation action
+ *
+ * @param cb - function to execute
+ */
+ onFlip(e) {
+ this.flipCallbacks.push(e);
+ }
+ /**
+ * Unregisteres function that is executed on each navigation action
+ *
+ * @param cb - function to stop executing
+ */
+ removeOnFlip(e) {
+ this.flipCallbacks = this.flipCallbacks.filter((t) => t !== e);
+ }
+ /**
+ * Drops flipper's iterator cursor
+ *
+ * @see DomIterator#dropCursor
+ */
+ dropCursor() {
+ this.iterator.dropCursor();
+ }
+ /**
+ * This function is fired before handling flipper keycodes
+ * The result of this function defines if it is need to be handled or not
+ *
+ * @param {KeyboardEvent} event - keydown keyboard event
+ * @returns {boolean}
+ */
+ isEventReadyForHandling(e) {
+ return this.activated && this.allowedKeys.includes(e.keyCode);
+ }
+ /**
+ * When flipper is activated tab press will leaf the items
+ *
+ * @param {KeyboardEvent} event - tab keydown event
+ */
+ handleTabPress(e) {
+ switch (e.shiftKey ? ke.directions.LEFT : ke.directions.RIGHT) {
+ case ke.directions.RIGHT:
+ this.flipRight();
+ break;
+ case ke.directions.LEFT:
+ this.flipLeft();
+ break;
+ }
+ }
+ /**
+ * Enter press will click current item if flipper is activated
+ *
+ * @param {KeyboardEvent} event - enter keydown event
+ */
+ handleEnterPress(e) {
+ this.activated && (this.iterator.currentItem && (e.stopPropagation(), e.preventDefault(), this.iterator.currentItem.click()), A(this.activateCallback) && this.activateCallback(this.iterator.currentItem));
+ }
+ /**
+ * Fired after flipping in any direction
+ */
+ flipCallback() {
+ this.iterator.currentItem && this.iterator.currentItem.scrollIntoViewIfNeeded(), this.flipCallbacks.forEach((e) => e());
+ }
+}
+const Ki = '', Xi = '', Vi = '', qi = '', Zi = '', Gi = '', Qi = '', Ji = '', Co = '', es = '', ts = '', Go = '', os = '', ns = '', is = '', ss = "__", rs = "--";
+function ne(n) {
+ return (e, t) => [[n, e].filter((i) => !!i).join(ss), t].filter((i) => !!i).join(rs);
+}
+const ye = ne("ce-hint"), we = {
+ root: ye(),
+ alignedStart: ye(null, "align-left"),
+ alignedCenter: ye(null, "align-center"),
+ title: ye("title"),
+ description: ye("description")
+};
+class as {
+ /**
+ * Constructs the hint content instance
+ *
+ * @param params - hint content parameters
+ */
+ constructor(e) {
+ this.nodes = {
+ root: d.make("div", [we.root, e.alignment === "center" ? we.alignedCenter : we.alignedStart]),
+ title: d.make("div", we.title, { textContent: e.title })
+ }, this.nodes.root.appendChild(this.nodes.title), e.description !== void 0 && (this.nodes.description = d.make("div", we.description, { textContent: e.description }), this.nodes.root.appendChild(this.nodes.description));
+ }
+ /**
+ * Returns the root element of the hint content
+ */
+ getElement() {
+ return this.nodes.root;
+ }
+}
+class xt {
+ /**
+ * Constructs the instance
+ *
+ * @param params - instance parameters
+ */
+ constructor(e) {
+ this.params = e;
+ }
+ /**
+ * Item name if exists
+ */
+ get name() {
+ if (this.params !== void 0 && "name" in this.params)
+ return this.params.name;
+ }
+ /**
+ * Destroys the instance
+ */
+ destroy() {
+ $e();
+ }
+ /**
+ * Called when children popover is opened (if exists)
+ */
+ onChildrenOpen() {
+ var e;
+ this.params !== void 0 && "children" in this.params && typeof ((e = this.params.children) == null ? void 0 : e.onOpen) == "function" && this.params.children.onOpen();
+ }
+ /**
+ * Called when children popover is closed (if exists)
+ */
+ onChildrenClose() {
+ var e;
+ this.params !== void 0 && "children" in this.params && typeof ((e = this.params.children) == null ? void 0 : e.onClose) == "function" && this.params.children.onClose();
+ }
+ /**
+ * Called on popover item click
+ */
+ handleClick() {
+ var e, t;
+ this.params !== void 0 && "onActivate" in this.params && ((t = (e = this.params).onActivate) == null || t.call(e, this.params));
+ }
+ /**
+ * Adds hint to the item element if hint data is provided
+ *
+ * @param itemElement - popover item root element to add hint to
+ * @param hintData - hint data
+ */
+ addHint(e, t) {
+ const o = new as(t);
+ ze(e, o.getElement(), {
+ placement: t.position,
+ hidingDelay: 100
+ });
+ }
+ /**
+ * Returns item children that are represented as popover items
+ */
+ get children() {
+ var e;
+ return this.params !== void 0 && "children" in this.params && ((e = this.params.children) == null ? void 0 : e.items) !== void 0 ? this.params.children.items : [];
+ }
+ /**
+ * Returns true if item has any type of children
+ */
+ get hasChildren() {
+ return this.children.length > 0;
+ }
+ /**
+ * Returns true if item children should be open instantly after popover is opened and not on item click/hover
+ */
+ get isChildrenOpen() {
+ var e;
+ return this.params !== void 0 && "children" in this.params && ((e = this.params.children) == null ? void 0 : e.isOpen) === !0;
+ }
+ /**
+ * True if item children items should be navigatable via keyboard
+ */
+ get isChildrenFlippable() {
+ var e;
+ return !(this.params === void 0 || !("children" in this.params) || ((e = this.params.children) == null ? void 0 : e.isFlippable) === !1);
+ }
+ /**
+ * Returns true if item has children that should be searchable
+ */
+ get isChildrenSearchable() {
+ var e;
+ return this.params !== void 0 && "children" in this.params && ((e = this.params.children) == null ? void 0 : e.searchable) === !0;
+ }
+ /**
+ * True if popover should close once item is activated
+ */
+ get closeOnActivate() {
+ return this.params !== void 0 && "closeOnActivate" in this.params && this.params.closeOnActivate;
+ }
+ /**
+ * True if item is active
+ */
+ get isActive() {
+ return this.params === void 0 || !("isActive" in this.params) ? !1 : typeof this.params.isActive == "function" ? this.params.isActive() : this.params.isActive === !0;
+ }
+}
+const Y = ne("ce-popover-item"), L = {
+ container: Y(),
+ active: Y(null, "active"),
+ disabled: Y(null, "disabled"),
+ focused: Y(null, "focused"),
+ hidden: Y(null, "hidden"),
+ confirmationState: Y(null, "confirmation"),
+ noHover: Y(null, "no-hover"),
+ noFocus: Y(null, "no-focus"),
+ title: Y("title"),
+ secondaryTitle: Y("secondary-title"),
+ icon: Y("icon"),
+ iconTool: Y("icon", "tool"),
+ iconChevronRight: Y("icon", "chevron-right"),
+ wobbleAnimation: ne("wobble")()
+};
+class re extends xt {
+ /**
+ * Constructs popover item instance
+ *
+ * @param params - popover item construction params
+ * @param renderParams - popover item render params.
+ * The parameters that are not set by user via popover api but rather depend on technical implementation
+ */
+ constructor(e, t) {
+ super(e), this.params = e, this.nodes = {
+ root: null,
+ icon: null
+ }, this.confirmationState = null, this.removeSpecialFocusBehavior = () => {
+ var o;
+ (o = this.nodes.root) == null || o.classList.remove(L.noFocus);
+ }, this.removeSpecialHoverBehavior = () => {
+ var o;
+ (o = this.nodes.root) == null || o.classList.remove(L.noHover);
+ }, this.onErrorAnimationEnd = () => {
+ var o, i;
+ (o = this.nodes.icon) == null || o.classList.remove(L.wobbleAnimation), (i = this.nodes.icon) == null || i.removeEventListener("animationend", this.onErrorAnimationEnd);
+ }, this.nodes.root = this.make(e, t);
+ }
+ /**
+ * True if item is disabled and hence not clickable
+ */
+ get isDisabled() {
+ return this.params.isDisabled === !0;
+ }
+ /**
+ * Exposes popover item toggle parameter
+ */
+ get toggle() {
+ return this.params.toggle;
+ }
+ /**
+ * Item title
+ */
+ get title() {
+ return this.params.title;
+ }
+ /**
+ * True if confirmation state is enabled for popover item
+ */
+ get isConfirmationStateEnabled() {
+ return this.confirmationState !== null;
+ }
+ /**
+ * True if item is focused in keyboard navigation process
+ */
+ get isFocused() {
+ return this.nodes.root === null ? !1 : this.nodes.root.classList.contains(L.focused);
+ }
+ /**
+ * Returns popover item root element
+ */
+ getElement() {
+ return this.nodes.root;
+ }
+ /**
+ * Called on popover item click
+ */
+ handleClick() {
+ if (this.isConfirmationStateEnabled && this.confirmationState !== null) {
+ this.activateOrEnableConfirmationMode(this.confirmationState);
+ return;
+ }
+ this.activateOrEnableConfirmationMode(this.params);
+ }
+ /**
+ * Toggles item active state
+ *
+ * @param isActive - true if item should strictly should become active
+ */
+ toggleActive(e) {
+ var t;
+ (t = this.nodes.root) == null || t.classList.toggle(L.active, e);
+ }
+ /**
+ * Toggles item hidden state
+ *
+ * @param isHidden - true if item should be hidden
+ */
+ toggleHidden(e) {
+ var t;
+ (t = this.nodes.root) == null || t.classList.toggle(L.hidden, e);
+ }
+ /**
+ * Resets popover item to its original state
+ */
+ reset() {
+ this.isConfirmationStateEnabled && this.disableConfirmationMode();
+ }
+ /**
+ * Method called once item becomes focused during keyboard navigation
+ */
+ onFocus() {
+ this.disableSpecialHoverAndFocusBehavior();
+ }
+ /**
+ * Constructs HTML element corresponding to popover item params
+ *
+ * @param params - item construction params
+ * @param renderParams - popover item render params
+ */
+ make(e, t) {
+ var s, r;
+ const o = (t == null ? void 0 : t.wrapperTag) || "div", i = d.make(o, L.container, {
+ type: o === "button" ? "button" : void 0
+ });
+ return e.name && (i.dataset.itemName = e.name), this.nodes.icon = d.make("div", [L.icon, L.iconTool], {
+ innerHTML: e.icon || Qi
+ }), i.appendChild(this.nodes.icon), e.title !== void 0 && i.appendChild(d.make("div", L.title, {
+ innerHTML: e.title || ""
+ })), e.secondaryLabel && i.appendChild(d.make("div", L.secondaryTitle, {
+ textContent: e.secondaryLabel
+ })), this.hasChildren && i.appendChild(d.make("div", [L.icon, L.iconChevronRight], {
+ innerHTML: qi
+ })), this.isActive && i.classList.add(L.active), e.isDisabled && i.classList.add(L.disabled), e.hint !== void 0 && ((s = t == null ? void 0 : t.hint) == null ? void 0 : s.enabled) !== !1 && this.addHint(i, {
+ ...e.hint,
+ position: ((r = t == null ? void 0 : t.hint) == null ? void 0 : r.position) || "right"
+ }), i;
+ }
+ /**
+ * Activates confirmation mode for the item.
+ *
+ * @param newState - new popover item params that should be applied
+ */
+ enableConfirmationMode(e) {
+ if (this.nodes.root === null)
+ return;
+ const t = {
+ ...this.params,
+ ...e,
+ confirmation: "confirmation" in e ? e.confirmation : void 0
+ }, o = this.make(t);
+ this.nodes.root.innerHTML = o.innerHTML, this.nodes.root.classList.add(L.confirmationState), this.confirmationState = e, this.enableSpecialHoverAndFocusBehavior();
+ }
+ /**
+ * Returns item to its original state
+ */
+ disableConfirmationMode() {
+ if (this.nodes.root === null)
+ return;
+ const e = this.make(this.params);
+ this.nodes.root.innerHTML = e.innerHTML, this.nodes.root.classList.remove(L.confirmationState), this.confirmationState = null, this.disableSpecialHoverAndFocusBehavior();
+ }
+ /**
+ * Enables special focus and hover behavior for item in confirmation state.
+ * This is needed to prevent item from being highlighted as hovered/focused just after click.
+ */
+ enableSpecialHoverAndFocusBehavior() {
+ var e, t, o;
+ (e = this.nodes.root) == null || e.classList.add(L.noHover), (t = this.nodes.root) == null || t.classList.add(L.noFocus), (o = this.nodes.root) == null || o.addEventListener("mouseleave", this.removeSpecialHoverBehavior, { once: !0 });
+ }
+ /**
+ * Disables special focus and hover behavior
+ */
+ disableSpecialHoverAndFocusBehavior() {
+ var e;
+ this.removeSpecialFocusBehavior(), this.removeSpecialHoverBehavior(), (e = this.nodes.root) == null || e.removeEventListener("mouseleave", this.removeSpecialHoverBehavior);
+ }
+ /**
+ * Executes item's onActivate callback if the item has no confirmation configured
+ *
+ * @param item - item to activate or bring to confirmation mode
+ */
+ activateOrEnableConfirmationMode(e) {
+ var t;
+ if (!("confirmation" in e) || e.confirmation === void 0)
+ try {
+ (t = e.onActivate) == null || t.call(e, e), this.disableConfirmationMode();
+ } catch {
+ this.animateError();
+ }
+ else
+ this.enableConfirmationMode(e.confirmation);
+ }
+ /**
+ * Animates item which symbolizes that error occured while executing 'onActivate()' callback
+ */
+ animateError() {
+ var e, t, o;
+ (e = this.nodes.icon) != null && e.classList.contains(L.wobbleAnimation) || ((t = this.nodes.icon) == null || t.classList.add(L.wobbleAnimation), (o = this.nodes.icon) == null || o.addEventListener("animationend", this.onErrorAnimationEnd));
+ }
+}
+const nt = ne("ce-popover-item-separator"), it = {
+ container: nt(),
+ line: nt("line"),
+ hidden: nt(null, "hidden")
+};
+class Qo extends xt {
+ /**
+ * Constructs the instance
+ */
+ constructor() {
+ super(), this.nodes = {
+ root: d.make("div", it.container),
+ line: d.make("div", it.line)
+ }, this.nodes.root.appendChild(this.nodes.line);
+ }
+ /**
+ * Returns popover separator root element
+ */
+ getElement() {
+ return this.nodes.root;
+ }
+ /**
+ * Toggles item hidden state
+ *
+ * @param isHidden - true if item should be hidden
+ */
+ toggleHidden(e) {
+ var t;
+ (t = this.nodes.root) == null || t.classList.toggle(it.hidden, e);
+ }
+}
+var G = /* @__PURE__ */ ((n) => (n.Closed = "closed", n.ClosedOnActivate = "closed-on-activate", n))(G || {});
+const $ = ne("ce-popover"), P = {
+ popover: $(),
+ popoverContainer: $("container"),
+ popoverOpenTop: $(null, "open-top"),
+ popoverOpenLeft: $(null, "open-left"),
+ popoverOpened: $(null, "opened"),
+ search: $("search"),
+ nothingFoundMessage: $("nothing-found-message"),
+ nothingFoundMessageDisplayed: $("nothing-found-message", "displayed"),
+ items: $("items"),
+ overlay: $("overlay"),
+ overlayHidden: $("overlay", "hidden"),
+ popoverNested: $(null, "nested"),
+ getPopoverNestedClass: (n) => $(null, `nested-level-${n.toString()}`),
+ popoverInline: $(null, "inline"),
+ popoverHeader: $("header")
+};
+var fe = /* @__PURE__ */ ((n) => (n.NestingLevel = "--nesting-level", n.PopoverHeight = "--popover-height", n.InlinePopoverWidth = "--inline-popover-width", n.TriggerItemLeft = "--trigger-item-left", n.TriggerItemTop = "--trigger-item-top", n))(fe || {});
+const To = ne("ce-popover-item-html"), So = {
+ root: To(),
+ hidden: To(null, "hidden")
+};
+class Se extends xt {
+ /**
+ * Constructs the instance
+ *
+ * @param params – instance parameters
+ * @param renderParams – popover item render params.
+ * The parameters that are not set by user via popover api but rather depend on technical implementation
+ */
+ constructor(e, t) {
+ var o, i;
+ super(e), this.nodes = {
+ root: d.make("div", So.root)
+ }, this.nodes.root.appendChild(e.element), e.name && (this.nodes.root.dataset.itemName = e.name), e.hint !== void 0 && ((o = t == null ? void 0 : t.hint) == null ? void 0 : o.enabled) !== !1 && this.addHint(this.nodes.root, {
+ ...e.hint,
+ position: ((i = t == null ? void 0 : t.hint) == null ? void 0 : i.position) || "right"
+ });
+ }
+ /**
+ * Returns popover item root element
+ */
+ getElement() {
+ return this.nodes.root;
+ }
+ /**
+ * Toggles item hidden state
+ *
+ * @param isHidden - true if item should be hidden
+ */
+ toggleHidden(e) {
+ var t;
+ (t = this.nodes.root) == null || t.classList.toggle(So.hidden, e);
+ }
+ /**
+ * Returns list of buttons and inputs inside custom content
+ */
+ getControls() {
+ const e = this.nodes.root.querySelectorAll(
+ `button, ${d.allInputsSelector}`
+ );
+ return Array.from(e);
+ }
+}
+class Jo extends Oe {
+ /**
+ * Constructs the instance
+ *
+ * @param params - popover construction params
+ * @param itemsRenderParams - popover item render params.
+ * The parameters that are not set by user via popover api but rather depend on technical implementation
+ */
+ constructor(e, t = {}) {
+ super(), this.params = e, this.itemsRenderParams = t, this.listeners = new _e(), this.messages = {
+ nothingFound: "Nothing found",
+ search: "Search"
+ }, this.items = this.buildItems(e.items), e.messages && (this.messages = {
+ ...this.messages,
+ ...e.messages
+ }), this.nodes = {}, this.nodes.popoverContainer = d.make("div", [P.popoverContainer]), this.nodes.nothingFoundMessage = d.make("div", [P.nothingFoundMessage], {
+ textContent: this.messages.nothingFound
+ }), this.nodes.popoverContainer.appendChild(this.nodes.nothingFoundMessage), this.nodes.items = d.make("div", [P.items]), this.items.forEach((o) => {
+ const i = o.getElement();
+ i !== null && this.nodes.items.appendChild(i);
+ }), this.nodes.popoverContainer.appendChild(this.nodes.items), this.listeners.on(this.nodes.popoverContainer, "click", (o) => this.handleClick(o)), this.nodes.popover = d.make("div", [
+ P.popover,
+ this.params.class
+ ]), this.nodes.popover.appendChild(this.nodes.popoverContainer);
+ }
+ /**
+ * List of default popover items that are searchable and may have confirmation state
+ */
+ get itemsDefault() {
+ return this.items.filter((e) => e instanceof re);
+ }
+ /**
+ * Returns HTML element corresponding to the popover
+ */
+ getElement() {
+ return this.nodes.popover;
+ }
+ /**
+ * Open popover
+ */
+ show() {
+ this.nodes.popover.classList.add(P.popoverOpened), this.search !== void 0 && this.search.focus();
+ }
+ /**
+ * Closes popover
+ */
+ hide() {
+ this.nodes.popover.classList.remove(P.popoverOpened), this.nodes.popover.classList.remove(P.popoverOpenTop), this.itemsDefault.forEach((e) => e.reset()), this.search !== void 0 && this.search.clear(), this.emit(G.Closed);
+ }
+ /**
+ * Clears memory
+ */
+ destroy() {
+ var e;
+ this.items.forEach((t) => t.destroy()), this.nodes.popover.remove(), this.listeners.removeAll(), (e = this.search) == null || e.destroy();
+ }
+ /**
+ * Looks for the item by name and imitates click on it
+ *
+ * @param name - name of the item to activate
+ */
+ activateItemByName(e) {
+ const t = this.items.find((o) => o.name === e);
+ this.handleItemClick(t);
+ }
+ /**
+ * Factory method for creating popover items
+ *
+ * @param items - list of items params
+ */
+ buildItems(e) {
+ return e.map((t) => {
+ switch (t.type) {
+ case _.Separator:
+ return new Qo();
+ case _.Html:
+ return new Se(t, this.itemsRenderParams[_.Html]);
+ default:
+ return new re(t, this.itemsRenderParams[_.Default]);
+ }
+ });
+ }
+ /**
+ * Retrieves popover item that is the target of the specified event
+ *
+ * @param event - event to retrieve popover item from
+ */
+ getTargetItem(e) {
+ return this.items.filter((t) => t instanceof re || t instanceof Se).find((t) => {
+ const o = t.getElement();
+ return o === null ? !1 : e.composedPath().includes(o);
+ });
+ }
+ /**
+ * Handles popover item click
+ *
+ * @param item - item to handle click of
+ */
+ handleItemClick(e) {
+ if (!("isDisabled" in e && e.isDisabled)) {
+ if (e.hasChildren) {
+ this.showNestedItems(e), "handleClick" in e && typeof e.handleClick == "function" && e.handleClick();
+ return;
+ }
+ this.itemsDefault.filter((t) => t !== e).forEach((t) => t.reset()), "handleClick" in e && typeof e.handleClick == "function" && e.handleClick(), this.toggleItemActivenessIfNeeded(e), e.closeOnActivate && (this.hide(), this.emit(G.ClosedOnActivate));
+ }
+ }
+ /**
+ * Handles clicks inside popover
+ *
+ * @param event - item to handle click of
+ */
+ handleClick(e) {
+ const t = this.getTargetItem(e);
+ t !== void 0 && this.handleItemClick(t);
+ }
+ /**
+ * - Toggles item active state, if clicked popover item has property 'toggle' set to true.
+ *
+ * - Performs radiobutton-like behavior if the item has property 'toggle' set to string key.
+ * (All the other items with the same key get inactive, and the item gets active)
+ *
+ * @param clickedItem - popover item that was clicked
+ */
+ toggleItemActivenessIfNeeded(e) {
+ if (e instanceof re && (e.toggle === !0 && e.toggleActive(), typeof e.toggle == "string")) {
+ const t = this.itemsDefault.filter((o) => o.toggle === e.toggle);
+ if (t.length === 1) {
+ e.toggleActive();
+ return;
+ }
+ t.forEach((o) => {
+ o.toggleActive(o === e);
+ });
+ }
+ }
+}
+var Ue = /* @__PURE__ */ ((n) => (n.Search = "search", n))(Ue || {});
+const st = ne("cdx-search-field"), rt = {
+ wrapper: st(),
+ icon: st("icon"),
+ input: st("input")
+};
+class ls extends Oe {
+ /**
+ * @param options - available config
+ * @param options.items - searchable items list
+ * @param options.placeholder - input placeholder
+ */
+ constructor({ items: e, placeholder: t }) {
+ super(), this.listeners = new _e(), this.items = e, this.wrapper = d.make("div", rt.wrapper);
+ const o = d.make("div", rt.icon, {
+ innerHTML: os
+ });
+ this.input = d.make("input", rt.input, {
+ placeholder: t,
+ /**
+ * Used to prevent focusing on the input by Tab key
+ * (Popover in the Toolbar lays below the blocks,
+ * so Tab in the last block will focus this hidden input if this property is not set)
+ */
+ tabIndex: -1
+ }), this.wrapper.appendChild(o), this.wrapper.appendChild(this.input), this.listeners.on(this.input, "input", () => {
+ this.searchQuery = this.input.value, this.emit(Ue.Search, {
+ query: this.searchQuery,
+ items: this.foundItems
+ });
+ });
+ }
+ /**
+ * Returns search field element
+ */
+ getElement() {
+ return this.wrapper;
+ }
+ /**
+ * Sets focus to the input
+ */
+ focus() {
+ this.input.focus();
+ }
+ /**
+ * Clears search query and results
+ */
+ clear() {
+ this.input.value = "", this.searchQuery = "", this.emit(Ue.Search, {
+ query: "",
+ items: this.foundItems
+ });
+ }
+ /**
+ * Clears memory
+ */
+ destroy() {
+ this.listeners.removeAll();
+ }
+ /**
+ * Returns list of found items for the current search query
+ */
+ get foundItems() {
+ return this.items.filter((e) => this.checkItem(e));
+ }
+ /**
+ * Contains logic for checking whether passed item conforms the search query
+ *
+ * @param item - item to be checked
+ */
+ checkItem(e) {
+ var i, s;
+ const t = ((i = e.title) == null ? void 0 : i.toLowerCase()) || "", o = (s = this.searchQuery) == null ? void 0 : s.toLowerCase();
+ return o !== void 0 ? t.includes(o) : !1;
+ }
+}
+var cs = Object.defineProperty, ds = Object.getOwnPropertyDescriptor, us = (n, e, t, o) => {
+ for (var i = o > 1 ? void 0 : o ? ds(e, t) : e, s = n.length - 1, r; s >= 0; s--)
+ (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);
+ return o && i && cs(e, t, i), i;
+};
+const en = class tn extends Jo {
+ /**
+ * Construct the instance
+ *
+ * @param params - popover params
+ * @param itemsRenderParams – popover item render params.
+ * The parameters that are not set by user via popover api but rather depend on technical implementation
+ */
+ constructor(e, t) {
+ super(e, t), this.nestingLevel = 0, this.nestedPopoverTriggerItem = null, this.previouslyHoveredItem = null, this.scopeElement = document.body, this.hide = () => {
+ var o;
+ super.hide(), this.destroyNestedPopoverIfExists(), (o = this.flipper) == null || o.deactivate(), this.previouslyHoveredItem = null;
+ }, this.onFlip = () => {
+ const o = this.itemsDefault.find((i) => i.isFocused);
+ o == null || o.onFocus();
+ }, this.onSearch = (o) => {
+ var a;
+ const i = o.query === "", s = o.items.length === 0;
+ this.items.forEach((l) => {
+ let c = !1;
+ l instanceof re ? c = !o.items.includes(l) : (l instanceof Qo || l instanceof Se) && (c = s || !i), l.toggleHidden(c);
+ }), this.toggleNothingFoundMessage(s);
+ const r = o.query === "" ? this.flippableElements : o.items.map((l) => l.getElement());
+ (a = this.flipper) != null && a.isActivated && (this.flipper.deactivate(), this.flipper.activate(r));
+ }, e.nestingLevel !== void 0 && (this.nestingLevel = e.nestingLevel), this.nestingLevel > 0 && this.nodes.popover.classList.add(P.popoverNested), e.scopeElement !== void 0 && (this.scopeElement = e.scopeElement), this.nodes.popoverContainer !== null && this.listeners.on(this.nodes.popoverContainer, "mouseover", (o) => this.handleHover(o)), e.searchable && this.addSearch(), e.flippable !== !1 && (this.flipper = new ce({
+ items: this.flippableElements,
+ focusedItemClass: L.focused,
+ allowedKeys: [
+ y.TAB,
+ y.UP,
+ y.DOWN,
+ y.ENTER
+ ]
+ }), this.flipper.onFlip(this.onFlip));
+ }
+ /**
+ * Returns true if some item inside popover is focused
+ */
+ hasFocus() {
+ return this.flipper === void 0 ? !1 : this.flipper.hasFocus();
+ }
+ /**
+ * Scroll position inside items container of the popover
+ */
+ get scrollTop() {
+ return this.nodes.items === null ? 0 : this.nodes.items.scrollTop;
+ }
+ /**
+ * Returns visible element offset top
+ */
+ get offsetTop() {
+ return this.nodes.popoverContainer === null ? 0 : this.nodes.popoverContainer.offsetTop;
+ }
+ /**
+ * Open popover
+ */
+ show() {
+ var e;
+ this.nodes.popover.style.setProperty(fe.PopoverHeight, this.size.height + "px"), this.shouldOpenBottom || this.nodes.popover.classList.add(P.popoverOpenTop), this.shouldOpenRight || this.nodes.popover.classList.add(P.popoverOpenLeft), super.show(), (e = this.flipper) == null || e.activate(this.flippableElements);
+ }
+ /**
+ * Clears memory
+ */
+ destroy() {
+ this.hide(), super.destroy();
+ }
+ /**
+ * Handles displaying nested items for the item.
+ *
+ * @param item – item to show nested popover for
+ */
+ showNestedItems(e) {
+ this.nestedPopover !== null && this.nestedPopover !== void 0 || (this.nestedPopoverTriggerItem = e, this.showNestedPopoverForItem(e));
+ }
+ /**
+ * Handles hover events inside popover items container
+ *
+ * @param event - hover event data
+ */
+ handleHover(e) {
+ const t = this.getTargetItem(e);
+ t !== void 0 && this.previouslyHoveredItem !== t && (this.destroyNestedPopoverIfExists(), this.previouslyHoveredItem = t, t.hasChildren && this.showNestedPopoverForItem(t));
+ }
+ /**
+ * Sets CSS variable with position of item near which nested popover should be displayed.
+ * Is used for correct positioning of the nested popover
+ *
+ * @param nestedPopoverEl - nested popover element
+ * @param item – item near which nested popover should be displayed
+ */
+ setTriggerItemPosition(e, t) {
+ const o = t.getElement(), i = (o ? o.offsetTop : 0) - this.scrollTop, s = this.offsetTop + i;
+ e.style.setProperty(fe.TriggerItemTop, s + "px");
+ }
+ /**
+ * Destroys existing nested popover
+ */
+ destroyNestedPopoverIfExists() {
+ var e, t;
+ this.nestedPopover === void 0 || this.nestedPopover === null || (this.nestedPopover.off(G.ClosedOnActivate, this.hide), this.nestedPopover.hide(), this.nestedPopover.destroy(), this.nestedPopover.getElement().remove(), this.nestedPopover = null, (e = this.flipper) == null || e.activate(this.flippableElements), (t = this.nestedPopoverTriggerItem) == null || t.onChildrenClose());
+ }
+ /**
+ * Creates and displays nested popover for specified item.
+ * Is used only on desktop
+ *
+ * @param item - item to display nested popover by
+ */
+ showNestedPopoverForItem(e) {
+ var o;
+ this.nestedPopover = new tn({
+ searchable: e.isChildrenSearchable,
+ items: e.children,
+ nestingLevel: this.nestingLevel + 1,
+ flippable: e.isChildrenFlippable,
+ messages: this.messages
+ }), e.onChildrenOpen(), this.nestedPopover.on(G.ClosedOnActivate, this.hide);
+ const t = this.nestedPopover.getElement();
+ return this.nodes.popover.appendChild(t), this.setTriggerItemPosition(t, e), t.style.setProperty(fe.NestingLevel, this.nestedPopover.nestingLevel.toString()), this.nestedPopover.show(), (o = this.flipper) == null || o.deactivate(), this.nestedPopover;
+ }
+ /**
+ * Checks if popover should be opened bottom.
+ * It should happen when there is enough space below or not enough space above
+ */
+ get shouldOpenBottom() {
+ if (this.nodes.popover === void 0 || this.nodes.popover === null)
+ return !1;
+ const e = this.nodes.popoverContainer.getBoundingClientRect(), t = this.scopeElement.getBoundingClientRect(), o = this.size.height, i = e.top + o, s = e.top - o, r = Math.min(window.innerHeight, t.bottom);
+ return s < t.top || i <= r;
+ }
+ /**
+ * Checks if popover should be opened left.
+ * It should happen when there is enough space in the right or not enough space in the left
+ */
+ get shouldOpenRight() {
+ if (this.nodes.popover === void 0 || this.nodes.popover === null)
+ return !1;
+ const e = this.nodes.popover.getBoundingClientRect(), t = this.scopeElement.getBoundingClientRect(), o = this.size.width, i = e.right + o, s = e.left - o, r = Math.min(window.innerWidth, t.right);
+ return s < t.left || i <= r;
+ }
+ get size() {
+ var i;
+ const e = {
+ height: 0,
+ width: 0
+ };
+ if (this.nodes.popover === null)
+ return e;
+ const t = this.nodes.popover.cloneNode(!0);
+ t.style.visibility = "hidden", t.style.position = "absolute", t.style.top = "-1000px", t.classList.add(P.popoverOpened), (i = t.querySelector("." + P.popoverNested)) == null || i.remove(), document.body.appendChild(t);
+ const o = t.querySelector("." + P.popoverContainer);
+ return e.height = o.offsetHeight, e.width = o.offsetWidth, t.remove(), e;
+ }
+ /**
+ * Returns list of elements available for keyboard navigation.
+ */
+ get flippableElements() {
+ return this.items.map((t) => {
+ if (t instanceof re)
+ return t.getElement();
+ if (t instanceof Se)
+ return t.getControls();
+ }).flat().filter((t) => t != null);
+ }
+ /**
+ * Adds search to the popover
+ */
+ addSearch() {
+ this.search = new ls({
+ items: this.itemsDefault,
+ placeholder: this.messages.search
+ }), this.search.on(Ue.Search, this.onSearch);
+ const e = this.search.getElement();
+ e.classList.add(P.search), this.nodes.popoverContainer.insertBefore(e, this.nodes.popoverContainer.firstChild);
+ }
+ /**
+ * Toggles nothing found message visibility
+ *
+ * @param isDisplayed - true if the message should be displayed
+ */
+ toggleNothingFoundMessage(e) {
+ this.nodes.nothingFoundMessage.classList.toggle(P.nothingFoundMessageDisplayed, e);
+ }
+};
+us([
+ me
+], en.prototype, "size", 1);
+let Bt = en;
+class hs extends Bt {
+ /**
+ * Constructs the instance
+ *
+ * @param params - instance parameters
+ */
+ constructor(e) {
+ const t = !be();
+ super(
+ {
+ ...e,
+ class: P.popoverInline
+ },
+ {
+ [_.Default]: {
+ /**
+ * We use button instead of div here to fix bug associated with focus loss (which leads to selection change) on click in safari
+ *
+ * @todo figure out better way to solve the issue
+ */
+ wrapperTag: "button",
+ hint: {
+ position: "top",
+ alignment: "center",
+ enabled: t
+ }
+ },
+ [_.Html]: {
+ hint: {
+ position: "top",
+ alignment: "center",
+ enabled: t
+ }
+ }
+ }
+ ), this.items.forEach((o) => {
+ !(o instanceof re) && !(o instanceof Se) || o.hasChildren && o.isChildrenOpen && this.showNestedItems(o);
+ });
+ }
+ /**
+ * Returns visible element offset top
+ */
+ get offsetLeft() {
+ return this.nodes.popoverContainer === null ? 0 : this.nodes.popoverContainer.offsetLeft;
+ }
+ /**
+ * Open popover
+ */
+ show() {
+ this.nestingLevel === 0 && this.nodes.popover.style.setProperty(
+ fe.InlinePopoverWidth,
+ this.size.width + "px"
+ ), super.show();
+ }
+ /**
+ * Disable hover event handling.
+ * Overrides parent's class behavior
+ */
+ handleHover() {
+ }
+ /**
+ * Sets CSS variable with position of item near which nested popover should be displayed.
+ * Is used to position nested popover right below clicked item
+ *
+ * @param nestedPopoverEl - nested popover element
+ * @param item – item near which nested popover should be displayed
+ */
+ setTriggerItemPosition(e, t) {
+ const o = t.getElement(), i = o ? o.offsetLeft : 0, s = this.offsetLeft + i;
+ e.style.setProperty(
+ fe.TriggerItemLeft,
+ s + "px"
+ );
+ }
+ /**
+ * Handles displaying nested items for the item.
+ * Overriding in order to add toggling behaviour
+ *
+ * @param item – item to toggle nested popover for
+ */
+ showNestedItems(e) {
+ if (this.nestedPopoverTriggerItem === e) {
+ this.destroyNestedPopoverIfExists(), this.nestedPopoverTriggerItem = null;
+ return;
+ }
+ super.showNestedItems(e);
+ }
+ /**
+ * Creates and displays nested popover for specified item.
+ * Is used only on desktop
+ *
+ * @param item - item to display nested popover by
+ */
+ showNestedPopoverForItem(e) {
+ const t = super.showNestedPopoverForItem(e);
+ return t.getElement().classList.add(P.getPopoverNestedClass(t.nestingLevel)), t;
+ }
+ /**
+ * Overrides default item click handling.
+ * Helps to close nested popover once other item is clicked.
+ *
+ * @param item - clicked item
+ */
+ handleItemClick(e) {
+ var t;
+ e !== this.nestedPopoverTriggerItem && ((t = this.nestedPopoverTriggerItem) == null || t.handleClick(), super.destroyNestedPopoverIfExists()), super.handleItemClick(e);
+ }
+}
+const on = class xe {
+ constructor() {
+ this.scrollPosition = null;
+ }
+ /**
+ * Locks body element scroll
+ */
+ lock() {
+ pt ? this.lockHard() : document.body.classList.add(xe.CSS.scrollLocked);
+ }
+ /**
+ * Unlocks body element scroll
+ */
+ unlock() {
+ pt ? this.unlockHard() : document.body.classList.remove(xe.CSS.scrollLocked);
+ }
+ /**
+ * Locks scroll in a hard way (via setting fixed position to body element)
+ */
+ lockHard() {
+ this.scrollPosition = window.pageYOffset, document.documentElement.style.setProperty(
+ "--window-scroll-offset",
+ `${this.scrollPosition}px`
+ ), document.body.classList.add(xe.CSS.scrollLockedHard);
+ }
+ /**
+ * Unlocks hard scroll lock
+ */
+ unlockHard() {
+ document.body.classList.remove(xe.CSS.scrollLockedHard), this.scrollPosition !== null && window.scrollTo(0, this.scrollPosition), this.scrollPosition = null;
+ }
+};
+on.CSS = {
+ scrollLocked: "ce-scroll-locked",
+ scrollLockedHard: "ce-scroll-locked--hard"
+};
+let ps = on;
+const at = ne("ce-popover-header"), lt = {
+ root: at(),
+ text: at("text"),
+ backButton: at("back-button")
+};
+class fs {
+ /**
+ * Constructs the instance
+ *
+ * @param params - popover header params
+ */
+ constructor({ text: e, onBackButtonClick: t }) {
+ this.listeners = new _e(), this.text = e, this.onBackButtonClick = t, this.nodes = {
+ root: d.make("div", [lt.root]),
+ backButton: d.make("button", [lt.backButton]),
+ text: d.make("div", [lt.text])
+ }, this.nodes.backButton.innerHTML = Vi, this.nodes.root.appendChild(this.nodes.backButton), this.listeners.on(this.nodes.backButton, "click", this.onBackButtonClick), this.nodes.text.innerText = this.text, this.nodes.root.appendChild(this.nodes.text);
+ }
+ /**
+ * Returns popover header root html element
+ */
+ getElement() {
+ return this.nodes.root;
+ }
+ /**
+ * Destroys the instance
+ */
+ destroy() {
+ this.nodes.root.remove(), this.listeners.destroy();
+ }
+}
+class gs {
+ constructor() {
+ this.history = [];
+ }
+ /**
+ * Push new popover state
+ *
+ * @param state - new state
+ */
+ push(e) {
+ this.history.push(e);
+ }
+ /**
+ * Pop last popover state
+ */
+ pop() {
+ return this.history.pop();
+ }
+ /**
+ * Title retrieved from the current state
+ */
+ get currentTitle() {
+ return this.history.length === 0 ? "" : this.history[this.history.length - 1].title;
+ }
+ /**
+ * Items list retrieved from the current state
+ */
+ get currentItems() {
+ return this.history.length === 0 ? [] : this.history[this.history.length - 1].items;
+ }
+ /**
+ * Returns history to initial popover state
+ */
+ reset() {
+ for (; this.history.length > 1; )
+ this.pop();
+ }
+}
+class nn extends Jo {
+ /**
+ * Construct the instance
+ *
+ * @param params - popover params
+ */
+ constructor(e) {
+ super(e, {
+ [_.Default]: {
+ hint: {
+ enabled: !1
+ }
+ },
+ [_.Html]: {
+ hint: {
+ enabled: !1
+ }
+ }
+ }), this.scrollLocker = new ps(), this.history = new gs(), this.isHidden = !0, this.nodes.overlay = d.make("div", [P.overlay, P.overlayHidden]), this.nodes.popover.insertBefore(this.nodes.overlay, this.nodes.popover.firstChild), this.listeners.on(this.nodes.overlay, "click", () => {
+ this.hide();
+ }), this.history.push({ items: e.items });
+ }
+ /**
+ * Open popover
+ */
+ show() {
+ this.nodes.overlay.classList.remove(P.overlayHidden), super.show(), this.scrollLocker.lock(), this.isHidden = !1;
+ }
+ /**
+ * Closes popover
+ */
+ hide() {
+ this.isHidden || (super.hide(), this.nodes.overlay.classList.add(P.overlayHidden), this.scrollLocker.unlock(), this.history.reset(), this.isHidden = !0);
+ }
+ /**
+ * Clears memory
+ */
+ destroy() {
+ super.destroy(), this.scrollLocker.unlock();
+ }
+ /**
+ * Handles displaying nested items for the item
+ *
+ * @param item – item to show nested popover for
+ */
+ showNestedItems(e) {
+ this.updateItemsAndHeader(e.children, e.title), this.history.push({
+ title: e.title,
+ items: e.children
+ });
+ }
+ /**
+ * Removes rendered popover items and header and displays new ones
+ *
+ * @param items - new popover items
+ * @param title - new popover header text
+ */
+ updateItemsAndHeader(e, t) {
+ if (this.header !== null && this.header !== void 0 && (this.header.destroy(), this.header = null), t !== void 0) {
+ this.header = new fs({
+ text: t,
+ onBackButtonClick: () => {
+ this.history.pop(), this.updateItemsAndHeader(this.history.currentItems, this.history.currentTitle);
+ }
+ });
+ const o = this.header.getElement();
+ o !== null && this.nodes.popoverContainer.insertBefore(o, this.nodes.popoverContainer.firstChild);
+ }
+ this.items.forEach((o) => {
+ var i;
+ return (i = o.getElement()) == null ? void 0 : i.remove();
+ }), this.items = this.buildItems(e), this.items.forEach((o) => {
+ var s;
+ const i = o.getElement();
+ i !== null && ((s = this.nodes.items) == null || s.appendChild(i));
+ });
+ }
+}
+class ms extends E {
+ constructor() {
+ super(...arguments), this.opened = !1, this.selection = new b(), this.popover = null, this.close = () => {
+ this.opened && (this.opened = !1, b.isAtEditor || this.selection.restore(), this.selection.clearSaved(), !this.Editor.CrossBlockSelection.isCrossBlockSelectionStarted && this.Editor.BlockManager.currentBlock && this.Editor.BlockSelection.unselectBlock(this.Editor.BlockManager.currentBlock), this.eventsDispatcher.emit(this.events.closed), this.popover && (this.popover.off(G.Closed, this.onPopoverClose), this.popover.destroy(), this.popover.getElement().remove(), this.popover = null));
+ }, this.onPopoverClose = () => {
+ this.close();
+ };
+ }
+ /**
+ * Module Events
+ */
+ get events() {
+ return {
+ opened: "block-settings-opened",
+ closed: "block-settings-closed"
+ };
+ }
+ /**
+ * Block Settings CSS
+ */
+ get CSS() {
+ return {
+ settings: "ce-settings"
+ };
+ }
+ /**
+ * Getter for inner popover's flipper instance
+ *
+ * @todo remove once BlockSettings becomes standalone non-module class
+ */
+ get flipper() {
+ var e;
+ if (this.popover !== null)
+ return "flipper" in this.popover ? (e = this.popover) == null ? void 0 : e.flipper : void 0;
+ }
+ /**
+ * Panel with block settings with 2 sections:
+ * - Tool's Settings
+ * - Default Settings [Move, Remove, etc]
+ */
+ make() {
+ this.nodes.wrapper = d.make("div", [this.CSS.settings]), this.eventsDispatcher.on(Te, this.close);
+ }
+ /**
+ * Destroys module
+ */
+ destroy() {
+ this.removeAllNodes(), this.listeners.destroy(), this.eventsDispatcher.off(Te, this.close);
+ }
+ /**
+ * Open Block Settings pane
+ *
+ * @param targetBlock - near which Block we should open BlockSettings
+ */
+ async open(e = this.Editor.BlockManager.currentBlock) {
+ var s;
+ this.opened = !0, this.selection.save(), this.Editor.BlockSelection.selectBlock(e), this.Editor.BlockSelection.clearCache();
+ const { toolTunes: t, commonTunes: o } = e.getTunes();
+ this.eventsDispatcher.emit(this.events.opened);
+ const i = be() ? nn : Bt;
+ this.popover = new i({
+ searchable: !0,
+ items: await this.getTunesItems(e, o, t),
+ scopeElement: this.Editor.API.methods.ui.nodes.redactor,
+ messages: {
+ nothingFound: z.ui(K.ui.popover, "Nothing found"),
+ search: z.ui(K.ui.popover, "Filter")
+ }
+ }), this.popover.on(G.Closed, this.onPopoverClose), (s = this.nodes.wrapper) == null || s.append(this.popover.getElement()), this.popover.show();
+ }
+ /**
+ * Returns root block settings element
+ */
+ getElement() {
+ return this.nodes.wrapper;
+ }
+ /**
+ * Returns list of items to be displayed in block tunes menu.
+ * Merges tool specific tunes, conversion menu and common tunes in one list in predefined order
+ *
+ * @param currentBlock – block we are about to open block tunes for
+ * @param commonTunes – common tunes
+ * @param toolTunes - tool specific tunes
+ */
+ async getTunesItems(e, t, o) {
+ const i = [];
+ o !== void 0 && o.length > 0 && (i.push(...o), i.push({
+ type: _.Separator
+ }));
+ const s = Array.from(this.Editor.Tools.blockTools.values()), a = (await Yo(e, s)).reduce((l, c) => (c.toolbox.forEach((u) => {
+ l.push({
+ icon: u.icon,
+ title: z.t(K.toolNames, u.title),
+ name: c.name,
+ closeOnActivate: !0,
+ onActivate: async () => {
+ const { BlockManager: h, Caret: p, Toolbar: g } = this.Editor, f = await h.convert(e, c.name, u.data);
+ g.close(), p.setToBlock(f, p.positions.END);
+ }
+ });
+ }), l), []);
+ return a.length > 0 && (i.push({
+ icon: Go,
+ name: "convert-to",
+ title: z.ui(K.ui.popover, "Convert to"),
+ children: {
+ searchable: !0,
+ items: a
+ }
+ }), i.push({
+ type: _.Separator
+ })), i.push(...t), i.map((l) => this.resolveTuneAliases(l));
+ }
+ /**
+ * Resolves aliases in tunes menu items
+ *
+ * @param item - item with resolved aliases
+ */
+ resolveTuneAliases(e) {
+ if (e.type === _.Separator || e.type === _.Html)
+ return e;
+ const t = Yi(e, { label: "title" });
+ return e.confirmation && (t.confirmation = this.resolveTuneAliases(e.confirmation)), t;
+ }
+}
+var sn = { exports: {} };
+/*!
+ * Library for handling keyboard shortcuts
+ * @copyright CodeX (https://codex.so)
+ * @license MIT
+ * @author CodeX (https://codex.so)
+ * @version 1.2.0
+ */
+(function(n, e) {
+ (function(t, o) {
+ n.exports = o();
+ })(window, function() {
+ return function(t) {
+ var o = {};
+ function i(s) {
+ if (o[s])
+ return o[s].exports;
+ var r = o[s] = { i: s, l: !1, exports: {} };
+ return t[s].call(r.exports, r, r.exports, i), r.l = !0, r.exports;
+ }
+ return i.m = t, i.c = o, i.d = function(s, r, a) {
+ i.o(s, r) || Object.defineProperty(s, r, { enumerable: !0, get: a });
+ }, i.r = function(s) {
+ typeof Symbol < "u" && Symbol.toStringTag && Object.defineProperty(s, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(s, "__esModule", { value: !0 });
+ }, i.t = function(s, r) {
+ if (1 & r && (s = i(s)), 8 & r || 4 & r && typeof s == "object" && s && s.__esModule)
+ return s;
+ var a = /* @__PURE__ */ Object.create(null);
+ if (i.r(a), Object.defineProperty(a, "default", { enumerable: !0, value: s }), 2 & r && typeof s != "string")
+ for (var l in s)
+ i.d(a, l, (function(c) {
+ return s[c];
+ }).bind(null, l));
+ return a;
+ }, i.n = function(s) {
+ var r = s && s.__esModule ? function() {
+ return s.default;
+ } : function() {
+ return s;
+ };
+ return i.d(r, "a", r), r;
+ }, i.o = function(s, r) {
+ return Object.prototype.hasOwnProperty.call(s, r);
+ }, i.p = "", i(i.s = 0);
+ }([function(t, o, i) {
+ function s(l, c) {
+ for (var u = 0; u < c.length; u++) {
+ var h = c[u];
+ h.enumerable = h.enumerable || !1, h.configurable = !0, "value" in h && (h.writable = !0), Object.defineProperty(l, h.key, h);
+ }
+ }
+ function r(l, c, u) {
+ return c && s(l.prototype, c), u && s(l, u), l;
+ }
+ i.r(o);
+ var a = function() {
+ function l(c) {
+ var u = this;
+ (function(h, p) {
+ if (!(h instanceof p))
+ throw new TypeError("Cannot call a class as a function");
+ })(this, l), this.commands = {}, this.keys = {}, this.name = c.name, this.parseShortcutName(c.name), this.element = c.on, this.callback = c.callback, this.executeShortcut = function(h) {
+ u.execute(h);
+ }, this.element.addEventListener("keydown", this.executeShortcut, !1);
+ }
+ return r(l, null, [{ key: "supportedCommands", get: function() {
+ return { SHIFT: ["SHIFT"], CMD: ["CMD", "CONTROL", "COMMAND", "WINDOWS", "CTRL"], ALT: ["ALT", "OPTION"] };
+ } }, { key: "keyCodes", get: function() {
+ return { 0: 48, 1: 49, 2: 50, 3: 51, 4: 52, 5: 53, 6: 54, 7: 55, 8: 56, 9: 57, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90, BACKSPACE: 8, ENTER: 13, ESCAPE: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, INSERT: 45, DELETE: 46, ".": 190 };
+ } }]), r(l, [{ key: "parseShortcutName", value: function(c) {
+ c = c.split("+");
+ for (var u = 0; u < c.length; u++) {
+ c[u] = c[u].toUpperCase();
+ var h = !1;
+ for (var p in l.supportedCommands)
+ if (l.supportedCommands[p].includes(c[u])) {
+ h = this.commands[p] = !0;
+ break;
+ }
+ h || (this.keys[c[u]] = !0);
+ }
+ for (var g in l.supportedCommands)
+ this.commands[g] || (this.commands[g] = !1);
+ } }, { key: "execute", value: function(c) {
+ var u, h = { CMD: c.ctrlKey || c.metaKey, SHIFT: c.shiftKey, ALT: c.altKey }, p = !0;
+ for (u in this.commands)
+ this.commands[u] !== h[u] && (p = !1);
+ var g, f = !0;
+ for (g in this.keys)
+ f = f && c.keyCode === l.keyCodes[g];
+ p && f && this.callback(c);
+ } }, { key: "remove", value: function() {
+ this.element.removeEventListener("keydown", this.executeShortcut);
+ } }]), l;
+ }();
+ o.default = a;
+ }]).default;
+ });
+})(sn);
+var bs = sn.exports;
+const vs = /* @__PURE__ */ Ke(bs);
+class ks {
+ constructor() {
+ this.registeredShortcuts = /* @__PURE__ */ new Map();
+ }
+ /**
+ * Register shortcut
+ *
+ * @param shortcut - shortcut options
+ */
+ add(e) {
+ if (this.findShortcut(e.on, e.name))
+ throw Error(
+ `Shortcut ${e.name} is already registered for ${e.on}. Please remove it before add a new handler.`
+ );
+ const o = new vs({
+ name: e.name,
+ on: e.on,
+ callback: e.handler
+ }), i = this.registeredShortcuts.get(e.on) || [];
+ this.registeredShortcuts.set(e.on, [...i, o]);
+ }
+ /**
+ * Remove shortcut
+ *
+ * @param element - Element shortcut is set for
+ * @param name - shortcut name
+ */
+ remove(e, t) {
+ const o = this.findShortcut(e, t);
+ if (!o)
+ return;
+ o.remove();
+ const s = this.registeredShortcuts.get(e).filter((r) => r !== o);
+ if (s.length === 0) {
+ this.registeredShortcuts.delete(e);
+ return;
+ }
+ this.registeredShortcuts.set(e, s);
+ }
+ /**
+ * Get Shortcut instance if exist
+ *
+ * @param element - Element shorcut is set for
+ * @param shortcut - shortcut name
+ * @returns {number} index - shortcut index if exist
+ */
+ findShortcut(e, t) {
+ return (this.registeredShortcuts.get(e) || []).find(({ name: i }) => i === t);
+ }
+}
+const ge = new ks();
+var ys = Object.defineProperty, ws = Object.getOwnPropertyDescriptor, rn = (n, e, t, o) => {
+ for (var i = o > 1 ? void 0 : o ? ws(e, t) : e, s = n.length - 1, r; s >= 0; s--)
+ (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);
+ return o && i && ys(e, t, i), i;
+}, Le = /* @__PURE__ */ ((n) => (n.Opened = "toolbox-opened", n.Closed = "toolbox-closed", n.BlockAdded = "toolbox-block-added", n))(Le || {});
+const Ct = class an extends Oe {
+ /**
+ * Toolbox constructor
+ *
+ * @param options - available parameters
+ * @param options.api - Editor API methods
+ * @param options.tools - Tools available to check whether some of them should be displayed at the Toolbox or not
+ */
+ constructor({ api: e, tools: t, i18nLabels: o }) {
+ super(), this.opened = !1, this.listeners = new _e(), this.popover = null, this.handleMobileLayoutToggle = () => {
+ this.destroyPopover(), this.initPopover();
+ }, this.onPopoverClose = () => {
+ this.opened = !1, this.emit(
+ "toolbox-closed"
+ /* Closed */
+ );
+ }, this.api = e, this.tools = t, this.i18nLabels = o, this.enableShortcuts(), this.nodes = {
+ toolbox: d.make("div", an.CSS.toolbox)
+ }, this.initPopover(), this.api.events.on(Te, this.handleMobileLayoutToggle);
+ }
+ /**
+ * Returns True if Toolbox is Empty and nothing to show
+ *
+ * @returns {boolean}
+ */
+ get isEmpty() {
+ return this.toolsToBeDisplayed.length === 0;
+ }
+ /**
+ * CSS styles
+ */
+ static get CSS() {
+ return {
+ toolbox: "ce-toolbox"
+ };
+ }
+ /**
+ * Returns root block settings element
+ */
+ getElement() {
+ return this.nodes.toolbox;
+ }
+ /**
+ * Returns true if the Toolbox has the Flipper activated and the Flipper has selected button
+ */
+ hasFocus() {
+ if (this.popover !== null)
+ return "hasFocus" in this.popover ? this.popover.hasFocus() : void 0;
+ }
+ /**
+ * Destroy Module
+ */
+ destroy() {
+ var e;
+ super.destroy(), this.nodes && this.nodes.toolbox && this.nodes.toolbox.remove(), this.removeAllShortcuts(), (e = this.popover) == null || e.off(G.Closed, this.onPopoverClose), this.listeners.destroy(), this.api.events.off(Te, this.handleMobileLayoutToggle);
+ }
+ /**
+ * Toolbox Tool's button click handler
+ *
+ * @param toolName - tool type to be activated
+ * @param blockDataOverrides - Block data predefined by the activated Toolbox item
+ */
+ toolButtonActivated(e, t) {
+ this.insertNewBlock(e, t);
+ }
+ /**
+ * Open Toolbox with Tools
+ */
+ open() {
+ var e;
+ this.isEmpty || ((e = this.popover) == null || e.show(), this.opened = !0, this.emit(
+ "toolbox-opened"
+ /* Opened */
+ ));
+ }
+ /**
+ * Close Toolbox
+ */
+ close() {
+ var e;
+ (e = this.popover) == null || e.hide(), this.opened = !1, this.emit(
+ "toolbox-closed"
+ /* Closed */
+ );
+ }
+ /**
+ * Close Toolbox
+ */
+ toggle() {
+ this.opened ? this.close() : this.open();
+ }
+ /**
+ * Creates toolbox popover and appends it inside wrapper element
+ */
+ initPopover() {
+ var t;
+ const e = be() ? nn : Bt;
+ this.popover = new e({
+ scopeElement: this.api.ui.nodes.redactor,
+ searchable: !0,
+ messages: {
+ nothingFound: this.i18nLabels.nothingFound,
+ search: this.i18nLabels.filter
+ },
+ items: this.toolboxItemsToBeDisplayed
+ }), this.popover.on(G.Closed, this.onPopoverClose), (t = this.nodes.toolbox) == null || t.append(this.popover.getElement());
+ }
+ /**
+ * Destroys popover instance and removes it from DOM
+ */
+ destroyPopover() {
+ this.popover !== null && (this.popover.hide(), this.popover.off(G.Closed, this.onPopoverClose), this.popover.destroy(), this.popover = null), this.nodes.toolbox !== null && (this.nodes.toolbox.innerHTML = "");
+ }
+ get toolsToBeDisplayed() {
+ const e = [];
+ return this.tools.forEach((t) => {
+ t.toolbox && e.push(t);
+ }), e;
+ }
+ get toolboxItemsToBeDisplayed() {
+ const e = (t, o, i = !0) => ({
+ icon: t.icon,
+ title: z.t(K.toolNames, t.title || je(o.name)),
+ name: o.name,
+ onActivate: () => {
+ this.toolButtonActivated(o.name, t.data);
+ },
+ secondaryLabel: o.shortcut && i ? vt(o.shortcut) : ""
+ });
+ return this.toolsToBeDisplayed.reduce((t, o) => (Array.isArray(o.toolbox) ? o.toolbox.forEach((i, s) => {
+ t.push(e(i, o, s === 0));
+ }) : o.toolbox !== void 0 && t.push(e(o.toolbox, o)), t), []);
+ }
+ /**
+ * Iterate all tools and enable theirs shortcuts if specified
+ */
+ enableShortcuts() {
+ this.toolsToBeDisplayed.forEach((e) => {
+ const t = e.shortcut;
+ t && this.enableShortcutForTool(e.name, t);
+ });
+ }
+ /**
+ * Enable shortcut Block Tool implemented shortcut
+ *
+ * @param {string} toolName - Tool name
+ * @param {string} shortcut - shortcut according to the ShortcutData Module format
+ */
+ enableShortcutForTool(e, t) {
+ ge.add({
+ name: t,
+ on: this.api.ui.nodes.redactor,
+ handler: async (o) => {
+ o.preventDefault();
+ const i = this.api.blocks.getCurrentBlockIndex(), s = this.api.blocks.getBlockByIndex(i);
+ if (s)
+ try {
+ const r = await this.api.blocks.convert(s.id, e);
+ this.api.caret.setToBlock(r, "end");
+ return;
+ } catch {
+ }
+ this.insertNewBlock(e);
+ }
+ });
+ }
+ /**
+ * Removes all added shortcuts
+ * Fired when the Read-Only mode is activated
+ */
+ removeAllShortcuts() {
+ this.toolsToBeDisplayed.forEach((e) => {
+ const t = e.shortcut;
+ t && ge.remove(this.api.ui.nodes.redactor, t);
+ });
+ }
+ /**
+ * Inserts new block
+ * Can be called when button clicked on Toolbox or by ShortcutData
+ *
+ * @param {string} toolName - Tool name
+ * @param blockDataOverrides - predefined Block data
+ */
+ async insertNewBlock(e, t) {
+ const o = this.api.blocks.getCurrentBlockIndex(), i = this.api.blocks.getBlockByIndex(o);
+ if (!i)
+ return;
+ const s = i.isEmpty ? o : o + 1;
+ let r;
+ if (t) {
+ const l = await this.api.blocks.composeBlockData(e);
+ r = Object.assign(l, t);
+ }
+ const a = this.api.blocks.insert(
+ e,
+ r,
+ void 0,
+ s,
+ void 0,
+ i.isEmpty
+ );
+ a.call(ee.APPEND_CALLBACK), this.api.caret.setToBlock(s), this.emit("toolbox-block-added", {
+ block: a
+ }), this.api.toolbar.close();
+ }
+};
+rn([
+ me
+], Ct.prototype, "toolsToBeDisplayed", 1);
+rn([
+ me
+], Ct.prototype, "toolboxItemsToBeDisplayed", 1);
+let Es = Ct;
+const ln = "block hovered";
+async function xs(n, e) {
+ const t = navigator.keyboard;
+ if (!t)
+ return e;
+ try {
+ return (await t.getLayoutMap()).get(n) || e;
+ } catch (o) {
+ return console.error(o), e;
+ }
+}
+class Bs extends E {
+ /**
+ * @class
+ * @param moduleConfiguration - Module Configuration
+ * @param moduleConfiguration.config - Editor's config
+ * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher
+ */
+ constructor({ config: e, eventsDispatcher: t }) {
+ super({
+ config: e,
+ eventsDispatcher: t
+ }), this.toolboxInstance = null;
+ }
+ /**
+ * CSS styles
+ *
+ * @returns {object}
+ */
+ get CSS() {
+ return {
+ toolbar: "ce-toolbar",
+ content: "ce-toolbar__content",
+ actions: "ce-toolbar__actions",
+ actionsOpened: "ce-toolbar__actions--opened",
+ toolbarOpened: "ce-toolbar--opened",
+ openedToolboxHolderModifier: "codex-editor--toolbox-opened",
+ plusButton: "ce-toolbar__plus",
+ plusButtonShortcut: "ce-toolbar__plus-shortcut",
+ settingsToggler: "ce-toolbar__settings-btn",
+ settingsTogglerHidden: "ce-toolbar__settings-btn--hidden"
+ };
+ }
+ /**
+ * Returns the Toolbar opening state
+ *
+ * @returns {boolean}
+ */
+ get opened() {
+ return this.nodes.wrapper.classList.contains(this.CSS.toolbarOpened);
+ }
+ /**
+ * Public interface for accessing the Toolbox
+ */
+ get toolbox() {
+ var e;
+ return {
+ opened: (e = this.toolboxInstance) == null ? void 0 : e.opened,
+ close: () => {
+ var t;
+ (t = this.toolboxInstance) == null || t.close();
+ },
+ open: () => {
+ if (this.toolboxInstance === null) {
+ S("toolbox.open() called before initialization is finished", "warn");
+ return;
+ }
+ this.Editor.BlockManager.currentBlock = this.hoveredBlock, this.toolboxInstance.open();
+ },
+ toggle: () => {
+ if (this.toolboxInstance === null) {
+ S("toolbox.toggle() called before initialization is finished", "warn");
+ return;
+ }
+ this.toolboxInstance.toggle();
+ },
+ hasFocus: () => {
+ var t;
+ return (t = this.toolboxInstance) == null ? void 0 : t.hasFocus();
+ }
+ };
+ }
+ /**
+ * Block actions appearance manipulations
+ */
+ get blockActions() {
+ return {
+ hide: () => {
+ this.nodes.actions.classList.remove(this.CSS.actionsOpened);
+ },
+ show: () => {
+ this.nodes.actions.classList.add(this.CSS.actionsOpened);
+ }
+ };
+ }
+ /**
+ * Methods for working with Block Tunes toggler
+ */
+ get blockTunesToggler() {
+ return {
+ hide: () => this.nodes.settingsToggler.classList.add(this.CSS.settingsTogglerHidden),
+ show: () => this.nodes.settingsToggler.classList.remove(this.CSS.settingsTogglerHidden)
+ };
+ }
+ /**
+ * Toggles read-only mode
+ *
+ * @param {boolean} readOnlyEnabled - read-only mode
+ */
+ toggleReadOnly(e) {
+ e ? (this.destroy(), this.Editor.BlockSettings.destroy(), this.disableModuleBindings()) : window.requestIdleCallback(() => {
+ this.drawUI(), this.enableModuleBindings();
+ }, { timeout: 2e3 });
+ }
+ /**
+ * Move Toolbar to the passed (or current) Block
+ *
+ * @param block - block to move Toolbar near it
+ */
+ moveAndOpen(e = this.Editor.BlockManager.currentBlock) {
+ if (this.toolboxInstance === null) {
+ S("Can't open Toolbar since Editor initialization is not finished yet", "warn");
+ return;
+ }
+ if (this.toolboxInstance.opened && this.toolboxInstance.close(), this.Editor.BlockSettings.opened && this.Editor.BlockSettings.close(), !e)
+ return;
+ this.hoveredBlock = e;
+ const t = e.holder, { isMobile: o } = this.Editor.UI;
+ let i;
+ const s = 20, r = e.firstInput, a = t.getBoundingClientRect(), l = r !== void 0 ? r.getBoundingClientRect() : null, c = l !== null ? l.top - a.top : null, u = c !== null ? c > s : void 0;
+ if (o)
+ i = t.offsetTop + t.offsetHeight;
+ else if (r === void 0 || u) {
+ const h = parseInt(window.getComputedStyle(e.pluginsContent).paddingTop);
+ i = t.offsetTop + h;
+ } else {
+ const h = li(r), p = parseInt(window.getComputedStyle(this.nodes.plusButton).height, 10), g = 8;
+ i = t.offsetTop + h - p + g + c;
+ }
+ this.nodes.wrapper.style.top = `${Math.floor(i)}px`, this.Editor.BlockManager.blocks.length === 1 && e.isEmpty ? this.blockTunesToggler.hide() : this.blockTunesToggler.show(), this.open();
+ }
+ /**
+ * Close the Toolbar
+ */
+ close() {
+ var e, t;
+ this.Editor.ReadOnly.isEnabled || ((e = this.nodes.wrapper) == null || e.classList.remove(this.CSS.toolbarOpened), this.blockActions.hide(), (t = this.toolboxInstance) == null || t.close(), this.Editor.BlockSettings.close(), this.reset());
+ }
+ /**
+ * Reset the Toolbar position to prevent DOM height growth, for example after blocks deletion
+ */
+ reset() {
+ this.nodes.wrapper.style.top = "unset";
+ }
+ /**
+ * Open Toolbar with Plus Button and Actions
+ *
+ * @param {boolean} withBlockActions - by default, Toolbar opens with Block Actions.
+ * This flag allows to open Toolbar without Actions.
+ */
+ open(e = !0) {
+ this.nodes.wrapper.classList.add(this.CSS.toolbarOpened), e ? this.blockActions.show() : this.blockActions.hide();
+ }
+ /**
+ * Draws Toolbar elements
+ */
+ async make() {
+ this.nodes.wrapper = d.make("div", this.CSS.toolbar), ["content", "actions"].forEach((s) => {
+ this.nodes[s] = d.make("div", this.CSS[s]);
+ }), d.append(this.nodes.wrapper, this.nodes.content), d.append(this.nodes.content, this.nodes.actions), this.nodes.plusButton = d.make("div", this.CSS.plusButton, {
+ innerHTML: ts
+ }), d.append(this.nodes.actions, this.nodes.plusButton), this.readOnlyMutableListeners.on(this.nodes.plusButton, "click", () => {
+ $e(!0), this.plusButtonClicked();
+ }, !1);
+ const e = d.make("div");
+ e.appendChild(document.createTextNode(z.ui(K.ui.toolbar.toolbox, "Add"))), e.appendChild(d.make("div", this.CSS.plusButtonShortcut, {
+ textContent: "/"
+ })), ze(this.nodes.plusButton, e, {
+ hidingDelay: 400
+ }), this.nodes.settingsToggler = d.make("span", this.CSS.settingsToggler, {
+ innerHTML: es
+ }), d.append(this.nodes.actions, this.nodes.settingsToggler);
+ const t = d.make("div"), o = d.text(z.ui(K.ui.blockTunes.toggler, "Click to tune")), i = await xs("Slash", "/");
+ t.appendChild(o), t.appendChild(d.make("div", this.CSS.plusButtonShortcut, {
+ textContent: vt(`CMD + ${i}`)
+ })), ze(this.nodes.settingsToggler, t, {
+ hidingDelay: 400
+ }), d.append(this.nodes.actions, this.makeToolbox()), d.append(this.nodes.actions, this.Editor.BlockSettings.getElement()), d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);
+ }
+ /**
+ * Creates the Toolbox instance and return it's rendered element
+ */
+ makeToolbox() {
+ return this.toolboxInstance = new Es({
+ api: this.Editor.API.methods,
+ tools: this.Editor.Tools.blockTools,
+ i18nLabels: {
+ filter: z.ui(K.ui.popover, "Filter"),
+ nothingFound: z.ui(K.ui.popover, "Nothing found")
+ }
+ }), this.toolboxInstance.on(Le.Opened, () => {
+ this.Editor.UI.nodes.wrapper.classList.add(this.CSS.openedToolboxHolderModifier);
+ }), this.toolboxInstance.on(Le.Closed, () => {
+ this.Editor.UI.nodes.wrapper.classList.remove(this.CSS.openedToolboxHolderModifier);
+ }), this.toolboxInstance.on(Le.BlockAdded, ({ block: e }) => {
+ const { BlockManager: t, Caret: o } = this.Editor, i = t.getBlockById(e.id);
+ i.inputs.length === 0 && (i === t.lastBlock ? (t.insertAtEnd(), o.setToBlock(t.lastBlock)) : o.setToBlock(t.nextBlock));
+ }), this.toolboxInstance.getElement();
+ }
+ /**
+ * Handler for Plus Button
+ */
+ plusButtonClicked() {
+ var e;
+ this.Editor.BlockManager.currentBlock = this.hoveredBlock, (e = this.toolboxInstance) == null || e.toggle();
+ }
+ /**
+ * Enable bindings
+ */
+ enableModuleBindings() {
+ this.readOnlyMutableListeners.on(this.nodes.settingsToggler, "mousedown", (e) => {
+ var t;
+ e.stopPropagation(), this.settingsTogglerClicked(), (t = this.toolboxInstance) != null && t.opened && this.toolboxInstance.close(), $e(!0);
+ }, !0), be() || this.eventsDispatcher.on(ln, (e) => {
+ var t;
+ this.Editor.BlockSettings.opened || (t = this.toolboxInstance) != null && t.opened || this.moveAndOpen(e.block);
+ });
+ }
+ /**
+ * Disable bindings
+ */
+ disableModuleBindings() {
+ this.readOnlyMutableListeners.clearAll();
+ }
+ /**
+ * Clicks on the Block Settings toggler
+ */
+ settingsTogglerClicked() {
+ this.Editor.BlockManager.currentBlock = this.hoveredBlock, this.Editor.BlockSettings.opened ? this.Editor.BlockSettings.close() : this.Editor.BlockSettings.open(this.hoveredBlock);
+ }
+ /**
+ * Draws Toolbar UI
+ *
+ * Toolbar contains BlockSettings and Toolbox.
+ * That's why at first we draw its components and then Toolbar itself
+ *
+ * Steps:
+ * - Make Toolbar dependent components like BlockSettings, Toolbox and so on
+ * - Make itself and append dependent nodes to itself
+ *
+ */
+ drawUI() {
+ this.Editor.BlockSettings.make(), this.make();
+ }
+ /**
+ * Removes all created and saved HTMLElements
+ * It is used in Read-Only mode
+ */
+ destroy() {
+ this.removeAllNodes(), this.toolboxInstance && this.toolboxInstance.destroy();
+ }
+}
+var ae = /* @__PURE__ */ ((n) => (n[n.Block = 0] = "Block", n[n.Inline = 1] = "Inline", n[n.Tune = 2] = "Tune", n))(ae || {}), Pe = /* @__PURE__ */ ((n) => (n.Shortcut = "shortcut", n.Toolbox = "toolbox", n.EnabledInlineTools = "inlineToolbar", n.EnabledBlockTunes = "tunes", n.Config = "config", n))(Pe || {}), cn = /* @__PURE__ */ ((n) => (n.Shortcut = "shortcut", n.SanitizeConfig = "sanitize", n))(cn || {}), pe = /* @__PURE__ */ ((n) => (n.IsEnabledLineBreaks = "enableLineBreaks", n.Toolbox = "toolbox", n.ConversionConfig = "conversionConfig", n.IsReadOnlySupported = "isReadOnlySupported", n.PasteConfig = "pasteConfig", n))(pe || {}), We = /* @__PURE__ */ ((n) => (n.IsInline = "isInline", n.Title = "title", n.IsReadOnlySupported = "isReadOnlySupported", n))(We || {}), mt = /* @__PURE__ */ ((n) => (n.IsTune = "isTune", n))(mt || {});
+class Tt {
+ /**
+ * @class
+ * @param {ConstructorOptions} options - Constructor options
+ */
+ constructor({
+ name: e,
+ constructable: t,
+ config: o,
+ api: i,
+ isDefault: s,
+ isInternal: r = !1,
+ defaultPlaceholder: a
+ }) {
+ this.api = i, this.name = e, this.constructable = t, this.config = o, this.isDefault = s, this.isInternal = r, this.defaultPlaceholder = a;
+ }
+ /**
+ * Returns Tool user configuration
+ */
+ get settings() {
+ const e = this.config.config || {};
+ return this.isDefault && !("placeholder" in e) && this.defaultPlaceholder && (e.placeholder = this.defaultPlaceholder), e;
+ }
+ /**
+ * Calls Tool's reset method
+ */
+ reset() {
+ if (A(this.constructable.reset))
+ return this.constructable.reset();
+ }
+ /**
+ * Calls Tool's prepare method
+ */
+ prepare() {
+ if (A(this.constructable.prepare))
+ return this.constructable.prepare({
+ toolName: this.name,
+ config: this.settings
+ });
+ }
+ /**
+ * Returns shortcut for Tool (internal or specified by user)
+ */
+ get shortcut() {
+ const e = this.constructable.shortcut;
+ return this.config.shortcut || e;
+ }
+ /**
+ * Returns Tool's sanitizer configuration
+ */
+ get sanitizeConfig() {
+ return this.constructable.sanitize || {};
+ }
+ /**
+ * Returns true if Tools is inline
+ */
+ isInline() {
+ return this.type === ae.Inline;
+ }
+ /**
+ * Returns true if Tools is block
+ */
+ isBlock() {
+ return this.type === ae.Block;
+ }
+ /**
+ * Returns true if Tools is tune
+ */
+ isTune() {
+ return this.type === ae.Tune;
+ }
+}
+class Cs extends E {
+ /**
+ * @param moduleConfiguration - Module Configuration
+ * @param moduleConfiguration.config - Editor's config
+ * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher
+ */
+ constructor({ config: e, eventsDispatcher: t }) {
+ super({
+ config: e,
+ eventsDispatcher: t
+ }), this.CSS = {
+ inlineToolbar: "ce-inline-toolbar"
+ }, this.opened = !1, this.popover = null, this.toolbarVerticalMargin = be() ? 20 : 6, this.tools = /* @__PURE__ */ new Map(), window.requestIdleCallback(() => {
+ this.make();
+ }, { timeout: 2e3 });
+ }
+ /**
+ * Moving / appearance
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+ /**
+ * Shows Inline Toolbar if something is selected
+ *
+ * @param [needToClose] - pass true to close toolbar if it is not allowed.
+ * Avoid to use it just for closing IT, better call .close() clearly.
+ */
+ async tryToShow(e = !1) {
+ e && this.close(), this.allowedToShow() && (await this.open(), this.Editor.Toolbar.close());
+ }
+ /**
+ * Hides Inline Toolbar
+ */
+ close() {
+ var e, t;
+ if (this.opened) {
+ for (const [o, i] of this.tools) {
+ const s = this.getToolShortcut(o.name);
+ s !== void 0 && ge.remove(this.Editor.UI.nodes.redactor, s), A(i.clear) && i.clear();
+ }
+ this.tools = /* @__PURE__ */ new Map(), this.reset(), this.opened = !1, (e = this.popover) == null || e.hide(), (t = this.popover) == null || t.destroy(), this.popover = null;
+ }
+ }
+ /**
+ * Check if node is contained by Inline Toolbar
+ *
+ * @param {Node} node — node to check
+ */
+ containsNode(e) {
+ return this.nodes.wrapper === void 0 ? !1 : this.nodes.wrapper.contains(e);
+ }
+ /**
+ * Removes UI and its components
+ */
+ destroy() {
+ var e;
+ this.removeAllNodes(), (e = this.popover) == null || e.destroy(), this.popover = null;
+ }
+ /**
+ * Making DOM
+ */
+ make() {
+ this.nodes.wrapper = d.make("div", [
+ this.CSS.inlineToolbar,
+ ...this.isRtl ? [this.Editor.UI.CSS.editorRtlFix] : []
+ ]), d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);
+ }
+ /**
+ * Shows Inline Toolbar
+ */
+ async open() {
+ var t;
+ if (this.opened)
+ return;
+ this.opened = !0, this.popover !== null && this.popover.destroy(), this.createToolsInstances();
+ const e = await this.getPopoverItems();
+ this.popover = new hs({
+ items: e,
+ scopeElement: this.Editor.API.methods.ui.nodes.redactor,
+ messages: {
+ nothingFound: z.ui(K.ui.popover, "Nothing found"),
+ search: z.ui(K.ui.popover, "Filter")
+ }
+ }), this.move(this.popover.size.width), (t = this.nodes.wrapper) == null || t.append(this.popover.getElement()), this.popover.show();
+ }
+ /**
+ * Move Toolbar to the selected text
+ *
+ * @param popoverWidth - width of the toolbar popover
+ */
+ move(e) {
+ const t = b.rect, o = this.Editor.UI.nodes.wrapper.getBoundingClientRect(), i = {
+ x: t.x - o.x,
+ y: t.y + t.height - // + window.scrollY
+ o.top + this.toolbarVerticalMargin
+ };
+ i.x + e + o.x > this.Editor.UI.contentRect.right && (i.x = this.Editor.UI.contentRect.right - e - o.x), this.nodes.wrapper.style.left = Math.floor(i.x) + "px", this.nodes.wrapper.style.top = Math.floor(i.y) + "px";
+ }
+ /**
+ * Clear orientation classes and reset position
+ */
+ reset() {
+ this.nodes.wrapper.style.left = "0", this.nodes.wrapper.style.top = "0";
+ }
+ /**
+ * Need to show Inline Toolbar or not
+ */
+ allowedToShow() {
+ const e = ["IMG", "INPUT"], t = b.get(), o = b.text;
+ if (!t || !t.anchorNode || t.isCollapsed || o.length < 1)
+ return !1;
+ const i = d.isElement(t.anchorNode) ? t.anchorNode : t.anchorNode.parentElement;
+ if (i === null || t !== null && e.includes(i.tagName))
+ return !1;
+ const s = this.Editor.BlockManager.getBlock(t.anchorNode);
+ return !s || this.getTools().some((c) => s.tool.inlineTools.has(c.name)) === !1 ? !1 : i.closest("[contenteditable]") !== null;
+ }
+ /**
+ * Working with Tools
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+ /**
+ * Returns tools that are available for current block
+ *
+ * Used to check if Inline Toolbar could be shown
+ * and to render tools in the Inline Toolbar
+ */
+ getTools() {
+ const e = this.Editor.BlockManager.currentBlock;
+ return e ? Array.from(e.tool.inlineTools.values()).filter((o) => !(this.Editor.ReadOnly.isEnabled && o.isReadOnlySupported !== !0)) : [];
+ }
+ /**
+ * Constructs tools instances and saves them to this.tools
+ */
+ createToolsInstances() {
+ this.tools = /* @__PURE__ */ new Map(), this.getTools().forEach((t) => {
+ const o = t.create();
+ this.tools.set(t, o);
+ });
+ }
+ /**
+ * Returns Popover Items for tools segregated by their appearance type: regular items and custom html elements.
+ */
+ async getPopoverItems() {
+ const e = [];
+ let t = 0;
+ for (const [o, i] of this.tools) {
+ const s = await i.render(), r = this.getToolShortcut(o.name);
+ if (r !== void 0)
+ try {
+ this.enableShortcuts(o.name, r);
+ } catch {
+ }
+ const a = r !== void 0 ? vt(r) : void 0, l = z.t(
+ K.toolNames,
+ o.title || je(o.name)
+ );
+ [s].flat().forEach((c) => {
+ var h, p;
+ const u = {
+ name: o.name,
+ onActivate: () => {
+ this.toolClicked(i);
+ },
+ hint: {
+ title: l,
+ description: a
+ }
+ };
+ if (d.isElement(c)) {
+ const g = {
+ ...u,
+ element: c,
+ type: _.Html
+ };
+ if (A(i.renderActions)) {
+ const f = i.renderActions();
+ g.children = {
+ isOpen: (h = i.checkState) == null ? void 0 : h.call(i, b.get()),
+ /** Disable keyboard navigation in actions, as it might conflict with enter press handling */
+ isFlippable: !1,
+ items: [
+ {
+ type: _.Html,
+ element: f
+ }
+ ]
+ };
+ } else
+ (p = i.checkState) == null || p.call(i, b.get());
+ e.push(g);
+ } else if (c.type === _.Html)
+ e.push({
+ ...u,
+ ...c,
+ type: _.Html
+ });
+ else if (c.type === _.Separator)
+ e.push({
+ type: _.Separator
+ });
+ else {
+ const g = {
+ ...u,
+ ...c,
+ type: _.Default
+ };
+ "children" in g && t !== 0 && e.push({
+ type: _.Separator
+ }), e.push(g), "children" in g && t < this.tools.size - 1 && e.push({
+ type: _.Separator
+ });
+ }
+ }), t++;
+ }
+ return e;
+ }
+ /**
+ * Get shortcut name for tool
+ *
+ * @param toolName — Tool name
+ */
+ getToolShortcut(e) {
+ const { Tools: t } = this.Editor, o = t.inlineTools.get(e), i = t.internal.inlineTools;
+ return Array.from(i.keys()).includes(e) ? this.inlineTools[e][cn.Shortcut] : o == null ? void 0 : o.shortcut;
+ }
+ /**
+ * Enable Tool shortcut with Editor Shortcuts Module
+ *
+ * @param toolName - tool name
+ * @param shortcut - shortcut according to the ShortcutData Module format
+ */
+ enableShortcuts(e, t) {
+ ge.add({
+ name: t,
+ handler: (o) => {
+ var s;
+ const { currentBlock: i } = this.Editor.BlockManager;
+ i && i.tool.enabledInlineTools && (o.preventDefault(), (s = this.popover) == null || s.activateItemByName(e));
+ },
+ /**
+ * We need to bind shortcut to the document to make it work in read-only mode
+ */
+ on: document
+ });
+ }
+ /**
+ * Inline Tool button clicks
+ *
+ * @param tool - Tool's instance
+ */
+ toolClicked(e) {
+ var o;
+ const t = b.range;
+ (o = e.surround) == null || o.call(e, t), this.checkToolsState();
+ }
+ /**
+ * Check Tools` state by selection
+ */
+ checkToolsState() {
+ var e;
+ (e = this.tools) == null || e.forEach((t) => {
+ var o;
+ (o = t.checkState) == null || o.call(t, b.get());
+ });
+ }
+ /**
+ * Get inline tools tools
+ * Tools that has isInline is true
+ */
+ get inlineTools() {
+ const e = {};
+ return Array.from(this.Editor.Tools.inlineTools.entries()).forEach(([t, o]) => {
+ e[t] = o.create();
+ }), e;
+ }
+}
+function dn() {
+ const n = window.getSelection();
+ if (n === null)
+ return [null, 0];
+ let e = n.focusNode, t = n.focusOffset;
+ return e === null ? [null, 0] : (e.nodeType !== Node.TEXT_NODE && e.childNodes.length > 0 && (e.childNodes[t] ? (e = e.childNodes[t], t = 0) : (e = e.childNodes[t - 1], t = e.textContent.length)), [e, t]);
+}
+function un(n, e, t, o) {
+ const i = document.createRange();
+ o === "left" ? (i.setStart(n, 0), i.setEnd(e, t)) : (i.setStart(e, t), i.setEnd(n, n.childNodes.length));
+ const s = i.cloneContents(), r = document.createElement("div");
+ r.appendChild(s);
+ const a = r.textContent || "";
+ return ai(a);
+}
+function Ne(n) {
+ const e = d.getDeepestNode(n);
+ if (e === null || d.isEmpty(n))
+ return !0;
+ if (d.isNativeInput(e))
+ return e.selectionEnd === 0;
+ if (d.isEmpty(n))
+ return !0;
+ const [t, o] = dn();
+ return t === null ? !1 : un(n, t, o, "left");
+}
+function Re(n) {
+ const e = d.getDeepestNode(n, !0);
+ if (e === null)
+ return !0;
+ if (d.isNativeInput(e))
+ return e.selectionEnd === e.value.length;
+ const [t, o] = dn();
+ return t === null ? !1 : un(n, t, o, "right");
+}
+var hn = {}, St = {}, Xe = {}, de = {}, It = {}, Ot = {};
+Object.defineProperty(Ot, "__esModule", { value: !0 });
+Ot.allInputsSelector = Ts;
+function Ts() {
+ var n = ["text", "password", "email", "number", "search", "tel", "url"];
+ return "[contenteditable=true], textarea, input:not([type]), " + n.map(function(e) {
+ return 'input[type="'.concat(e, '"]');
+ }).join(", ");
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.allInputsSelector = void 0;
+ var e = Ot;
+ Object.defineProperty(n, "allInputsSelector", { enumerable: !0, get: function() {
+ return e.allInputsSelector;
+ } });
+})(It);
+var ue = {}, _t = {};
+Object.defineProperty(_t, "__esModule", { value: !0 });
+_t.isNativeInput = Ss;
+function Ss(n) {
+ var e = [
+ "INPUT",
+ "TEXTAREA"
+ ];
+ return n && n.tagName ? e.includes(n.tagName) : !1;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isNativeInput = void 0;
+ var e = _t;
+ Object.defineProperty(n, "isNativeInput", { enumerable: !0, get: function() {
+ return e.isNativeInput;
+ } });
+})(ue);
+var pn = {}, Mt = {};
+Object.defineProperty(Mt, "__esModule", { value: !0 });
+Mt.append = Is;
+function Is(n, e) {
+ Array.isArray(e) ? e.forEach(function(t) {
+ n.appendChild(t);
+ }) : n.appendChild(e);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.append = void 0;
+ var e = Mt;
+ Object.defineProperty(n, "append", { enumerable: !0, get: function() {
+ return e.append;
+ } });
+})(pn);
+var At = {}, Lt = {};
+Object.defineProperty(Lt, "__esModule", { value: !0 });
+Lt.blockElements = Os;
+function Os() {
+ return [
+ "address",
+ "article",
+ "aside",
+ "blockquote",
+ "canvas",
+ "div",
+ "dl",
+ "dt",
+ "fieldset",
+ "figcaption",
+ "figure",
+ "footer",
+ "form",
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6",
+ "header",
+ "hgroup",
+ "hr",
+ "li",
+ "main",
+ "nav",
+ "noscript",
+ "ol",
+ "output",
+ "p",
+ "pre",
+ "ruby",
+ "section",
+ "table",
+ "tbody",
+ "thead",
+ "tr",
+ "tfoot",
+ "ul",
+ "video"
+ ];
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.blockElements = void 0;
+ var e = Lt;
+ Object.defineProperty(n, "blockElements", { enumerable: !0, get: function() {
+ return e.blockElements;
+ } });
+})(At);
+var fn = {}, Pt = {};
+Object.defineProperty(Pt, "__esModule", { value: !0 });
+Pt.calculateBaseline = _s;
+function _s(n) {
+ var e = window.getComputedStyle(n), t = parseFloat(e.fontSize), o = parseFloat(e.lineHeight) || t * 1.2, i = parseFloat(e.paddingTop), s = parseFloat(e.borderTopWidth), r = parseFloat(e.marginTop), a = t * 0.8, l = (o - t) / 2, c = r + s + i + l + a;
+ return c;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.calculateBaseline = void 0;
+ var e = Pt;
+ Object.defineProperty(n, "calculateBaseline", { enumerable: !0, get: function() {
+ return e.calculateBaseline;
+ } });
+})(fn);
+var gn = {}, Nt = {}, Rt = {}, Dt = {};
+Object.defineProperty(Dt, "__esModule", { value: !0 });
+Dt.isContentEditable = Ms;
+function Ms(n) {
+ return n.contentEditable === "true";
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isContentEditable = void 0;
+ var e = Dt;
+ Object.defineProperty(n, "isContentEditable", { enumerable: !0, get: function() {
+ return e.isContentEditable;
+ } });
+})(Rt);
+Object.defineProperty(Nt, "__esModule", { value: !0 });
+Nt.canSetCaret = Ps;
+var As = ue, Ls = Rt;
+function Ps(n) {
+ var e = !0;
+ if ((0, As.isNativeInput)(n))
+ switch (n.type) {
+ case "file":
+ case "checkbox":
+ case "radio":
+ case "hidden":
+ case "submit":
+ case "button":
+ case "image":
+ case "reset":
+ e = !1;
+ break;
+ }
+ else
+ e = (0, Ls.isContentEditable)(n);
+ return e;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.canSetCaret = void 0;
+ var e = Nt;
+ Object.defineProperty(n, "canSetCaret", { enumerable: !0, get: function() {
+ return e.canSetCaret;
+ } });
+})(gn);
+var Ve = {}, Ft = {};
+function Ns(n, e, t) {
+ const o = t.value !== void 0 ? "value" : "get", i = t[o], s = `#${e}Cache`;
+ if (t[o] = function(...r) {
+ return this[s] === void 0 && (this[s] = i.apply(this, r)), this[s];
+ }, o === "get" && t.set) {
+ const r = t.set;
+ t.set = function(a) {
+ delete n[s], r.apply(this, a);
+ };
+ }
+ return t;
+}
+function mn() {
+ const n = {
+ win: !1,
+ mac: !1,
+ x11: !1,
+ linux: !1
+ }, e = Object.keys(n).find((t) => window.navigator.appVersion.toLowerCase().indexOf(t) !== -1);
+ return e !== void 0 && (n[e] = !0), n;
+}
+function jt(n) {
+ return n != null && n !== "" && (typeof n != "object" || Object.keys(n).length > 0);
+}
+function Rs(n) {
+ return !jt(n);
+}
+const Ds = () => typeof window < "u" && window.navigator !== null && jt(window.navigator.platform) && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === "MacIntel" && window.navigator.maxTouchPoints > 1);
+function Fs(n) {
+ const e = mn();
+ return n = n.replace(/shift/gi, "⇧").replace(/backspace/gi, "⌫").replace(/enter/gi, "⏎").replace(/up/gi, "↑").replace(/left/gi, "→").replace(/down/gi, "↓").replace(/right/gi, "←").replace(/escape/gi, "⎋").replace(/insert/gi, "Ins").replace(/delete/gi, "␡").replace(/\+/gi, "+"), e.mac ? n = n.replace(/ctrl|cmd/gi, "⌘").replace(/alt/gi, "⌥") : n = n.replace(/cmd/gi, "Ctrl").replace(/windows/gi, "WIN"), n;
+}
+function js(n) {
+ return n[0].toUpperCase() + n.slice(1);
+}
+function Hs(n) {
+ const e = document.createElement("div");
+ e.style.position = "absolute", e.style.left = "-999px", e.style.bottom = "-999px", e.innerHTML = n, document.body.appendChild(e);
+ const t = window.getSelection(), o = document.createRange();
+ if (o.selectNode(e), t === null)
+ throw new Error("Cannot copy text to clipboard");
+ t.removeAllRanges(), t.addRange(o), document.execCommand("copy"), document.body.removeChild(e);
+}
+function $s(n, e, t) {
+ let o;
+ return (...i) => {
+ const s = this, r = () => {
+ o = void 0, t !== !0 && n.apply(s, i);
+ }, a = t === !0 && o !== void 0;
+ window.clearTimeout(o), o = window.setTimeout(r, e), a && n.apply(s, i);
+ };
+}
+function oe(n) {
+ return Object.prototype.toString.call(n).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
+}
+function zs(n) {
+ return oe(n) === "boolean";
+}
+function bn(n) {
+ return oe(n) === "function" || oe(n) === "asyncfunction";
+}
+function Us(n) {
+ return bn(n) && /^\s*class\s+/.test(n.toString());
+}
+function Ws(n) {
+ return oe(n) === "number";
+}
+function De(n) {
+ return oe(n) === "object";
+}
+function Ys(n) {
+ return Promise.resolve(n) === n;
+}
+function Ks(n) {
+ return oe(n) === "string";
+}
+function Xs(n) {
+ return oe(n) === "undefined";
+}
+function bt(n, ...e) {
+ if (!e.length)
+ return n;
+ const t = e.shift();
+ if (De(n) && De(t))
+ for (const o in t)
+ De(t[o]) ? (n[o] === void 0 && Object.assign(n, { [o]: {} }), bt(n[o], t[o])) : Object.assign(n, { [o]: t[o] });
+ return bt(n, ...e);
+}
+function Vs(n, e, t) {
+ const o = `«${e}» is deprecated and will be removed in the next major release. Please use the «${t}» instead.`;
+ n && console.warn(o);
+}
+function qs(n) {
+ try {
+ return new URL(n).href;
+ } catch {
+ }
+ return n.substring(0, 2) === "//" ? window.location.protocol + n : window.location.origin + n;
+}
+function Zs(n) {
+ return n > 47 && n < 58 || n === 32 || n === 13 || n === 229 || n > 64 && n < 91 || n > 95 && n < 112 || n > 185 && n < 193 || n > 218 && n < 223;
+}
+const Gs = {
+ BACKSPACE: 8,
+ TAB: 9,
+ ENTER: 13,
+ SHIFT: 16,
+ CTRL: 17,
+ ALT: 18,
+ ESC: 27,
+ SPACE: 32,
+ LEFT: 37,
+ UP: 38,
+ DOWN: 40,
+ RIGHT: 39,
+ DELETE: 46,
+ META: 91,
+ SLASH: 191
+}, Qs = {
+ LEFT: 0,
+ WHEEL: 1,
+ RIGHT: 2,
+ BACKWARD: 3,
+ FORWARD: 4
+};
+let Js = class {
+ constructor() {
+ this.completed = Promise.resolve();
+ }
+ /**
+ * Add new promise to queue
+ * @param operation - promise should be added to queue
+ */
+ add(e) {
+ return new Promise((t, o) => {
+ this.completed = this.completed.then(e).then(t).catch(o);
+ });
+ }
+};
+function er(n, e, t = void 0) {
+ let o, i, s, r = null, a = 0;
+ t || (t = {});
+ const l = function() {
+ a = t.leading === !1 ? 0 : Date.now(), r = null, s = n.apply(o, i), r === null && (o = i = null);
+ };
+ return function() {
+ const c = Date.now();
+ !a && t.leading === !1 && (a = c);
+ const u = e - (c - a);
+ return o = this, i = arguments, u <= 0 || u > e ? (r && (clearTimeout(r), r = null), a = c, s = n.apply(o, i), r === null && (o = i = null)) : !r && t.trailing !== !1 && (r = setTimeout(l, u)), s;
+ };
+}
+const tr = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
+ __proto__: null,
+ PromiseQueue: Js,
+ beautifyShortcut: Fs,
+ cacheable: Ns,
+ capitalize: js,
+ copyTextToClipboard: Hs,
+ debounce: $s,
+ deepMerge: bt,
+ deprecationAssert: Vs,
+ getUserOS: mn,
+ getValidUrl: qs,
+ isBoolean: zs,
+ isClass: Us,
+ isEmpty: Rs,
+ isFunction: bn,
+ isIosDevice: Ds,
+ isNumber: Ws,
+ isObject: De,
+ isPrintableKey: Zs,
+ isPromise: Ys,
+ isString: Ks,
+ isUndefined: Xs,
+ keyCodes: Gs,
+ mouseButtons: Qs,
+ notEmpty: jt,
+ throttle: er,
+ typeOf: oe
+}, Symbol.toStringTag, { value: "Module" })), Ht = /* @__PURE__ */ Xn(tr);
+Object.defineProperty(Ft, "__esModule", { value: !0 });
+Ft.containsOnlyInlineElements = ir;
+var or = Ht, nr = At;
+function ir(n) {
+ var e;
+ (0, or.isString)(n) ? (e = document.createElement("div"), e.innerHTML = n) : e = n;
+ var t = function(o) {
+ return !(0, nr.blockElements)().includes(o.tagName.toLowerCase()) && Array.from(o.children).every(t);
+ };
+ return Array.from(e.children).every(t);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.containsOnlyInlineElements = void 0;
+ var e = Ft;
+ Object.defineProperty(n, "containsOnlyInlineElements", { enumerable: !0, get: function() {
+ return e.containsOnlyInlineElements;
+ } });
+})(Ve);
+var vn = {}, $t = {}, qe = {}, zt = {};
+Object.defineProperty(zt, "__esModule", { value: !0 });
+zt.make = sr;
+function sr(n, e, t) {
+ var o;
+ e === void 0 && (e = null), t === void 0 && (t = {});
+ var i = document.createElement(n);
+ if (Array.isArray(e)) {
+ var s = e.filter(function(a) {
+ return a !== void 0;
+ });
+ (o = i.classList).add.apply(o, s);
+ } else
+ e !== null && i.classList.add(e);
+ for (var r in t)
+ Object.prototype.hasOwnProperty.call(t, r) && (i[r] = t[r]);
+ return i;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.make = void 0;
+ var e = zt;
+ Object.defineProperty(n, "make", { enumerable: !0, get: function() {
+ return e.make;
+ } });
+})(qe);
+Object.defineProperty($t, "__esModule", { value: !0 });
+$t.fragmentToString = ar;
+var rr = qe;
+function ar(n) {
+ var e = (0, rr.make)("div");
+ return e.appendChild(n), e.innerHTML;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.fragmentToString = void 0;
+ var e = $t;
+ Object.defineProperty(n, "fragmentToString", { enumerable: !0, get: function() {
+ return e.fragmentToString;
+ } });
+})(vn);
+var kn = {}, Ut = {};
+Object.defineProperty(Ut, "__esModule", { value: !0 });
+Ut.getContentLength = cr;
+var lr = ue;
+function cr(n) {
+ var e, t;
+ return (0, lr.isNativeInput)(n) ? n.value.length : n.nodeType === Node.TEXT_NODE ? n.length : (t = (e = n.textContent) === null || e === void 0 ? void 0 : e.length) !== null && t !== void 0 ? t : 0;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.getContentLength = void 0;
+ var e = Ut;
+ Object.defineProperty(n, "getContentLength", { enumerable: !0, get: function() {
+ return e.getContentLength;
+ } });
+})(kn);
+var Wt = {}, Yt = {}, Io = Ce && Ce.__spreadArray || function(n, e, t) {
+ if (t || arguments.length === 2)
+ for (var o = 0, i = e.length, s; o < i; o++)
+ (s || !(o in e)) && (s || (s = Array.prototype.slice.call(e, 0, o)), s[o] = e[o]);
+ return n.concat(s || Array.prototype.slice.call(e));
+};
+Object.defineProperty(Yt, "__esModule", { value: !0 });
+Yt.getDeepestBlockElements = yn;
+var dr = Ve;
+function yn(n) {
+ return (0, dr.containsOnlyInlineElements)(n) ? [n] : Array.from(n.children).reduce(function(e, t) {
+ return Io(Io([], e, !0), yn(t), !0);
+ }, []);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.getDeepestBlockElements = void 0;
+ var e = Yt;
+ Object.defineProperty(n, "getDeepestBlockElements", { enumerable: !0, get: function() {
+ return e.getDeepestBlockElements;
+ } });
+})(Wt);
+var wn = {}, Kt = {}, Ze = {}, Xt = {};
+Object.defineProperty(Xt, "__esModule", { value: !0 });
+Xt.isLineBreakTag = ur;
+function ur(n) {
+ return [
+ "BR",
+ "WBR"
+ ].includes(n.tagName);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isLineBreakTag = void 0;
+ var e = Xt;
+ Object.defineProperty(n, "isLineBreakTag", { enumerable: !0, get: function() {
+ return e.isLineBreakTag;
+ } });
+})(Ze);
+var Ge = {}, Vt = {};
+Object.defineProperty(Vt, "__esModule", { value: !0 });
+Vt.isSingleTag = hr;
+function hr(n) {
+ return [
+ "AREA",
+ "BASE",
+ "BR",
+ "COL",
+ "COMMAND",
+ "EMBED",
+ "HR",
+ "IMG",
+ "INPUT",
+ "KEYGEN",
+ "LINK",
+ "META",
+ "PARAM",
+ "SOURCE",
+ "TRACK",
+ "WBR"
+ ].includes(n.tagName);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isSingleTag = void 0;
+ var e = Vt;
+ Object.defineProperty(n, "isSingleTag", { enumerable: !0, get: function() {
+ return e.isSingleTag;
+ } });
+})(Ge);
+Object.defineProperty(Kt, "__esModule", { value: !0 });
+Kt.getDeepestNode = En;
+var pr = ue, fr = Ze, gr = Ge;
+function En(n, e) {
+ e === void 0 && (e = !1);
+ var t = e ? "lastChild" : "firstChild", o = e ? "previousSibling" : "nextSibling";
+ if (n.nodeType === Node.ELEMENT_NODE && n[t]) {
+ var i = n[t];
+ if ((0, gr.isSingleTag)(i) && !(0, pr.isNativeInput)(i) && !(0, fr.isLineBreakTag)(i))
+ if (i[o])
+ i = i[o];
+ else if (i.parentNode !== null && i.parentNode[o])
+ i = i.parentNode[o];
+ else
+ return i.parentNode;
+ return En(i, e);
+ }
+ return n;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.getDeepestNode = void 0;
+ var e = Kt;
+ Object.defineProperty(n, "getDeepestNode", { enumerable: !0, get: function() {
+ return e.getDeepestNode;
+ } });
+})(wn);
+var xn = {}, qt = {}, Me = Ce && Ce.__spreadArray || function(n, e, t) {
+ if (t || arguments.length === 2)
+ for (var o = 0, i = e.length, s; o < i; o++)
+ (s || !(o in e)) && (s || (s = Array.prototype.slice.call(e, 0, o)), s[o] = e[o]);
+ return n.concat(s || Array.prototype.slice.call(e));
+};
+Object.defineProperty(qt, "__esModule", { value: !0 });
+qt.findAllInputs = yr;
+var mr = Ve, br = Wt, vr = It, kr = ue;
+function yr(n) {
+ return Array.from(n.querySelectorAll((0, vr.allInputsSelector)())).reduce(function(e, t) {
+ return (0, kr.isNativeInput)(t) || (0, mr.containsOnlyInlineElements)(t) ? Me(Me([], e, !0), [t], !1) : Me(Me([], e, !0), (0, br.getDeepestBlockElements)(t), !0);
+ }, []);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.findAllInputs = void 0;
+ var e = qt;
+ Object.defineProperty(n, "findAllInputs", { enumerable: !0, get: function() {
+ return e.findAllInputs;
+ } });
+})(xn);
+var Bn = {}, Zt = {};
+Object.defineProperty(Zt, "__esModule", { value: !0 });
+Zt.isCollapsedWhitespaces = wr;
+function wr(n) {
+ return !/[^\t\n\r ]/.test(n);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isCollapsedWhitespaces = void 0;
+ var e = Zt;
+ Object.defineProperty(n, "isCollapsedWhitespaces", { enumerable: !0, get: function() {
+ return e.isCollapsedWhitespaces;
+ } });
+})(Bn);
+var Gt = {}, Qt = {};
+Object.defineProperty(Qt, "__esModule", { value: !0 });
+Qt.isElement = xr;
+var Er = Ht;
+function xr(n) {
+ return (0, Er.isNumber)(n) ? !1 : !!n && !!n.nodeType && n.nodeType === Node.ELEMENT_NODE;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isElement = void 0;
+ var e = Qt;
+ Object.defineProperty(n, "isElement", { enumerable: !0, get: function() {
+ return e.isElement;
+ } });
+})(Gt);
+var Cn = {}, Jt = {}, eo = {}, to = {};
+Object.defineProperty(to, "__esModule", { value: !0 });
+to.isLeaf = Br;
+function Br(n) {
+ return n === null ? !1 : n.childNodes.length === 0;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isLeaf = void 0;
+ var e = to;
+ Object.defineProperty(n, "isLeaf", { enumerable: !0, get: function() {
+ return e.isLeaf;
+ } });
+})(eo);
+var oo = {}, no = {};
+Object.defineProperty(no, "__esModule", { value: !0 });
+no.isNodeEmpty = Or;
+var Cr = Ze, Tr = Gt, Sr = ue, Ir = Ge;
+function Or(n, e) {
+ var t = "";
+ return (0, Ir.isSingleTag)(n) && !(0, Cr.isLineBreakTag)(n) ? !1 : ((0, Tr.isElement)(n) && (0, Sr.isNativeInput)(n) ? t = n.value : n.textContent !== null && (t = n.textContent.replace("", "")), e !== void 0 && (t = t.replace(new RegExp(e, "g"), "")), t.trim().length === 0);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isNodeEmpty = void 0;
+ var e = no;
+ Object.defineProperty(n, "isNodeEmpty", { enumerable: !0, get: function() {
+ return e.isNodeEmpty;
+ } });
+})(oo);
+Object.defineProperty(Jt, "__esModule", { value: !0 });
+Jt.isEmpty = Ar;
+var _r = eo, Mr = oo;
+function Ar(n, e) {
+ n.normalize();
+ for (var t = [n]; t.length > 0; ) {
+ var o = t.shift();
+ if (o) {
+ if (n = o, (0, _r.isLeaf)(n) && !(0, Mr.isNodeEmpty)(n, e))
+ return !1;
+ t.push.apply(t, Array.from(n.childNodes));
+ }
+ }
+ return !0;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isEmpty = void 0;
+ var e = Jt;
+ Object.defineProperty(n, "isEmpty", { enumerable: !0, get: function() {
+ return e.isEmpty;
+ } });
+})(Cn);
+var Tn = {}, io = {};
+Object.defineProperty(io, "__esModule", { value: !0 });
+io.isFragment = Pr;
+var Lr = Ht;
+function Pr(n) {
+ return (0, Lr.isNumber)(n) ? !1 : !!n && !!n.nodeType && n.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isFragment = void 0;
+ var e = io;
+ Object.defineProperty(n, "isFragment", { enumerable: !0, get: function() {
+ return e.isFragment;
+ } });
+})(Tn);
+var Sn = {}, so = {};
+Object.defineProperty(so, "__esModule", { value: !0 });
+so.isHTMLString = Rr;
+var Nr = qe;
+function Rr(n) {
+ var e = (0, Nr.make)("div");
+ return e.innerHTML = n, e.childElementCount > 0;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isHTMLString = void 0;
+ var e = so;
+ Object.defineProperty(n, "isHTMLString", { enumerable: !0, get: function() {
+ return e.isHTMLString;
+ } });
+})(Sn);
+var In = {}, ro = {};
+Object.defineProperty(ro, "__esModule", { value: !0 });
+ro.offset = Dr;
+function Dr(n) {
+ var e = n.getBoundingClientRect(), t = window.pageXOffset || document.documentElement.scrollLeft, o = window.pageYOffset || document.documentElement.scrollTop, i = e.top + o, s = e.left + t;
+ return {
+ top: i,
+ left: s,
+ bottom: i + e.height,
+ right: s + e.width
+ };
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.offset = void 0;
+ var e = ro;
+ Object.defineProperty(n, "offset", { enumerable: !0, get: function() {
+ return e.offset;
+ } });
+})(In);
+var On = {}, ao = {};
+Object.defineProperty(ao, "__esModule", { value: !0 });
+ao.prepend = Fr;
+function Fr(n, e) {
+ Array.isArray(e) ? (e = e.reverse(), e.forEach(function(t) {
+ return n.prepend(t);
+ })) : n.prepend(e);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.prepend = void 0;
+ var e = ao;
+ Object.defineProperty(n, "prepend", { enumerable: !0, get: function() {
+ return e.prepend;
+ } });
+})(On);
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.prepend = n.offset = n.make = n.isLineBreakTag = n.isSingleTag = n.isNodeEmpty = n.isLeaf = n.isHTMLString = n.isFragment = n.isEmpty = n.isElement = n.isContentEditable = n.isCollapsedWhitespaces = n.findAllInputs = n.isNativeInput = n.allInputsSelector = n.getDeepestNode = n.getDeepestBlockElements = n.getContentLength = n.fragmentToString = n.containsOnlyInlineElements = n.canSetCaret = n.calculateBaseline = n.blockElements = n.append = void 0;
+ var e = It;
+ Object.defineProperty(n, "allInputsSelector", { enumerable: !0, get: function() {
+ return e.allInputsSelector;
+ } });
+ var t = ue;
+ Object.defineProperty(n, "isNativeInput", { enumerable: !0, get: function() {
+ return t.isNativeInput;
+ } });
+ var o = pn;
+ Object.defineProperty(n, "append", { enumerable: !0, get: function() {
+ return o.append;
+ } });
+ var i = At;
+ Object.defineProperty(n, "blockElements", { enumerable: !0, get: function() {
+ return i.blockElements;
+ } });
+ var s = fn;
+ Object.defineProperty(n, "calculateBaseline", { enumerable: !0, get: function() {
+ return s.calculateBaseline;
+ } });
+ var r = gn;
+ Object.defineProperty(n, "canSetCaret", { enumerable: !0, get: function() {
+ return r.canSetCaret;
+ } });
+ var a = Ve;
+ Object.defineProperty(n, "containsOnlyInlineElements", { enumerable: !0, get: function() {
+ return a.containsOnlyInlineElements;
+ } });
+ var l = vn;
+ Object.defineProperty(n, "fragmentToString", { enumerable: !0, get: function() {
+ return l.fragmentToString;
+ } });
+ var c = kn;
+ Object.defineProperty(n, "getContentLength", { enumerable: !0, get: function() {
+ return c.getContentLength;
+ } });
+ var u = Wt;
+ Object.defineProperty(n, "getDeepestBlockElements", { enumerable: !0, get: function() {
+ return u.getDeepestBlockElements;
+ } });
+ var h = wn;
+ Object.defineProperty(n, "getDeepestNode", { enumerable: !0, get: function() {
+ return h.getDeepestNode;
+ } });
+ var p = xn;
+ Object.defineProperty(n, "findAllInputs", { enumerable: !0, get: function() {
+ return p.findAllInputs;
+ } });
+ var g = Bn;
+ Object.defineProperty(n, "isCollapsedWhitespaces", { enumerable: !0, get: function() {
+ return g.isCollapsedWhitespaces;
+ } });
+ var f = Rt;
+ Object.defineProperty(n, "isContentEditable", { enumerable: !0, get: function() {
+ return f.isContentEditable;
+ } });
+ var v = Gt;
+ Object.defineProperty(n, "isElement", { enumerable: !0, get: function() {
+ return v.isElement;
+ } });
+ var O = Cn;
+ Object.defineProperty(n, "isEmpty", { enumerable: !0, get: function() {
+ return O.isEmpty;
+ } });
+ var T = Tn;
+ Object.defineProperty(n, "isFragment", { enumerable: !0, get: function() {
+ return T.isFragment;
+ } });
+ var M = Sn;
+ Object.defineProperty(n, "isHTMLString", { enumerable: !0, get: function() {
+ return M.isHTMLString;
+ } });
+ var q = eo;
+ Object.defineProperty(n, "isLeaf", { enumerable: !0, get: function() {
+ return q.isLeaf;
+ } });
+ var F = oo;
+ Object.defineProperty(n, "isNodeEmpty", { enumerable: !0, get: function() {
+ return F.isNodeEmpty;
+ } });
+ var H = Ze;
+ Object.defineProperty(n, "isLineBreakTag", { enumerable: !0, get: function() {
+ return H.isLineBreakTag;
+ } });
+ var Q = Ge;
+ Object.defineProperty(n, "isSingleTag", { enumerable: !0, get: function() {
+ return Q.isSingleTag;
+ } });
+ var ie = qe;
+ Object.defineProperty(n, "make", { enumerable: !0, get: function() {
+ return ie.make;
+ } });
+ var k = In;
+ Object.defineProperty(n, "offset", { enumerable: !0, get: function() {
+ return k.offset;
+ } });
+ var m = On;
+ Object.defineProperty(n, "prepend", { enumerable: !0, get: function() {
+ return m.prepend;
+ } });
+})(de);
+var Qe = {};
+Object.defineProperty(Qe, "__esModule", { value: !0 });
+Qe.getContenteditableSlice = Hr;
+var jr = de;
+function Hr(n, e, t, o, i) {
+ var s;
+ i === void 0 && (i = !1);
+ var r = document.createRange();
+ if (o === "left" ? (r.setStart(n, 0), r.setEnd(e, t)) : (r.setStart(e, t), r.setEnd(n, n.childNodes.length)), i === !0) {
+ var a = r.extractContents();
+ return (0, jr.fragmentToString)(a);
+ }
+ var l = r.cloneContents(), c = document.createElement("div");
+ c.appendChild(l);
+ var u = (s = c.textContent) !== null && s !== void 0 ? s : "";
+ return u;
+}
+Object.defineProperty(Xe, "__esModule", { value: !0 });
+Xe.checkContenteditableSliceForEmptiness = Ur;
+var $r = de, zr = Qe;
+function Ur(n, e, t, o) {
+ var i = (0, zr.getContenteditableSlice)(n, e, t, o);
+ return (0, $r.isCollapsedWhitespaces)(i);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.checkContenteditableSliceForEmptiness = void 0;
+ var e = Xe;
+ Object.defineProperty(n, "checkContenteditableSliceForEmptiness", { enumerable: !0, get: function() {
+ return e.checkContenteditableSliceForEmptiness;
+ } });
+})(St);
+var _n = {};
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.getContenteditableSlice = void 0;
+ var e = Qe;
+ Object.defineProperty(n, "getContenteditableSlice", { enumerable: !0, get: function() {
+ return e.getContenteditableSlice;
+ } });
+})(_n);
+var Mn = {}, lo = {};
+Object.defineProperty(lo, "__esModule", { value: !0 });
+lo.focus = Yr;
+var Wr = de;
+function Yr(n, e) {
+ var t, o;
+ if (e === void 0 && (e = !0), (0, Wr.isNativeInput)(n)) {
+ n.focus();
+ var i = e ? 0 : n.value.length;
+ n.setSelectionRange(i, i);
+ } else {
+ var s = document.createRange(), r = window.getSelection();
+ if (!r)
+ return;
+ var a = function(p) {
+ var g = document.createTextNode("");
+ p.appendChild(g), s.setStart(g, 0), s.setEnd(g, 0);
+ }, l = function(p) {
+ return p != null;
+ }, c = n.childNodes, u = e ? c[0] : c[c.length - 1];
+ if (l(u)) {
+ for (; l(u) && u.nodeType !== Node.TEXT_NODE; )
+ u = e ? u.firstChild : u.lastChild;
+ if (l(u) && u.nodeType === Node.TEXT_NODE) {
+ var h = (o = (t = u.textContent) === null || t === void 0 ? void 0 : t.length) !== null && o !== void 0 ? o : 0, i = e ? 0 : h;
+ s.setStart(u, i), s.setEnd(u, i);
+ } else
+ a(n);
+ } else
+ a(n);
+ r.removeAllRanges(), r.addRange(s);
+ }
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.focus = void 0;
+ var e = lo;
+ Object.defineProperty(n, "focus", { enumerable: !0, get: function() {
+ return e.focus;
+ } });
+})(Mn);
+var co = {}, Je = {};
+Object.defineProperty(Je, "__esModule", { value: !0 });
+Je.getCaretNodeAndOffset = Kr;
+function Kr() {
+ var n = window.getSelection();
+ if (n === null)
+ return [null, 0];
+ var e = n.focusNode, t = n.focusOffset;
+ return e === null ? [null, 0] : (e.nodeType !== Node.TEXT_NODE && e.childNodes.length > 0 && (e.childNodes[t] !== void 0 ? (e = e.childNodes[t], t = 0) : (e = e.childNodes[t - 1], e.textContent !== null && (t = e.textContent.length))), [e, t]);
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.getCaretNodeAndOffset = void 0;
+ var e = Je;
+ Object.defineProperty(n, "getCaretNodeAndOffset", { enumerable: !0, get: function() {
+ return e.getCaretNodeAndOffset;
+ } });
+})(co);
+var An = {}, et = {};
+Object.defineProperty(et, "__esModule", { value: !0 });
+et.getRange = Xr;
+function Xr() {
+ var n = window.getSelection();
+ return n && n.rangeCount ? n.getRangeAt(0) : null;
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.getRange = void 0;
+ var e = et;
+ Object.defineProperty(n, "getRange", { enumerable: !0, get: function() {
+ return e.getRange;
+ } });
+})(An);
+var Ln = {}, uo = {};
+Object.defineProperty(uo, "__esModule", { value: !0 });
+uo.isCaretAtEndOfInput = Zr;
+var Oo = de, Vr = co, qr = St;
+function Zr(n) {
+ var e = (0, Oo.getDeepestNode)(n, !0);
+ if (e === null)
+ return !0;
+ if ((0, Oo.isNativeInput)(e))
+ return e.selectionEnd === e.value.length;
+ var t = (0, Vr.getCaretNodeAndOffset)(), o = t[0], i = t[1];
+ return o === null ? !1 : (0, qr.checkContenteditableSliceForEmptiness)(n, o, i, "right");
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isCaretAtEndOfInput = void 0;
+ var e = uo;
+ Object.defineProperty(n, "isCaretAtEndOfInput", { enumerable: !0, get: function() {
+ return e.isCaretAtEndOfInput;
+ } });
+})(Ln);
+var Pn = {}, ho = {};
+Object.defineProperty(ho, "__esModule", { value: !0 });
+ho.isCaretAtStartOfInput = Jr;
+var Ae = de, Gr = Je, Qr = Xe;
+function Jr(n) {
+ var e = (0, Ae.getDeepestNode)(n);
+ if (e === null || (0, Ae.isEmpty)(n))
+ return !0;
+ if ((0, Ae.isNativeInput)(e))
+ return e.selectionEnd === 0;
+ if ((0, Ae.isEmpty)(n))
+ return !0;
+ var t = (0, Gr.getCaretNodeAndOffset)(), o = t[0], i = t[1];
+ return o === null ? !1 : (0, Qr.checkContenteditableSliceForEmptiness)(n, o, i, "left");
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.isCaretAtStartOfInput = void 0;
+ var e = ho;
+ Object.defineProperty(n, "isCaretAtStartOfInput", { enumerable: !0, get: function() {
+ return e.isCaretAtStartOfInput;
+ } });
+})(Pn);
+var Nn = {}, po = {};
+Object.defineProperty(po, "__esModule", { value: !0 });
+po.save = oa;
+var ea = de, ta = et;
+function oa() {
+ var n = (0, ta.getRange)(), e = (0, ea.make)("span");
+ if (e.id = "cursor", e.hidden = !0, !!n)
+ return n.insertNode(e), function() {
+ var o = window.getSelection();
+ o && (n.setStartAfter(e), n.setEndAfter(e), o.removeAllRanges(), o.addRange(n), setTimeout(function() {
+ e.remove();
+ }, 150));
+ };
+}
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.save = void 0;
+ var e = po;
+ Object.defineProperty(n, "save", { enumerable: !0, get: function() {
+ return e.save;
+ } });
+})(Nn);
+(function(n) {
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.save = n.isCaretAtStartOfInput = n.isCaretAtEndOfInput = n.getRange = n.getCaretNodeAndOffset = n.focus = n.getContenteditableSlice = n.checkContenteditableSliceForEmptiness = void 0;
+ var e = St;
+ Object.defineProperty(n, "checkContenteditableSliceForEmptiness", { enumerable: !0, get: function() {
+ return e.checkContenteditableSliceForEmptiness;
+ } });
+ var t = _n;
+ Object.defineProperty(n, "getContenteditableSlice", { enumerable: !0, get: function() {
+ return t.getContenteditableSlice;
+ } });
+ var o = Mn;
+ Object.defineProperty(n, "focus", { enumerable: !0, get: function() {
+ return o.focus;
+ } });
+ var i = co;
+ Object.defineProperty(n, "getCaretNodeAndOffset", { enumerable: !0, get: function() {
+ return i.getCaretNodeAndOffset;
+ } });
+ var s = An;
+ Object.defineProperty(n, "getRange", { enumerable: !0, get: function() {
+ return s.getRange;
+ } });
+ var r = Ln;
+ Object.defineProperty(n, "isCaretAtEndOfInput", { enumerable: !0, get: function() {
+ return r.isCaretAtEndOfInput;
+ } });
+ var a = Pn;
+ Object.defineProperty(n, "isCaretAtStartOfInput", { enumerable: !0, get: function() {
+ return a.isCaretAtStartOfInput;
+ } });
+ var l = Nn;
+ Object.defineProperty(n, "save", { enumerable: !0, get: function() {
+ return l.save;
+ } });
+})(hn);
+class na extends E {
+ /**
+ * All keydowns on Block
+ *
+ * @param {KeyboardEvent} event - keydown
+ */
+ keydown(e) {
+ switch (this.beforeKeydownProcessing(e), e.keyCode) {
+ case y.BACKSPACE:
+ this.backspace(e);
+ break;
+ case y.DELETE:
+ this.delete(e);
+ break;
+ case y.ENTER:
+ this.enter(e);
+ break;
+ case y.DOWN:
+ case y.RIGHT:
+ this.arrowRightAndDown(e);
+ break;
+ case y.UP:
+ case y.LEFT:
+ this.arrowLeftAndUp(e);
+ break;
+ case y.TAB:
+ this.tabPressed(e);
+ break;
+ }
+ e.key === "/" && !e.ctrlKey && !e.metaKey && this.slashPressed(e), e.code === "Slash" && (e.ctrlKey || e.metaKey) && (e.preventDefault(), this.commandSlashPressed());
+ }
+ /**
+ * Fires on keydown before event processing
+ *
+ * @param {KeyboardEvent} event - keydown
+ */
+ beforeKeydownProcessing(e) {
+ this.needToolbarClosing(e) && Po(e.keyCode) && (this.Editor.Toolbar.close(), e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || this.Editor.BlockSelection.clearSelection(e));
+ }
+ /**
+ * Key up on Block:
+ * - shows Inline Toolbar if something selected
+ * - shows conversion toolbar with 85% of block selection
+ *
+ * @param {KeyboardEvent} event - keyup event
+ */
+ keyup(e) {
+ e.shiftKey || this.Editor.UI.checkEmptiness();
+ }
+ /**
+ * Add drop target styles
+ *
+ * @param {DragEvent} event - drag over event
+ */
+ dragOver(e) {
+ const t = this.Editor.BlockManager.getBlockByChildNode(e.target);
+ t.dropTarget = !0;
+ }
+ /**
+ * Remove drop target style
+ *
+ * @param {DragEvent} event - drag leave event
+ */
+ dragLeave(e) {
+ const t = this.Editor.BlockManager.getBlockByChildNode(e.target);
+ t.dropTarget = !1;
+ }
+ /**
+ * Copying selected blocks
+ * Before putting to the clipboard we sanitize all blocks and then copy to the clipboard
+ *
+ * @param {ClipboardEvent} event - clipboard event
+ */
+ handleCommandC(e) {
+ const { BlockSelection: t } = this.Editor;
+ t.anyBlockSelected && t.copySelectedBlocks(e);
+ }
+ /**
+ * Copy and Delete selected Blocks
+ *
+ * @param {ClipboardEvent} event - clipboard event
+ */
+ handleCommandX(e) {
+ const { BlockSelection: t, BlockManager: o, Caret: i } = this.Editor;
+ t.anyBlockSelected && t.copySelectedBlocks(e).then(() => {
+ const s = o.removeSelectedBlocks(), r = o.insertDefaultBlockAtIndex(s, !0);
+ i.setToBlock(r, i.positions.START), t.clearSelection(e);
+ });
+ }
+ /**
+ * Tab pressed inside a Block.
+ *
+ * @param {KeyboardEvent} event - keydown
+ */
+ tabPressed(e) {
+ const { InlineToolbar: t, Caret: o } = this.Editor;
+ if (t.opened)
+ return;
+ (e.shiftKey ? o.navigatePrevious(!0) : o.navigateNext(!0)) && e.preventDefault();
+ }
+ /**
+ * '/' + 'command' keydown inside a Block
+ */
+ commandSlashPressed() {
+ this.Editor.BlockSelection.selectedBlocks.length > 1 || this.activateBlockSettings();
+ }
+ /**
+ * '/' keydown inside a Block
+ *
+ * @param event - keydown
+ */
+ slashPressed(e) {
+ !this.Editor.UI.nodes.wrapper.contains(e.target) || !this.Editor.BlockManager.currentBlock.isEmpty || (e.preventDefault(), this.Editor.Caret.insertContentAtCaretPosition("/"), this.activateToolbox());
+ }
+ /**
+ * ENTER pressed on block
+ *
+ * @param {KeyboardEvent} event - keydown
+ */
+ enter(e) {
+ const { BlockManager: t, UI: o } = this.Editor, i = t.currentBlock;
+ if (i === void 0 || i.tool.isLineBreaksEnabled || o.someToolbarOpened && o.someFlipperButtonFocused || e.shiftKey && !pt)
+ return;
+ let s = i;
+ i.currentInput !== void 0 && Ne(i.currentInput) && !i.hasMedia ? this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex) : i.currentInput && Re(i.currentInput) ? s = this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex + 1) : s = this.Editor.BlockManager.split(), this.Editor.Caret.setToBlock(s), this.Editor.Toolbar.moveAndOpen(s), e.preventDefault();
+ }
+ /**
+ * Handle backspace keydown on Block
+ *
+ * @param {KeyboardEvent} event - keydown
+ */
+ backspace(e) {
+ const { BlockManager: t, Caret: o } = this.Editor, { currentBlock: i, previousBlock: s } = t;
+ if (i === void 0 || !b.isCollapsed || !i.currentInput || !Ne(i.currentInput))
+ return;
+ if (e.preventDefault(), this.Editor.Toolbar.close(), !(i.currentInput === i.firstInput)) {
+ o.navigatePrevious();
+ return;
+ }
+ if (s === null)
+ return;
+ if (s.isEmpty) {
+ t.removeBlock(s);
+ return;
+ }
+ if (i.isEmpty) {
+ t.removeBlock(i);
+ const l = t.currentBlock;
+ o.setToBlock(l, o.positions.END);
+ return;
+ }
+ xo(s, i) ? this.mergeBlocks(s, i) : o.setToBlock(s, o.positions.END);
+ }
+ /**
+ * Handles delete keydown on Block
+ * Removes char after the caret.
+ * If caret is at the end of the block, merge next block with current
+ *
+ * @param {KeyboardEvent} event - keydown
+ */
+ delete(e) {
+ const { BlockManager: t, Caret: o } = this.Editor, { currentBlock: i, nextBlock: s } = t;
+ if (!b.isCollapsed || !Re(i.currentInput))
+ return;
+ if (e.preventDefault(), this.Editor.Toolbar.close(), !(i.currentInput === i.lastInput)) {
+ o.navigateNext();
+ return;
+ }
+ if (s === null)
+ return;
+ if (s.isEmpty) {
+ t.removeBlock(s);
+ return;
+ }
+ if (i.isEmpty) {
+ t.removeBlock(i), o.setToBlock(s, o.positions.START);
+ return;
+ }
+ xo(i, s) ? this.mergeBlocks(i, s) : o.setToBlock(s, o.positions.START);
+ }
+ /**
+ * Merge passed Blocks
+ *
+ * @param targetBlock - to which Block we want to merge
+ * @param blockToMerge - what Block we want to merge
+ */
+ mergeBlocks(e, t) {
+ const { BlockManager: o, Toolbar: i } = this.Editor;
+ e.lastInput !== void 0 && (hn.focus(e.lastInput, !1), o.mergeBlocks(e, t).then(() => {
+ i.close();
+ }));
+ }
+ /**
+ * Handle right and down keyboard keys
+ *
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ arrowRightAndDown(e) {
+ const t = ce.usedKeys.includes(e.keyCode) && (!e.shiftKey || e.keyCode === y.TAB);
+ if (this.Editor.UI.someToolbarOpened && t)
+ return;
+ this.Editor.Toolbar.close();
+ const { currentBlock: o } = this.Editor.BlockManager, s = ((o == null ? void 0 : o.currentInput) !== void 0 ? Re(o.currentInput) : void 0) || this.Editor.BlockSelection.anyBlockSelected;
+ if (e.shiftKey && e.keyCode === y.DOWN && s) {
+ this.Editor.CrossBlockSelection.toggleBlockSelectedState();
+ return;
+ }
+ if (e.keyCode === y.DOWN || e.keyCode === y.RIGHT && !this.isRtl ? this.Editor.Caret.navigateNext() : this.Editor.Caret.navigatePrevious()) {
+ e.preventDefault();
+ return;
+ }
+ Fe(() => {
+ this.Editor.BlockManager.currentBlock && this.Editor.BlockManager.currentBlock.updateCurrentInput();
+ }, 20)(), this.Editor.BlockSelection.clearSelection(e);
+ }
+ /**
+ * Handle left and up keyboard keys
+ *
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ arrowLeftAndUp(e) {
+ if (this.Editor.UI.someToolbarOpened) {
+ if (ce.usedKeys.includes(e.keyCode) && (!e.shiftKey || e.keyCode === y.TAB))
+ return;
+ this.Editor.UI.closeAllToolbars();
+ }
+ this.Editor.Toolbar.close();
+ const { currentBlock: t } = this.Editor.BlockManager, i = ((t == null ? void 0 : t.currentInput) !== void 0 ? Ne(t.currentInput) : void 0) || this.Editor.BlockSelection.anyBlockSelected;
+ if (e.shiftKey && e.keyCode === y.UP && i) {
+ this.Editor.CrossBlockSelection.toggleBlockSelectedState(!1);
+ return;
+ }
+ if (e.keyCode === y.UP || e.keyCode === y.LEFT && !this.isRtl ? this.Editor.Caret.navigatePrevious() : this.Editor.Caret.navigateNext()) {
+ e.preventDefault();
+ return;
+ }
+ Fe(() => {
+ this.Editor.BlockManager.currentBlock && this.Editor.BlockManager.currentBlock.updateCurrentInput();
+ }, 20)(), this.Editor.BlockSelection.clearSelection(e);
+ }
+ /**
+ * Cases when we need to close Toolbar
+ *
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ needToolbarClosing(e) {
+ const t = e.keyCode === y.ENTER && this.Editor.Toolbar.toolbox.opened, o = e.keyCode === y.ENTER && this.Editor.BlockSettings.opened, i = e.keyCode === y.ENTER && this.Editor.InlineToolbar.opened, s = e.keyCode === y.TAB;
+ return !(e.shiftKey || s || t || o || i);
+ }
+ /**
+ * If Toolbox is not open, then just open it and show plus button
+ */
+ activateToolbox() {
+ this.Editor.Toolbar.opened || this.Editor.Toolbar.moveAndOpen(), this.Editor.Toolbar.toolbox.open();
+ }
+ /**
+ * Open Toolbar and show BlockSettings before flipping Tools
+ */
+ activateBlockSettings() {
+ this.Editor.Toolbar.opened || this.Editor.Toolbar.moveAndOpen(), this.Editor.BlockSettings.opened || this.Editor.BlockSettings.open();
+ }
+}
+class ct {
+ /**
+ * @class
+ * @param {HTMLElement} workingArea — editor`s working node
+ */
+ constructor(e) {
+ this.blocks = [], this.workingArea = e;
+ }
+ /**
+ * Get length of Block instances array
+ *
+ * @returns {number}
+ */
+ get length() {
+ return this.blocks.length;
+ }
+ /**
+ * Get Block instances array
+ *
+ * @returns {Block[]}
+ */
+ get array() {
+ return this.blocks;
+ }
+ /**
+ * Get blocks html elements array
+ *
+ * @returns {HTMLElement[]}
+ */
+ get nodes() {
+ return No(this.workingArea.children);
+ }
+ /**
+ * Proxy trap to implement array-like setter
+ *
+ * @example
+ * blocks[0] = new Block(...)
+ * @param {Blocks} instance — Blocks instance
+ * @param {PropertyKey} property — block index or any Blocks class property key to set
+ * @param {Block} value — value to set
+ * @returns {boolean}
+ */
+ static set(e, t, o) {
+ return isNaN(Number(t)) ? (Reflect.set(e, t, o), !0) : (e.insert(+t, o), !0);
+ }
+ /**
+ * Proxy trap to implement array-like getter
+ *
+ * @param {Blocks} instance — Blocks instance
+ * @param {PropertyKey} property — Blocks class property key
+ * @returns {Block|*}
+ */
+ static get(e, t) {
+ return isNaN(Number(t)) ? Reflect.get(e, t) : e.get(+t);
+ }
+ /**
+ * Push new Block to the blocks array and append it to working area
+ *
+ * @param {Block} block - Block to add
+ */
+ push(e) {
+ this.blocks.push(e), this.insertToDOM(e);
+ }
+ /**
+ * Swaps blocks with indexes first and second
+ *
+ * @param {number} first - first block index
+ * @param {number} second - second block index
+ * @deprecated — use 'move' instead
+ */
+ swap(e, t) {
+ const o = this.blocks[t];
+ d.swap(this.blocks[e].holder, o.holder), this.blocks[t] = this.blocks[e], this.blocks[e] = o;
+ }
+ /**
+ * Move a block from one to another index
+ *
+ * @param {number} toIndex - new index of the block
+ * @param {number} fromIndex - block to move
+ */
+ move(e, t) {
+ const o = this.blocks.splice(t, 1)[0], i = e - 1, s = Math.max(0, i), r = this.blocks[s];
+ e > 0 ? this.insertToDOM(o, "afterend", r) : this.insertToDOM(o, "beforebegin", r), this.blocks.splice(e, 0, o);
+ const a = this.composeBlockEvent("move", {
+ fromIndex: t,
+ toIndex: e
+ });
+ o.call(ee.MOVED, a);
+ }
+ /**
+ * Insert new Block at passed index
+ *
+ * @param {number} index — index to insert Block
+ * @param {Block} block — Block to insert
+ * @param {boolean} replace — it true, replace block on given index
+ */
+ insert(e, t, o = !1) {
+ if (!this.length) {
+ this.push(t);
+ return;
+ }
+ e > this.length && (e = this.length), o && (this.blocks[e].holder.remove(), this.blocks[e].call(ee.REMOVED));
+ const i = o ? 1 : 0;
+ if (this.blocks.splice(e, i, t), e > 0) {
+ const s = this.blocks[e - 1];
+ this.insertToDOM(t, "afterend", s);
+ } else {
+ const s = this.blocks[e + 1];
+ s ? this.insertToDOM(t, "beforebegin", s) : this.insertToDOM(t);
+ }
+ }
+ /**
+ * Replaces block under passed index with passed block
+ *
+ * @param index - index of existed block
+ * @param block - new block
+ */
+ replace(e, t) {
+ if (this.blocks[e] === void 0)
+ throw Error("Incorrect index");
+ this.blocks[e].holder.replaceWith(t.holder), this.blocks[e] = t;
+ }
+ /**
+ * Inserts several blocks at once
+ *
+ * @param blocks - blocks to insert
+ * @param index - index to insert blocks at
+ */
+ insertMany(e, t) {
+ const o = new DocumentFragment();
+ for (const i of e)
+ o.appendChild(i.holder);
+ if (this.length > 0) {
+ if (t > 0) {
+ const i = Math.min(t - 1, this.length - 1);
+ this.blocks[i].holder.after(o);
+ } else
+ t === 0 && this.workingArea.prepend(o);
+ this.blocks.splice(t, 0, ...e);
+ } else
+ this.blocks.push(...e), this.workingArea.appendChild(o);
+ e.forEach((i) => i.call(ee.RENDERED));
+ }
+ /**
+ * Remove block
+ *
+ * @param {number} index - index of Block to remove
+ */
+ remove(e) {
+ isNaN(e) && (e = this.length - 1), this.blocks[e].holder.remove(), this.blocks[e].call(ee.REMOVED), this.blocks.splice(e, 1);
+ }
+ /**
+ * Remove all blocks
+ */
+ removeAll() {
+ this.workingArea.innerHTML = "", this.blocks.forEach((e) => e.call(ee.REMOVED)), this.blocks.length = 0;
+ }
+ /**
+ * Insert Block after passed target
+ *
+ * @todo decide if this method is necessary
+ * @param {Block} targetBlock — target after which Block should be inserted
+ * @param {Block} newBlock — Block to insert
+ */
+ insertAfter(e, t) {
+ const o = this.blocks.indexOf(e);
+ this.insert(o + 1, t);
+ }
+ /**
+ * Get Block by index
+ *
+ * @param {number} index — Block index
+ * @returns {Block}
+ */
+ get(e) {
+ return this.blocks[e];
+ }
+ /**
+ * Return index of passed Block
+ *
+ * @param {Block} block - Block to find
+ * @returns {number}
+ */
+ indexOf(e) {
+ return this.blocks.indexOf(e);
+ }
+ /**
+ * Insert new Block into DOM
+ *
+ * @param {Block} block - Block to insert
+ * @param {InsertPosition} position — insert position (if set, will use insertAdjacentElement)
+ * @param {Block} target — Block related to position
+ */
+ insertToDOM(e, t, o) {
+ t ? o.holder.insertAdjacentElement(t, e.holder) : this.workingArea.appendChild(e.holder), e.call(ee.RENDERED);
+ }
+ /**
+ * Composes Block event with passed type and details
+ *
+ * @param {string} type - event type
+ * @param {object} detail - event detail
+ */
+ composeBlockEvent(e, t) {
+ return new CustomEvent(e, {
+ detail: t
+ });
+ }
+}
+const _o = "block-removed", Mo = "block-added", ia = "block-moved", Ao = "block-changed";
+class sa {
+ constructor() {
+ this.completed = Promise.resolve();
+ }
+ /**
+ * Add new promise to queue
+ *
+ * @param operation - promise should be added to queue
+ */
+ add(e) {
+ return new Promise((t, o) => {
+ this.completed = this.completed.then(e).then(t).catch(o);
+ });
+ }
+}
+class ra extends E {
+ constructor() {
+ super(...arguments), this._currentBlockIndex = -1, this._blocks = null;
+ }
+ /**
+ * Returns current Block index
+ *
+ * @returns {number}
+ */
+ get currentBlockIndex() {
+ return this._currentBlockIndex;
+ }
+ /**
+ * Set current Block index and fire Block lifecycle callbacks
+ *
+ * @param {number} newIndex - index of Block to set as current
+ */
+ set currentBlockIndex(e) {
+ this._currentBlockIndex = e;
+ }
+ /**
+ * returns first Block
+ *
+ * @returns {Block}
+ */
+ get firstBlock() {
+ return this._blocks[0];
+ }
+ /**
+ * returns last Block
+ *
+ * @returns {Block}
+ */
+ get lastBlock() {
+ return this._blocks[this._blocks.length - 1];
+ }
+ /**
+ * Get current Block instance
+ *
+ * @returns {Block}
+ */
+ get currentBlock() {
+ return this._blocks[this.currentBlockIndex];
+ }
+ /**
+ * Set passed Block as a current
+ *
+ * @param block - block to set as a current
+ */
+ set currentBlock(e) {
+ this.currentBlockIndex = this.getBlockIndex(e);
+ }
+ /**
+ * Returns next Block instance
+ *
+ * @returns {Block|null}
+ */
+ get nextBlock() {
+ return this.currentBlockIndex === this._blocks.length - 1 ? null : this._blocks[this.currentBlockIndex + 1];
+ }
+ /**
+ * Return first Block with inputs after current Block
+ *
+ * @returns {Block | undefined}
+ */
+ get nextContentfulBlock() {
+ return this.blocks.slice(this.currentBlockIndex + 1).find((t) => !!t.inputs.length);
+ }
+ /**
+ * Return first Block with inputs before current Block
+ *
+ * @returns {Block | undefined}
+ */
+ get previousContentfulBlock() {
+ return this.blocks.slice(0, this.currentBlockIndex).reverse().find((t) => !!t.inputs.length);
+ }
+ /**
+ * Returns previous Block instance
+ *
+ * @returns {Block|null}
+ */
+ get previousBlock() {
+ return this.currentBlockIndex === 0 ? null : this._blocks[this.currentBlockIndex - 1];
+ }
+ /**
+ * Get array of Block instances
+ *
+ * @returns {Block[]} {@link Blocks#array}
+ */
+ get blocks() {
+ return this._blocks.array;
+ }
+ /**
+ * Check if each Block is empty
+ *
+ * @returns {boolean}
+ */
+ get isEditorEmpty() {
+ return this.blocks.every((e) => e.isEmpty);
+ }
+ /**
+ * Should be called after Editor.UI preparation
+ * Define this._blocks property
+ */
+ prepare() {
+ const e = new ct(this.Editor.UI.nodes.redactor);
+ this._blocks = new Proxy(e, {
+ set: ct.set,
+ get: ct.get
+ }), this.listeners.on(
+ document,
+ "copy",
+ (t) => this.Editor.BlockEvents.handleCommandC(t)
+ );
+ }
+ /**
+ * Toggle read-only state
+ *
+ * If readOnly is true:
+ * - Unbind event handlers from created Blocks
+ *
+ * if readOnly is false:
+ * - Bind event handlers to all existing Blocks
+ *
+ * @param {boolean} readOnlyEnabled - "read only" state
+ */
+ toggleReadOnly(e) {
+ e ? this.disableModuleBindings() : this.enableModuleBindings();
+ }
+ /**
+ * Creates Block instance by tool name
+ *
+ * @param {object} options - block creation options
+ * @param {string} options.tool - tools passed in editor config {@link EditorConfig#tools}
+ * @param {string} [options.id] - unique id for this block
+ * @param {BlockToolData} [options.data] - constructor params
+ * @returns {Block}
+ */
+ composeBlock({
+ tool: e,
+ data: t = {},
+ id: o = void 0,
+ tunes: i = {}
+ }) {
+ const s = this.Editor.ReadOnly.isEnabled, r = this.Editor.Tools.blockTools.get(e), a = new R({
+ id: o,
+ data: t,
+ tool: r,
+ api: this.Editor.API,
+ readOnly: s,
+ tunesData: i
+ }, this.eventsDispatcher);
+ return s || window.requestIdleCallback(() => {
+ this.bindBlockEvents(a);
+ }, { timeout: 2e3 }), a;
+ }
+ /**
+ * Insert new block into _blocks
+ *
+ * @param {object} options - insert options
+ * @param {string} [options.id] - block's unique id
+ * @param {string} [options.tool] - plugin name, by default method inserts the default block type
+ * @param {object} [options.data] - plugin data
+ * @param {number} [options.index] - index where to insert new Block
+ * @param {boolean} [options.needToFocus] - flag shows if needed to update current Block index
+ * @param {boolean} [options.replace] - flag shows if block by passed index should be replaced with inserted one
+ * @returns {Block}
+ */
+ insert({
+ id: e = void 0,
+ tool: t = this.config.defaultBlock,
+ data: o = {},
+ index: i,
+ needToFocus: s = !0,
+ replace: r = !1,
+ tunes: a = {}
+ } = {}) {
+ let l = i;
+ l === void 0 && (l = this.currentBlockIndex + (r ? 0 : 1));
+ const c = this.composeBlock({
+ id: e,
+ tool: t,
+ data: o,
+ tunes: a
+ });
+ return r && this.blockDidMutated(_o, this.getBlockByIndex(l), {
+ index: l
+ }), this._blocks.insert(l, c, r), this.blockDidMutated(Mo, c, {
+ index: l
+ }), s ? this.currentBlockIndex = l : l <= this.currentBlockIndex && this.currentBlockIndex++, c;
+ }
+ /**
+ * Inserts several blocks at once
+ *
+ * @param blocks - blocks to insert
+ * @param index - index where to insert
+ */
+ insertMany(e, t = 0) {
+ this._blocks.insertMany(e, t);
+ }
+ /**
+ * Update Block data.
+ *
+ * Currently we don't have an 'update' method in the Tools API, so we just create a new block with the same id and type
+ * Should not trigger 'block-removed' or 'block-added' events.
+ *
+ * If neither data nor tunes is provided, return the provided block instead.
+ *
+ * @param block - block to update
+ * @param data - (optional) new data
+ * @param tunes - (optional) tune data
+ */
+ async update(e, t, o) {
+ if (!t && !o)
+ return e;
+ const i = await e.data, s = this.composeBlock({
+ id: e.id,
+ tool: e.name,
+ data: Object.assign({}, i, t ?? {}),
+ tunes: o ?? e.tunes
+ }), r = this.getBlockIndex(e);
+ return this._blocks.replace(r, s), this.blockDidMutated(Ao, s, {
+ index: r
+ }), s;
+ }
+ /**
+ * Replace passed Block with the new one with specified Tool and data
+ *
+ * @param block - block to replace
+ * @param newTool - new Tool name
+ * @param data - new Tool data
+ */
+ replace(e, t, o) {
+ const i = this.getBlockIndex(e);
+ return this.insert({
+ tool: t,
+ data: o,
+ index: i,
+ replace: !0
+ });
+ }
+ /**
+ * Insert pasted content. Call onPaste callback after insert.
+ *
+ * @param {string} toolName - name of Tool to insert
+ * @param {PasteEvent} pasteEvent - pasted data
+ * @param {boolean} replace - should replace current block
+ */
+ paste(e, t, o = !1) {
+ const i = this.insert({
+ tool: e,
+ replace: o
+ });
+ try {
+ window.requestIdleCallback(() => {
+ i.call(ee.ON_PASTE, t);
+ });
+ } catch (s) {
+ S(`${e}: onPaste callback call is failed`, "error", s);
+ }
+ return i;
+ }
+ /**
+ * Insert new default block at passed index
+ *
+ * @param {number} index - index where Block should be inserted
+ * @param {boolean} needToFocus - if true, updates current Block index
+ *
+ * TODO: Remove method and use insert() with index instead (?)
+ * @returns {Block} inserted Block
+ */
+ insertDefaultBlockAtIndex(e, t = !1) {
+ const o = this.composeBlock({ tool: this.config.defaultBlock });
+ return this._blocks[e] = o, this.blockDidMutated(Mo, o, {
+ index: e
+ }), t ? this.currentBlockIndex = e : e <= this.currentBlockIndex && this.currentBlockIndex++, o;
+ }
+ /**
+ * Always inserts at the end
+ *
+ * @returns {Block}
+ */
+ insertAtEnd() {
+ return this.currentBlockIndex = this.blocks.length - 1, this.insert();
+ }
+ /**
+ * Merge two blocks
+ *
+ * @param {Block} targetBlock - previous block will be append to this block
+ * @param {Block} blockToMerge - block that will be merged with target block
+ * @returns {Promise} - the sequence that can be continued
+ */
+ async mergeBlocks(e, t) {
+ let o;
+ if (e.name === t.name && e.mergeable) {
+ const i = await t.data;
+ if (V(i)) {
+ console.error("Could not merge Block. Failed to extract original Block data.");
+ return;
+ }
+ const [s] = yt([i], e.tool.sanitizeConfig);
+ o = s;
+ } else if (e.mergeable && He(t, "export") && He(e, "import")) {
+ const i = await t.exportDataAsString(), s = Z(i, e.tool.sanitizeConfig);
+ o = Bo(s, e.tool.conversionConfig);
+ }
+ o !== void 0 && (await e.mergeWith(o), this.removeBlock(t), this.currentBlockIndex = this._blocks.indexOf(e));
+ }
+ /**
+ * Remove passed Block
+ *
+ * @param block - Block to remove
+ * @param addLastBlock - if true, adds new default block at the end. @todo remove this logic and use event-bus instead
+ */
+ removeBlock(e, t = !0) {
+ return new Promise((o) => {
+ const i = this._blocks.indexOf(e);
+ if (!this.validateIndex(i))
+ throw new Error("Can't find a Block to remove");
+ e.destroy(), this._blocks.remove(i), this.blockDidMutated(_o, e, {
+ index: i
+ }), this.currentBlockIndex >= i && this.currentBlockIndex--, this.blocks.length ? i === 0 && (this.currentBlockIndex = 0) : (this.unsetCurrentBlock(), t && this.insert()), o();
+ });
+ }
+ /**
+ * Remove only selected Blocks
+ * and returns first Block index where started removing...
+ *
+ * @returns {number|undefined}
+ */
+ removeSelectedBlocks() {
+ let e;
+ for (let t = this.blocks.length - 1; t >= 0; t--)
+ this.blocks[t].selected && (this.removeBlock(this.blocks[t]), e = t);
+ return e;
+ }
+ /**
+ * Attention!
+ * After removing insert the new default typed Block and focus on it
+ * Removes all blocks
+ */
+ removeAllBlocks() {
+ for (let e = this.blocks.length - 1; e >= 0; e--)
+ this._blocks.remove(e);
+ this.unsetCurrentBlock(), this.insert(), this.currentBlock.firstInput.focus();
+ }
+ /**
+ * Split current Block
+ * 1. Extract content from Caret position to the Block`s end
+ * 2. Insert a new Block below current one with extracted content
+ *
+ * @returns {Block}
+ */
+ split() {
+ const e = this.Editor.Caret.extractFragmentFromCaretPosition(), t = d.make("div");
+ t.appendChild(e);
+ const o = {
+ text: d.isEmpty(t) ? "" : t.innerHTML
+ };
+ return this.insert({ data: o });
+ }
+ /**
+ * Returns Block by passed index
+ *
+ * @param {number} index - index to get. -1 to get last
+ * @returns {Block}
+ */
+ getBlockByIndex(e) {
+ return e === -1 && (e = this._blocks.length - 1), this._blocks[e];
+ }
+ /**
+ * Returns an index for passed Block
+ *
+ * @param block - block to find index
+ */
+ getBlockIndex(e) {
+ return this._blocks.indexOf(e);
+ }
+ /**
+ * Returns the Block by passed id
+ *
+ * @param id - id of block to get
+ * @returns {Block}
+ */
+ getBlockById(e) {
+ return this._blocks.array.find((t) => t.id === e);
+ }
+ /**
+ * Get Block instance by html element
+ *
+ * @param {Node} element - html element to get Block by
+ */
+ getBlock(e) {
+ d.isElement(e) || (e = e.parentNode);
+ const t = this._blocks.nodes, o = e.closest(`.${R.CSS.wrapper}`), i = t.indexOf(o);
+ if (i >= 0)
+ return this._blocks[i];
+ }
+ /**
+ * 1) Find first-level Block from passed child Node
+ * 2) Mark it as current
+ *
+ * @param {Node} childNode - look ahead from this node.
+ * @returns {Block | undefined} can return undefined in case when the passed child note is not a part of the current editor instance
+ */
+ setCurrentBlockByChildNode(e) {
+ d.isElement(e) || (e = e.parentNode);
+ const t = e.closest(`.${R.CSS.wrapper}`);
+ if (!t)
+ return;
+ const o = t.closest(`.${this.Editor.UI.CSS.editorWrapper}`);
+ if (o != null && o.isEqualNode(this.Editor.UI.nodes.wrapper))
+ return this.currentBlockIndex = this._blocks.nodes.indexOf(t), this.currentBlock.updateCurrentInput(), this.currentBlock;
+ }
+ /**
+ * Return block which contents passed node
+ *
+ * @param {Node} childNode - node to get Block by
+ * @returns {Block}
+ */
+ getBlockByChildNode(e) {
+ if (!e || !(e instanceof Node))
+ return;
+ d.isElement(e) || (e = e.parentNode);
+ const t = e.closest(`.${R.CSS.wrapper}`);
+ return this.blocks.find((o) => o.holder === t);
+ }
+ /**
+ * Swap Blocks Position
+ *
+ * @param {number} fromIndex - index of first block
+ * @param {number} toIndex - index of second block
+ * @deprecated — use 'move' instead
+ */
+ swap(e, t) {
+ this._blocks.swap(e, t), this.currentBlockIndex = t;
+ }
+ /**
+ * Move a block to a new index
+ *
+ * @param {number} toIndex - index where to move Block
+ * @param {number} fromIndex - index of Block to move
+ */
+ move(e, t = this.currentBlockIndex) {
+ if (isNaN(e) || isNaN(t)) {
+ S("Warning during 'move' call: incorrect indices provided.", "warn");
+ return;
+ }
+ if (!this.validateIndex(e) || !this.validateIndex(t)) {
+ S("Warning during 'move' call: indices cannot be lower than 0 or greater than the amount of blocks.", "warn");
+ return;
+ }
+ this._blocks.move(e, t), this.currentBlockIndex = e, this.blockDidMutated(ia, this.currentBlock, {
+ fromIndex: t,
+ toIndex: e
+ });
+ }
+ /**
+ * Converts passed Block to the new Tool
+ * Uses Conversion Config
+ *
+ * @param blockToConvert - Block that should be converted
+ * @param targetToolName - name of the Tool to convert to
+ * @param blockDataOverrides - optional new Block data overrides
+ */
+ async convert(e, t, o) {
+ if (!await e.save())
+ throw new Error("Could not convert Block. Failed to extract original Block data.");
+ const s = this.Editor.Tools.blockTools.get(t);
+ if (!s)
+ throw new Error(`Could not convert Block. Tool «${t}» not found.`);
+ const r = await e.exportDataAsString(), a = Z(
+ r,
+ s.sanitizeConfig
+ );
+ let l = Bo(a, s.conversionConfig, s.settings);
+ return o && (l = Object.assign(l, o)), this.replace(e, s.name, l);
+ }
+ /**
+ * Sets current Block Index -1 which means unknown
+ * and clear highlights
+ */
+ unsetCurrentBlock() {
+ this.currentBlockIndex = -1;
+ }
+ /**
+ * Clears Editor
+ *
+ * @param {boolean} needToAddDefaultBlock - 1) in internal calls (for example, in api.blocks.render)
+ * we don't need to add an empty default block
+ * 2) in api.blocks.clear we should add empty block
+ */
+ async clear(e = !1) {
+ const t = new sa();
+ this.blocks.forEach((o) => {
+ t.add(async () => {
+ await this.removeBlock(o, !1);
+ });
+ }), await t.completed, this.unsetCurrentBlock(), e && this.insert(), this.Editor.UI.checkEmptiness();
+ }
+ /**
+ * Cleans up all the block tools' resources
+ * This is called when editor is destroyed
+ */
+ async destroy() {
+ await Promise.all(this.blocks.map((e) => e.destroy()));
+ }
+ /**
+ * Bind Block events
+ *
+ * @param {Block} block - Block to which event should be bound
+ */
+ bindBlockEvents(e) {
+ const { BlockEvents: t } = this.Editor;
+ this.readOnlyMutableListeners.on(e.holder, "keydown", (o) => {
+ t.keydown(o);
+ }), this.readOnlyMutableListeners.on(e.holder, "keyup", (o) => {
+ t.keyup(o);
+ }), this.readOnlyMutableListeners.on(e.holder, "dragover", (o) => {
+ t.dragOver(o);
+ }), this.readOnlyMutableListeners.on(e.holder, "dragleave", (o) => {
+ t.dragLeave(o);
+ }), e.on("didMutated", (o) => this.blockDidMutated(Ao, o, {
+ index: this.getBlockIndex(o)
+ }));
+ }
+ /**
+ * Disable mutable handlers and bindings
+ */
+ disableModuleBindings() {
+ this.readOnlyMutableListeners.clearAll();
+ }
+ /**
+ * Enables all module handlers and bindings for all Blocks
+ */
+ enableModuleBindings() {
+ this.readOnlyMutableListeners.on(
+ document,
+ "cut",
+ (e) => this.Editor.BlockEvents.handleCommandX(e)
+ ), this.blocks.forEach((e) => {
+ this.bindBlockEvents(e);
+ });
+ }
+ /**
+ * Validates that the given index is not lower than 0 or higher than the amount of blocks
+ *
+ * @param {number} index - index of blocks array to validate
+ * @returns {boolean}
+ */
+ validateIndex(e) {
+ return !(e < 0 || e >= this._blocks.length);
+ }
+ /**
+ * Block mutation callback
+ *
+ * @param mutationType - what happened with block
+ * @param block - mutated block
+ * @param detailData - additional data to pass with change event
+ */
+ blockDidMutated(e, t, o) {
+ const i = new CustomEvent(e, {
+ detail: {
+ target: new J(t),
+ ...o
+ }
+ });
+ return this.eventsDispatcher.emit($o, {
+ event: i
+ }), t;
+ }
+}
+class aa extends E {
+ constructor() {
+ super(...arguments), this.anyBlockSelectedCache = null, this.needToSelectAll = !1, this.nativeInputSelected = !1, this.readyToBlockSelection = !1;
+ }
+ /**
+ * Sanitizer Config
+ *
+ * @returns {SanitizerConfig}
+ */
+ get sanitizerConfig() {
+ return {
+ p: {},
+ h1: {},
+ h2: {},
+ h3: {},
+ h4: {},
+ h5: {},
+ h6: {},
+ ol: {},
+ ul: {},
+ li: {},
+ br: !0,
+ img: {
+ src: !0,
+ width: !0,
+ height: !0
+ },
+ a: {
+ href: !0
+ },
+ b: {},
+ i: {},
+ u: {}
+ };
+ }
+ /**
+ * Flag that identifies all Blocks selection
+ *
+ * @returns {boolean}
+ */
+ get allBlocksSelected() {
+ const { BlockManager: e } = this.Editor;
+ return e.blocks.every((t) => t.selected === !0);
+ }
+ /**
+ * Set selected all blocks
+ *
+ * @param {boolean} state - state to set
+ */
+ set allBlocksSelected(e) {
+ const { BlockManager: t } = this.Editor;
+ t.blocks.forEach((o) => {
+ o.selected = e;
+ }), this.clearCache();
+ }
+ /**
+ * Flag that identifies any Block selection
+ *
+ * @returns {boolean}
+ */
+ get anyBlockSelected() {
+ const { BlockManager: e } = this.Editor;
+ return this.anyBlockSelectedCache === null && (this.anyBlockSelectedCache = e.blocks.some((t) => t.selected === !0)), this.anyBlockSelectedCache;
+ }
+ /**
+ * Return selected Blocks array
+ *
+ * @returns {Block[]}
+ */
+ get selectedBlocks() {
+ return this.Editor.BlockManager.blocks.filter((e) => e.selected);
+ }
+ /**
+ * Module Preparation
+ * Registers Shortcuts CMD+A and CMD+C
+ * to select all and copy them
+ */
+ prepare() {
+ this.selection = new b(), ge.add({
+ name: "CMD+A",
+ handler: (e) => {
+ const { BlockManager: t, ReadOnly: o } = this.Editor;
+ if (o.isEnabled) {
+ e.preventDefault(), this.selectAllBlocks();
+ return;
+ }
+ t.currentBlock && this.handleCommandA(e);
+ },
+ on: this.Editor.UI.nodes.redactor
+ });
+ }
+ /**
+ * Toggle read-only state
+ *
+ * - Remove all ranges
+ * - Unselect all Blocks
+ */
+ toggleReadOnly() {
+ b.get().removeAllRanges(), this.allBlocksSelected = !1;
+ }
+ /**
+ * Remove selection of Block
+ *
+ * @param {number?} index - Block index according to the BlockManager's indexes
+ */
+ unSelectBlockByIndex(e) {
+ const { BlockManager: t } = this.Editor;
+ let o;
+ isNaN(e) ? o = t.currentBlock : o = t.getBlockByIndex(e), o.selected = !1, this.clearCache();
+ }
+ /**
+ * Clear selection from Blocks
+ *
+ * @param {Event} reason - event caused clear of selection
+ * @param {boolean} restoreSelection - if true, restore saved selection
+ */
+ clearSelection(e, t = !1) {
+ const { BlockManager: o, Caret: i, RectangleSelection: s } = this.Editor;
+ this.needToSelectAll = !1, this.nativeInputSelected = !1, this.readyToBlockSelection = !1;
+ const r = e && e instanceof KeyboardEvent, a = r && Po(e.keyCode);
+ if (this.anyBlockSelected && r && a && !b.isSelectionExists) {
+ const l = o.removeSelectedBlocks();
+ o.insertDefaultBlockAtIndex(l, !0), i.setToBlock(o.currentBlock), Fe(() => {
+ const c = e.key;
+ i.insertContentAtCaretPosition(c.length > 1 ? "" : c);
+ }, 20)();
+ }
+ if (this.Editor.CrossBlockSelection.clear(e), !this.anyBlockSelected || s.isRectActivated()) {
+ this.Editor.RectangleSelection.clearSelection();
+ return;
+ }
+ t && this.selection.restore(), this.allBlocksSelected = !1;
+ }
+ /**
+ * Reduce each Block and copy its content
+ *
+ * @param {ClipboardEvent} e - copy/cut event
+ * @returns {Promise}
+ */
+ copySelectedBlocks(e) {
+ e.preventDefault();
+ const t = d.make("div");
+ this.selectedBlocks.forEach((s) => {
+ const r = Z(s.holder.innerHTML, this.sanitizerConfig), a = d.make("p");
+ a.innerHTML = r, t.appendChild(a);
+ });
+ const o = Array.from(t.childNodes).map((s) => s.textContent).join(`
+
+`), i = t.innerHTML;
+ return e.clipboardData.setData("text/plain", o), e.clipboardData.setData("text/html", i), Promise.all(this.selectedBlocks.map((s) => s.save())).then((s) => {
+ try {
+ e.clipboardData.setData(this.Editor.Paste.MIME_TYPE, JSON.stringify(s));
+ } catch {
+ }
+ });
+ }
+ /**
+ * Select Block by its index
+ *
+ * @param {number?} index - Block index according to the BlockManager's indexes
+ */
+ selectBlockByIndex(e) {
+ const { BlockManager: t } = this.Editor, o = t.getBlockByIndex(e);
+ o !== void 0 && this.selectBlock(o);
+ }
+ /**
+ * Select passed Block
+ *
+ * @param {Block} block - Block to select
+ */
+ selectBlock(e) {
+ this.selection.save(), b.get().removeAllRanges(), e.selected = !0, this.clearCache(), this.Editor.InlineToolbar.close();
+ }
+ /**
+ * Remove selection from passed Block
+ *
+ * @param {Block} block - Block to unselect
+ */
+ unselectBlock(e) {
+ e.selected = !1, this.clearCache();
+ }
+ /**
+ * Clear anyBlockSelected cache
+ */
+ clearCache() {
+ this.anyBlockSelectedCache = null;
+ }
+ /**
+ * Module destruction
+ * De-registers Shortcut CMD+A
+ */
+ destroy() {
+ ge.remove(this.Editor.UI.nodes.redactor, "CMD+A");
+ }
+ /**
+ * First CMD+A selects all input content by native behaviour,
+ * next CMD+A keypress selects all blocks
+ *
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ handleCommandA(e) {
+ if (this.Editor.RectangleSelection.clearSelection(), d.isNativeInput(e.target) && !this.readyToBlockSelection) {
+ this.readyToBlockSelection = !0;
+ return;
+ }
+ const t = this.Editor.BlockManager.getBlock(e.target), o = t.inputs;
+ if (o.length > 1 && !this.readyToBlockSelection) {
+ this.readyToBlockSelection = !0;
+ return;
+ }
+ if (o.length === 1 && !this.needToSelectAll) {
+ this.needToSelectAll = !0;
+ return;
+ }
+ this.needToSelectAll ? (e.preventDefault(), this.selectAllBlocks(), this.needToSelectAll = !1, this.readyToBlockSelection = !1) : this.readyToBlockSelection && (e.preventDefault(), this.selectBlock(t), this.needToSelectAll = !0);
+ }
+ /**
+ * Select All Blocks
+ * Each Block has selected setter that makes Block copyable
+ */
+ selectAllBlocks() {
+ this.selection.save(), b.get().removeAllRanges(), this.allBlocksSelected = !0, this.Editor.InlineToolbar.close();
+ }
+}
+class Ye extends E {
+ /**
+ * Allowed caret positions in input
+ *
+ * @static
+ * @returns {{START: string, END: string, DEFAULT: string}}
+ */
+ get positions() {
+ return {
+ START: "start",
+ END: "end",
+ DEFAULT: "default"
+ };
+ }
+ /**
+ * Elements styles that can be useful for Caret Module
+ */
+ static get CSS() {
+ return {
+ shadowCaret: "cdx-shadow-caret"
+ };
+ }
+ /**
+ * Method gets Block instance and puts caret to the text node with offset
+ * There two ways that method applies caret position:
+ * - first found text node: sets at the beginning, but you can pass an offset
+ * - last found text node: sets at the end of the node. Also, you can customize the behaviour
+ *
+ * @param {Block} block - Block class
+ * @param {string} position - position where to set caret.
+ * If default - leave default behaviour and apply offset if it's passed
+ * @param {number} offset - caret offset regarding to the text node
+ */
+ setToBlock(e, t = this.positions.DEFAULT, o = 0) {
+ var c;
+ const { BlockManager: i, BlockSelection: s } = this.Editor;
+ if (s.clearSelection(), !e.focusable) {
+ (c = window.getSelection()) == null || c.removeAllRanges(), s.selectBlock(e), i.currentBlock = e;
+ return;
+ }
+ let r;
+ switch (t) {
+ case this.positions.START:
+ r = e.firstInput;
+ break;
+ case this.positions.END:
+ r = e.lastInput;
+ break;
+ default:
+ r = e.currentInput;
+ }
+ if (!r)
+ return;
+ const a = d.getDeepestNode(r, t === this.positions.END), l = d.getContentLength(a);
+ switch (!0) {
+ case t === this.positions.START:
+ o = 0;
+ break;
+ case t === this.positions.END:
+ case o > l:
+ o = l;
+ break;
+ }
+ this.set(a, o), i.setCurrentBlockByChildNode(e.holder), i.currentBlock.currentInput = r;
+ }
+ /**
+ * Set caret to the current input of current Block.
+ *
+ * @param {HTMLElement} input - input where caret should be set
+ * @param {string} position - position of the caret.
+ * If default - leave default behaviour and apply offset if it's passed
+ * @param {number} offset - caret offset regarding to the text node
+ */
+ setToInput(e, t = this.positions.DEFAULT, o = 0) {
+ const { currentBlock: i } = this.Editor.BlockManager, s = d.getDeepestNode(e);
+ switch (t) {
+ case this.positions.START:
+ this.set(s, 0);
+ break;
+ case this.positions.END:
+ this.set(s, d.getContentLength(s));
+ break;
+ default:
+ o && this.set(s, o);
+ }
+ i.currentInput = e;
+ }
+ /**
+ * Creates Document Range and sets caret to the element with offset
+ *
+ * @param {HTMLElement} element - target node.
+ * @param {number} offset - offset
+ */
+ set(e, t = 0) {
+ const { top: i, bottom: s } = b.setCursor(e, t), { innerHeight: r } = window;
+ i < 0 ? window.scrollBy(0, i - 30) : s > r && window.scrollBy(0, s - r + 30);
+ }
+ /**
+ * Set Caret to the last Block
+ * If last block is not empty, append another empty block
+ */
+ setToTheLastBlock() {
+ const e = this.Editor.BlockManager.lastBlock;
+ if (e)
+ if (e.tool.isDefault && e.isEmpty)
+ this.setToBlock(e);
+ else {
+ const t = this.Editor.BlockManager.insertAtEnd();
+ this.setToBlock(t);
+ }
+ }
+ /**
+ * Extract content fragment of current Block from Caret position to the end of the Block
+ */
+ extractFragmentFromCaretPosition() {
+ const e = b.get();
+ if (e.rangeCount) {
+ const t = e.getRangeAt(0), o = this.Editor.BlockManager.currentBlock.currentInput;
+ if (t.deleteContents(), o)
+ if (d.isNativeInput(o)) {
+ const i = o, s = document.createDocumentFragment(), r = i.value.substring(0, i.selectionStart), a = i.value.substring(i.selectionStart);
+ return s.textContent = a, i.value = r, s;
+ } else {
+ const i = t.cloneRange();
+ return i.selectNodeContents(o), i.setStart(t.endContainer, t.endOffset), i.extractContents();
+ }
+ }
+ }
+ /**
+ * Set's caret to the next Block or Tool`s input
+ * Before moving caret, we should check if caret position is at the end of Plugins node
+ * Using {@link Dom#getDeepestNode} to get a last node and match with current selection
+ *
+ * @param {boolean} force - pass true to skip check for caret position
+ */
+ navigateNext(e = !1) {
+ const { BlockManager: t } = this.Editor, { currentBlock: o, nextBlock: i } = t;
+ if (o === void 0)
+ return !1;
+ const { nextInput: s, currentInput: r } = o, a = r !== void 0 ? Re(r) : void 0;
+ let l = i;
+ const c = e || a || !o.focusable;
+ if (s && c)
+ return this.setToInput(s, this.positions.START), !0;
+ if (l === null) {
+ if (o.tool.isDefault || !c)
+ return !1;
+ l = t.insertAtEnd();
+ }
+ return c ? (this.setToBlock(l, this.positions.START), !0) : !1;
+ }
+ /**
+ * Set's caret to the previous Tool`s input or Block
+ * Before moving caret, we should check if caret position is start of the Plugins node
+ * Using {@link Dom#getDeepestNode} to get a last node and match with current selection
+ *
+ * @param {boolean} force - pass true to skip check for caret position
+ */
+ navigatePrevious(e = !1) {
+ const { currentBlock: t, previousBlock: o } = this.Editor.BlockManager;
+ if (!t)
+ return !1;
+ const { previousInput: i, currentInput: s } = t, r = s !== void 0 ? Ne(s) : void 0, a = e || r || !t.focusable;
+ return i && a ? (this.setToInput(i, this.positions.END), !0) : o !== null && a ? (this.setToBlock(o, this.positions.END), !0) : !1;
+ }
+ /**
+ * Inserts shadow element after passed element where caret can be placed
+ *
+ * @param {Element} element - element after which shadow caret should be inserted
+ */
+ createShadow(e) {
+ const t = document.createElement("span");
+ t.classList.add(Ye.CSS.shadowCaret), e.insertAdjacentElement("beforeend", t);
+ }
+ /**
+ * Restores caret position
+ *
+ * @param {HTMLElement} element - element where caret should be restored
+ */
+ restoreCaret(e) {
+ const t = e.querySelector(`.${Ye.CSS.shadowCaret}`);
+ if (!t)
+ return;
+ new b().expandToTag(t);
+ const i = document.createRange();
+ i.selectNode(t), i.extractContents();
+ }
+ /**
+ * Inserts passed content at caret position
+ *
+ * @param {string} content - content to insert
+ */
+ insertContentAtCaretPosition(e) {
+ const t = document.createDocumentFragment(), o = document.createElement("div"), i = b.get(), s = b.range;
+ o.innerHTML = e, Array.from(o.childNodes).forEach((c) => t.appendChild(c)), t.childNodes.length === 0 && t.appendChild(new Text());
+ const r = t.lastChild;
+ s.deleteContents(), s.insertNode(t);
+ const a = document.createRange(), l = r.nodeType === Node.TEXT_NODE ? r : r.firstChild;
+ l !== null && l.textContent !== null && a.setStart(l, l.textContent.length), i.removeAllRanges(), i.addRange(a);
+ }
+}
+class la extends E {
+ constructor() {
+ super(...arguments), this.onMouseUp = () => {
+ this.listeners.off(document, "mouseover", this.onMouseOver), this.listeners.off(document, "mouseup", this.onMouseUp);
+ }, this.onMouseOver = (e) => {
+ const { BlockManager: t, BlockSelection: o } = this.Editor;
+ if (e.relatedTarget === null && e.target === null)
+ return;
+ const i = t.getBlockByChildNode(e.relatedTarget) || this.lastSelectedBlock, s = t.getBlockByChildNode(e.target);
+ if (!(!i || !s) && s !== i) {
+ if (i === this.firstSelectedBlock) {
+ b.get().removeAllRanges(), i.selected = !0, s.selected = !0, o.clearCache();
+ return;
+ }
+ if (s === this.firstSelectedBlock) {
+ i.selected = !1, s.selected = !1, o.clearCache();
+ return;
+ }
+ this.Editor.InlineToolbar.close(), this.toggleBlocksSelectedState(i, s), this.lastSelectedBlock = s;
+ }
+ };
+ }
+ /**
+ * Module preparation
+ *
+ * @returns {Promise}
+ */
+ async prepare() {
+ this.listeners.on(document, "mousedown", (e) => {
+ this.enableCrossBlockSelection(e);
+ });
+ }
+ /**
+ * Sets up listeners
+ *
+ * @param {MouseEvent} event - mouse down event
+ */
+ watchSelection(e) {
+ if (e.button !== qn.LEFT)
+ return;
+ const { BlockManager: t } = this.Editor;
+ this.firstSelectedBlock = t.getBlock(e.target), this.lastSelectedBlock = this.firstSelectedBlock, this.listeners.on(document, "mouseover", this.onMouseOver), this.listeners.on(document, "mouseup", this.onMouseUp);
+ }
+ /**
+ * Return boolean is cross block selection started:
+ * there should be at least 2 selected blocks
+ */
+ get isCrossBlockSelectionStarted() {
+ return !!this.firstSelectedBlock && !!this.lastSelectedBlock && this.firstSelectedBlock !== this.lastSelectedBlock;
+ }
+ /**
+ * Change selection state of the next Block
+ * Used for CBS via Shift + arrow keys
+ *
+ * @param {boolean} next - if true, toggle next block. Previous otherwise
+ */
+ toggleBlockSelectedState(e = !0) {
+ const { BlockManager: t, BlockSelection: o } = this.Editor;
+ this.lastSelectedBlock || (this.lastSelectedBlock = this.firstSelectedBlock = t.currentBlock), this.firstSelectedBlock === this.lastSelectedBlock && (this.firstSelectedBlock.selected = !0, o.clearCache(), b.get().removeAllRanges());
+ const i = t.blocks.indexOf(this.lastSelectedBlock) + (e ? 1 : -1), s = t.blocks[i];
+ s && (this.lastSelectedBlock.selected !== s.selected ? (s.selected = !0, o.clearCache()) : (this.lastSelectedBlock.selected = !1, o.clearCache()), this.lastSelectedBlock = s, this.Editor.InlineToolbar.close(), s.holder.scrollIntoView({
+ block: "nearest"
+ }));
+ }
+ /**
+ * Clear saved state
+ *
+ * @param {Event} reason - event caused clear of selection
+ */
+ clear(e) {
+ const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor, s = t.blocks.indexOf(this.firstSelectedBlock), r = t.blocks.indexOf(this.lastSelectedBlock);
+ if (o.anyBlockSelected && s > -1 && r > -1 && e && e instanceof KeyboardEvent)
+ switch (e.keyCode) {
+ case y.DOWN:
+ case y.RIGHT:
+ i.setToBlock(t.blocks[Math.max(s, r)], i.positions.END);
+ break;
+ case y.UP:
+ case y.LEFT:
+ i.setToBlock(t.blocks[Math.min(s, r)], i.positions.START);
+ break;
+ default:
+ i.setToBlock(t.blocks[Math.max(s, r)], i.positions.END);
+ }
+ this.firstSelectedBlock = this.lastSelectedBlock = null;
+ }
+ /**
+ * Enables Cross Block Selection
+ *
+ * @param {MouseEvent} event - mouse down event
+ */
+ enableCrossBlockSelection(e) {
+ const { UI: t } = this.Editor;
+ b.isCollapsed || this.Editor.BlockSelection.clearSelection(e), t.nodes.redactor.contains(e.target) ? this.watchSelection(e) : this.Editor.BlockSelection.clearSelection(e);
+ }
+ /**
+ * Change blocks selection state between passed two blocks.
+ *
+ * @param {Block} firstBlock - first block in range
+ * @param {Block} lastBlock - last block in range
+ */
+ toggleBlocksSelectedState(e, t) {
+ const { BlockManager: o, BlockSelection: i } = this.Editor, s = o.blocks.indexOf(e), r = o.blocks.indexOf(t), a = e.selected !== t.selected;
+ for (let l = Math.min(s, r); l <= Math.max(s, r); l++) {
+ const c = o.blocks[l];
+ c !== this.firstSelectedBlock && c !== (a ? e : t) && (o.blocks[l].selected = !o.blocks[l].selected, i.clearCache());
+ }
+ }
+}
+class ca extends E {
+ constructor() {
+ super(...arguments), this.isStartedAtEditor = !1;
+ }
+ /**
+ * Toggle read-only state
+ *
+ * if state is true:
+ * - disable all drag-n-drop event handlers
+ *
+ * if state is false:
+ * - restore drag-n-drop event handlers
+ *
+ * @param {boolean} readOnlyEnabled - "read only" state
+ */
+ toggleReadOnly(e) {
+ e ? this.disableModuleBindings() : this.enableModuleBindings();
+ }
+ /**
+ * Add drag events listeners to editor zone
+ */
+ enableModuleBindings() {
+ const { UI: e } = this.Editor;
+ this.readOnlyMutableListeners.on(e.nodes.holder, "drop", async (t) => {
+ await this.processDrop(t);
+ }, !0), this.readOnlyMutableListeners.on(e.nodes.holder, "dragstart", () => {
+ this.processDragStart();
+ }), this.readOnlyMutableListeners.on(e.nodes.holder, "dragover", (t) => {
+ this.processDragOver(t);
+ }, !0);
+ }
+ /**
+ * Unbind drag-n-drop event handlers
+ */
+ disableModuleBindings() {
+ this.readOnlyMutableListeners.clearAll();
+ }
+ /**
+ * Handle drop event
+ *
+ * @param {DragEvent} dropEvent - drop event
+ */
+ async processDrop(e) {
+ const {
+ BlockManager: t,
+ Paste: o,
+ Caret: i
+ } = this.Editor;
+ e.preventDefault(), t.blocks.forEach((r) => {
+ r.dropTarget = !1;
+ }), b.isAtEditor && !b.isCollapsed && this.isStartedAtEditor && document.execCommand("delete"), this.isStartedAtEditor = !1;
+ const s = t.setCurrentBlockByChildNode(e.target);
+ if (s)
+ this.Editor.Caret.setToBlock(s, i.positions.END);
+ else {
+ const r = t.setCurrentBlockByChildNode(t.lastBlock.holder);
+ this.Editor.Caret.setToBlock(r, i.positions.END);
+ }
+ await o.processDataTransfer(e.dataTransfer, !0);
+ }
+ /**
+ * Handle drag start event
+ */
+ processDragStart() {
+ b.isAtEditor && !b.isCollapsed && (this.isStartedAtEditor = !0), this.Editor.InlineToolbar.close();
+ }
+ /**
+ * @param {DragEvent} dragEvent - drag event
+ */
+ processDragOver(e) {
+ e.preventDefault();
+ }
+}
+const da = 180, ua = 400;
+class ha extends E {
+ /**
+ * Prepare the module
+ *
+ * @param options - options used by the modification observer module
+ * @param options.config - Editor configuration object
+ * @param options.eventsDispatcher - common Editor event bus
+ */
+ constructor({ config: e, eventsDispatcher: t }) {
+ super({
+ config: e,
+ eventsDispatcher: t
+ }), this.disabled = !1, this.batchingTimeout = null, this.batchingOnChangeQueue = /* @__PURE__ */ new Map(), this.batchTime = ua, this.mutationObserver = new MutationObserver((o) => {
+ this.redactorChanged(o);
+ }), this.eventsDispatcher.on($o, (o) => {
+ this.particularBlockChanged(o.event);
+ }), this.eventsDispatcher.on(zo, () => {
+ this.disable();
+ }), this.eventsDispatcher.on(Uo, () => {
+ this.enable();
+ });
+ }
+ /**
+ * Enables onChange event
+ */
+ enable() {
+ this.mutationObserver.observe(
+ this.Editor.UI.nodes.redactor,
+ {
+ childList: !0,
+ subtree: !0,
+ characterData: !0,
+ attributes: !0
+ }
+ ), this.disabled = !1;
+ }
+ /**
+ * Disables onChange event
+ */
+ disable() {
+ this.mutationObserver.disconnect(), this.disabled = !0;
+ }
+ /**
+ * Call onChange event passed to Editor.js configuration
+ *
+ * @param event - some of our custom change events
+ */
+ particularBlockChanged(e) {
+ this.disabled || !A(this.config.onChange) || (this.batchingOnChangeQueue.set(`block:${e.detail.target.id}:event:${e.type}`, e), this.batchingTimeout && clearTimeout(this.batchingTimeout), this.batchingTimeout = setTimeout(() => {
+ let t;
+ this.batchingOnChangeQueue.size === 1 ? t = this.batchingOnChangeQueue.values().next().value : t = Array.from(this.batchingOnChangeQueue.values()), this.config.onChange && this.config.onChange(this.Editor.API.methods, t), this.batchingOnChangeQueue.clear();
+ }, this.batchTime));
+ }
+ /**
+ * Fired on every blocks wrapper dom change
+ *
+ * @param mutations - mutations happened
+ */
+ redactorChanged(e) {
+ this.eventsDispatcher.emit(ft, {
+ mutations: e
+ });
+ }
+}
+const Rn = class Dn extends E {
+ constructor() {
+ super(...arguments), this.MIME_TYPE = "application/x-editor-js", this.toolsTags = {}, this.tagsByTool = {}, this.toolsPatterns = [], this.toolsFiles = {}, this.exceptionList = [], this.processTool = (e) => {
+ try {
+ const t = e.create({}, {}, !1);
+ if (e.pasteConfig === !1) {
+ this.exceptionList.push(e.name);
+ return;
+ }
+ if (!A(t.onPaste))
+ return;
+ this.getTagsConfig(e), this.getFilesConfig(e), this.getPatternsConfig(e);
+ } catch (t) {
+ S(
+ `Paste handling for «${e.name}» Tool hasn't been set up because of the error`,
+ "warn",
+ t
+ );
+ }
+ }, this.handlePasteEvent = async (e) => {
+ const { BlockManager: t, Toolbar: o } = this.Editor, i = t.setCurrentBlockByChildNode(e.target);
+ !i || this.isNativeBehaviour(e.target) && !e.clipboardData.types.includes("Files") || i && this.exceptionList.includes(i.name) || (e.preventDefault(), this.processDataTransfer(e.clipboardData), o.close());
+ };
+ }
+ /**
+ * Set onPaste callback and collect tools` paste configurations
+ */
+ async prepare() {
+ this.processTools();
+ }
+ /**
+ * Set read-only state
+ *
+ * @param {boolean} readOnlyEnabled - read only flag value
+ */
+ toggleReadOnly(e) {
+ e ? this.unsetCallback() : this.setCallback();
+ }
+ /**
+ * Handle pasted or dropped data transfer object
+ *
+ * @param {DataTransfer} dataTransfer - pasted or dropped data transfer object
+ * @param {boolean} isDragNDrop - true if data transfer comes from drag'n'drop events
+ */
+ async processDataTransfer(e, t = !1) {
+ const { Tools: o } = this.Editor, i = e.types;
+ if ((i.includes ? i.includes("Files") : i.contains("Files")) && !V(this.toolsFiles)) {
+ await this.processFiles(e.files);
+ return;
+ }
+ const r = e.getData(this.MIME_TYPE), a = e.getData("text/plain");
+ let l = e.getData("text/html");
+ if (r)
+ try {
+ this.insertEditorJSData(JSON.parse(r));
+ return;
+ } catch {
+ }
+ t && a.trim() && l.trim() && (l = "" + (l.trim() ? l : a) + "
");
+ const c = Object.keys(this.toolsTags).reduce((p, g) => (p[g.toLowerCase()] = this.toolsTags[g].sanitizationConfig ?? {}, p), {}), u = Object.assign({}, c, o.getAllInlineToolsSanitizeConfig(), { br: {} }), h = Z(l, u);
+ !h.trim() || h.trim() === a || !d.isHTMLString(h) ? await this.processText(a) : await this.processText(h, !0);
+ }
+ /**
+ * Process pasted text and divide them into Blocks
+ *
+ * @param {string} data - text to process. Can be HTML or plain.
+ * @param {boolean} isHTML - if passed string is HTML, this parameter should be true
+ */
+ async processText(e, t = !1) {
+ const { Caret: o, BlockManager: i } = this.Editor, s = t ? this.processHTML(e) : this.processPlain(e);
+ if (!s.length)
+ return;
+ if (s.length === 1) {
+ s[0].isBlock ? this.processSingleBlock(s.pop()) : this.processInlinePaste(s.pop());
+ return;
+ }
+ const a = i.currentBlock && i.currentBlock.tool.isDefault && i.currentBlock.isEmpty;
+ s.map(
+ async (l, c) => this.insertBlock(l, c === 0 && a)
+ ), i.currentBlock && o.setToBlock(i.currentBlock, o.positions.END);
+ }
+ /**
+ * Set onPaste callback handler
+ */
+ setCallback() {
+ this.listeners.on(this.Editor.UI.nodes.holder, "paste", this.handlePasteEvent);
+ }
+ /**
+ * Unset onPaste callback handler
+ */
+ unsetCallback() {
+ this.listeners.off(this.Editor.UI.nodes.holder, "paste", this.handlePasteEvent);
+ }
+ /**
+ * Get and process tool`s paste configs
+ */
+ processTools() {
+ const e = this.Editor.Tools.blockTools;
+ Array.from(e.values()).forEach(this.processTool);
+ }
+ /**
+ * Get tags name list from either tag name or sanitization config.
+ *
+ * @param {string | object} tagOrSanitizeConfig - tag name or sanitize config object.
+ * @returns {string[]} array of tags.
+ */
+ collectTagNames(e) {
+ return te(e) ? [e] : D(e) ? Object.keys(e) : [];
+ }
+ /**
+ * Get tags to substitute by Tool
+ *
+ * @param tool - BlockTool object
+ */
+ getTagsConfig(e) {
+ if (e.pasteConfig === !1)
+ return;
+ const t = e.pasteConfig.tags || [], o = [];
+ t.forEach((i) => {
+ const s = this.collectTagNames(i);
+ o.push(...s), s.forEach((r) => {
+ if (Object.prototype.hasOwnProperty.call(this.toolsTags, r)) {
+ S(
+ `Paste handler for «${e.name}» Tool on «${r}» tag is skipped because it is already used by «${this.toolsTags[r].tool.name}» Tool.`,
+ "warn"
+ );
+ return;
+ }
+ const a = D(i) ? i[r] : null;
+ this.toolsTags[r.toUpperCase()] = {
+ tool: e,
+ sanitizationConfig: a
+ };
+ });
+ }), this.tagsByTool[e.name] = o.map((i) => i.toUpperCase());
+ }
+ /**
+ * Get files` types and extensions to substitute by Tool
+ *
+ * @param tool - BlockTool object
+ */
+ getFilesConfig(e) {
+ if (e.pasteConfig === !1)
+ return;
+ const { files: t = {} } = e.pasteConfig;
+ let { extensions: o, mimeTypes: i } = t;
+ !o && !i || (o && !Array.isArray(o) && (S(`«extensions» property of the onDrop config for «${e.name}» Tool should be an array`), o = []), i && !Array.isArray(i) && (S(`«mimeTypes» property of the onDrop config for «${e.name}» Tool should be an array`), i = []), i && (i = i.filter((s) => ei(s) ? !0 : (S(`MIME type value «${s}» for the «${e.name}» Tool is not a valid MIME type`, "warn"), !1))), this.toolsFiles[e.name] = {
+ extensions: o || [],
+ mimeTypes: i || []
+ });
+ }
+ /**
+ * Get RegExp patterns to substitute by Tool
+ *
+ * @param tool - BlockTool object
+ */
+ getPatternsConfig(e) {
+ e.pasteConfig === !1 || !e.pasteConfig.patterns || V(e.pasteConfig.patterns) || Object.entries(e.pasteConfig.patterns).forEach(([t, o]) => {
+ o instanceof RegExp || S(
+ `Pattern ${o} for «${e.name}» Tool is skipped because it should be a Regexp instance.`,
+ "warn"
+ ), this.toolsPatterns.push({
+ key: t,
+ pattern: o,
+ tool: e
+ });
+ });
+ }
+ /**
+ * Check if browser behavior suits better
+ *
+ * @param {EventTarget} element - element where content has been pasted
+ * @returns {boolean}
+ */
+ isNativeBehaviour(e) {
+ return d.isNativeInput(e);
+ }
+ /**
+ * Get files from data transfer object and insert related Tools
+ *
+ * @param {FileList} items - pasted or dropped items
+ */
+ async processFiles(e) {
+ const { BlockManager: t } = this.Editor;
+ let o;
+ o = await Promise.all(
+ Array.from(e).map((r) => this.processFile(r))
+ ), o = o.filter((r) => !!r);
+ const s = t.currentBlock.tool.isDefault && t.currentBlock.isEmpty;
+ o.forEach(
+ (r, a) => {
+ t.paste(r.type, r.event, a === 0 && s);
+ }
+ );
+ }
+ /**
+ * Get information about file and find Tool to handle it
+ *
+ * @param {File} file - file to process
+ */
+ async processFile(e) {
+ const t = Jn(e), o = Object.entries(this.toolsFiles).find(([r, { mimeTypes: a, extensions: l }]) => {
+ const [c, u] = e.type.split("/"), h = l.find((g) => g.toLowerCase() === t.toLowerCase()), p = a.find((g) => {
+ const [f, v] = g.split("/");
+ return f === c && (v === u || v === "*");
+ });
+ return !!h || !!p;
+ });
+ if (!o)
+ return;
+ const [i] = o;
+ return {
+ event: this.composePasteEvent("file", {
+ file: e
+ }),
+ type: i
+ };
+ }
+ /**
+ * Split HTML string to blocks and return it as array of Block data
+ *
+ * @param {string} innerHTML - html string to process
+ * @returns {PasteData[]}
+ */
+ processHTML(e) {
+ const { Tools: t } = this.Editor, o = d.make("DIV");
+ return o.innerHTML = e, this.getNodes(o).map((s) => {
+ let r, a = t.defaultTool, l = !1;
+ switch (s.nodeType) {
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ r = d.make("div"), r.appendChild(s);
+ break;
+ case Node.ELEMENT_NODE:
+ r = s, l = !0, this.toolsTags[r.tagName] && (a = this.toolsTags[r.tagName].tool);
+ break;
+ }
+ const { tags: c } = a.pasteConfig || { tags: [] }, u = c.reduce((g, f) => (this.collectTagNames(f).forEach((O) => {
+ const T = D(f) ? f[O] : null;
+ g[O.toLowerCase()] = T || {};
+ }), g), {}), h = Object.assign({}, u, a.baseSanitizeConfig);
+ if (r.tagName.toLowerCase() === "table") {
+ const g = Z(r.outerHTML, h);
+ r = d.make("div", void 0, {
+ innerHTML: g
+ }).firstChild;
+ } else
+ r.innerHTML = Z(r.innerHTML, h);
+ const p = this.composePasteEvent("tag", {
+ data: r
+ });
+ return {
+ content: r,
+ isBlock: l,
+ tool: a.name,
+ event: p
+ };
+ }).filter((s) => {
+ const r = d.isEmpty(s.content), a = d.isSingleTag(s.content);
+ return !r || a;
+ });
+ }
+ /**
+ * Split plain text by new line symbols and return it as array of Block data
+ *
+ * @param {string} plain - string to process
+ * @returns {PasteData[]}
+ */
+ processPlain(e) {
+ const { defaultBlock: t } = this.config;
+ if (!e)
+ return [];
+ const o = t;
+ return e.split(/\r?\n/).filter((i) => i.trim()).map((i) => {
+ const s = d.make("div");
+ s.textContent = i;
+ const r = this.composePasteEvent("tag", {
+ data: s
+ });
+ return {
+ content: s,
+ tool: o,
+ isBlock: !1,
+ event: r
+ };
+ });
+ }
+ /**
+ * Process paste of single Block tool content
+ *
+ * @param {PasteData} dataToInsert - data of Block to insert
+ */
+ async processSingleBlock(e) {
+ const { Caret: t, BlockManager: o } = this.Editor, { currentBlock: i } = o;
+ if (!i || e.tool !== i.name || !d.containsOnlyInlineElements(e.content.innerHTML)) {
+ this.insertBlock(e, (i == null ? void 0 : i.tool.isDefault) && i.isEmpty);
+ return;
+ }
+ t.insertContentAtCaretPosition(e.content.innerHTML);
+ }
+ /**
+ * Process paste to single Block:
+ * 1. Find patterns` matches
+ * 2. Insert new block if it is not the same type as current one
+ * 3. Just insert text if there is no substitutions
+ *
+ * @param {PasteData} dataToInsert - data of Block to insert
+ */
+ async processInlinePaste(e) {
+ const { BlockManager: t, Caret: o } = this.Editor, { content: i } = e;
+ if (t.currentBlock && t.currentBlock.tool.isDefault && i.textContent.length < Dn.PATTERN_PROCESSING_MAX_LENGTH) {
+ const r = await this.processPattern(i.textContent);
+ if (r) {
+ const a = t.currentBlock && t.currentBlock.tool.isDefault && t.currentBlock.isEmpty, l = t.paste(r.tool, r.event, a);
+ o.setToBlock(l, o.positions.END);
+ return;
+ }
+ }
+ if (t.currentBlock && t.currentBlock.currentInput) {
+ const r = t.currentBlock.tool.baseSanitizeConfig;
+ document.execCommand(
+ "insertHTML",
+ !1,
+ Z(i.innerHTML, r)
+ );
+ } else
+ this.insertBlock(e);
+ }
+ /**
+ * Get patterns` matches
+ *
+ * @param {string} text - text to process
+ * @returns {Promise<{event: PasteEvent, tool: string}>}
+ */
+ async processPattern(e) {
+ const t = this.toolsPatterns.find((i) => {
+ const s = i.pattern.exec(e);
+ return s ? e === s.shift() : !1;
+ });
+ return t ? {
+ event: this.composePasteEvent("pattern", {
+ key: t.key,
+ data: e
+ }),
+ tool: t.tool.name
+ } : void 0;
+ }
+ /**
+ * Insert pasted Block content to Editor
+ *
+ * @param {PasteData} data - data to insert
+ * @param {boolean} canReplaceCurrentBlock - if true and is current Block is empty, will replace current Block
+ * @returns {void}
+ */
+ insertBlock(e, t = !1) {
+ const { BlockManager: o, Caret: i } = this.Editor, { currentBlock: s } = o;
+ let r;
+ if (t && s && s.isEmpty) {
+ r = o.paste(e.tool, e.event, !0), i.setToBlock(r, i.positions.END);
+ return;
+ }
+ r = o.paste(e.tool, e.event), i.setToBlock(r, i.positions.END);
+ }
+ /**
+ * Insert data passed as application/x-editor-js JSON
+ *
+ * @param {Array} blocks — Blocks' data to insert
+ * @returns {void}
+ */
+ insertEditorJSData(e) {
+ const { BlockManager: t, Caret: o, Tools: i } = this.Editor;
+ yt(
+ e,
+ (r) => i.blockTools.get(r).sanitizeConfig
+ ).forEach(({ tool: r, data: a }, l) => {
+ let c = !1;
+ l === 0 && (c = t.currentBlock && t.currentBlock.tool.isDefault && t.currentBlock.isEmpty);
+ const u = t.insert({
+ tool: r,
+ data: a,
+ replace: c
+ });
+ o.setToBlock(u, o.positions.END);
+ });
+ }
+ /**
+ * Fetch nodes from Element node
+ *
+ * @param {Node} node - current node
+ * @param {Node[]} nodes - processed nodes
+ * @param {Node} destNode - destination node
+ */
+ processElementNode(e, t, o) {
+ const i = Object.keys(this.toolsTags), s = e, { tool: r } = this.toolsTags[s.tagName] || {}, a = this.tagsByTool[r == null ? void 0 : r.name] || [], l = i.includes(s.tagName), c = d.blockElements.includes(s.tagName.toLowerCase()), u = Array.from(s.children).some(
+ ({ tagName: p }) => i.includes(p) && !a.includes(p)
+ ), h = Array.from(s.children).some(
+ ({ tagName: p }) => d.blockElements.includes(p.toLowerCase())
+ );
+ if (!c && !l && !u)
+ return o.appendChild(s), [...t, o];
+ if (l && !u || c && !h && !u)
+ return [...t, o, s];
+ }
+ /**
+ * Recursively divide HTML string to two types of nodes:
+ * 1. Block element
+ * 2. Document Fragments contained text and markup tags like a, b, i etc.
+ *
+ * @param {Node} wrapper - wrapper of paster HTML content
+ * @returns {Node[]}
+ */
+ getNodes(e) {
+ const t = Array.from(e.childNodes);
+ let o;
+ const i = (s, r) => {
+ if (d.isEmpty(r) && !d.isSingleTag(r))
+ return s;
+ const a = s[s.length - 1];
+ let l = new DocumentFragment();
+ switch (a && d.isFragment(a) && (l = s.pop()), r.nodeType) {
+ case Node.ELEMENT_NODE:
+ if (o = this.processElementNode(r, s, l), o)
+ return o;
+ break;
+ case Node.TEXT_NODE:
+ return l.appendChild(r), [...s, l];
+ default:
+ return [...s, l];
+ }
+ return [...s, ...Array.from(r.childNodes).reduce(i, [])];
+ };
+ return t.reduce(i, []);
+ }
+ /**
+ * Compose paste event with passed type and detail
+ *
+ * @param {string} type - event type
+ * @param {PasteEventDetail} detail - event detail
+ */
+ composePasteEvent(e, t) {
+ return new CustomEvent(e, {
+ detail: t
+ });
+ }
+};
+Rn.PATTERN_PROCESSING_MAX_LENGTH = 450;
+let pa = Rn;
+class fa extends E {
+ constructor() {
+ super(...arguments), this.toolsDontSupportReadOnly = [], this.readOnlyEnabled = !1;
+ }
+ /**
+ * Returns state of read only mode
+ */
+ get isEnabled() {
+ return this.readOnlyEnabled;
+ }
+ /**
+ * Set initial state
+ */
+ async prepare() {
+ const { Tools: e } = this.Editor, { blockTools: t } = e, o = [];
+ Array.from(t.entries()).forEach(([i, s]) => {
+ s.isReadOnlySupported || o.push(i);
+ }), this.toolsDontSupportReadOnly = o, this.config.readOnly && o.length > 0 && this.throwCriticalError(), this.toggle(this.config.readOnly, !0);
+ }
+ /**
+ * Set read-only mode or toggle current state
+ * Call all Modules `toggleReadOnly` method and re-render Editor
+ *
+ * @param state - (optional) read-only state or toggle
+ * @param isInitial - (optional) true when editor is initializing
+ */
+ async toggle(e = !this.readOnlyEnabled, t = !1) {
+ e && this.toolsDontSupportReadOnly.length > 0 && this.throwCriticalError();
+ const o = this.readOnlyEnabled;
+ this.readOnlyEnabled = e;
+ for (const s in this.Editor)
+ this.Editor[s].toggleReadOnly && this.Editor[s].toggleReadOnly(e);
+ if (o === e)
+ return this.readOnlyEnabled;
+ if (t)
+ return this.readOnlyEnabled;
+ this.Editor.ModificationsObserver.disable();
+ const i = await this.Editor.Saver.save();
+ return await this.Editor.BlockManager.clear(), await this.Editor.Renderer.render(i.blocks), this.Editor.ModificationsObserver.enable(), this.readOnlyEnabled;
+ }
+ /**
+ * Throws an error about tools which don't support read-only mode
+ */
+ throwCriticalError() {
+ throw new Ho(
+ `To enable read-only mode all connected tools should support it. Tools ${this.toolsDontSupportReadOnly.join(", ")} don't support read-only mode.`
+ );
+ }
+}
+class Be extends E {
+ constructor() {
+ super(...arguments), this.isRectSelectionActivated = !1, this.SCROLL_SPEED = 3, this.HEIGHT_OF_SCROLL_ZONE = 40, this.BOTTOM_SCROLL_ZONE = 1, this.TOP_SCROLL_ZONE = 2, this.MAIN_MOUSE_BUTTON = 0, this.mousedown = !1, this.isScrolling = !1, this.inScrollZone = null, this.startX = 0, this.startY = 0, this.mouseX = 0, this.mouseY = 0, this.stackOfSelected = [], this.listenerIds = [];
+ }
+ /**
+ * CSS classes for the Block
+ *
+ * @returns {{wrapper: string, content: string}}
+ */
+ static get CSS() {
+ return {
+ overlay: "codex-editor-overlay",
+ overlayContainer: "codex-editor-overlay__container",
+ rect: "codex-editor-overlay__rectangle",
+ topScrollZone: "codex-editor-overlay__scroll-zone--top",
+ bottomScrollZone: "codex-editor-overlay__scroll-zone--bottom"
+ };
+ }
+ /**
+ * Module Preparation
+ * Creating rect and hang handlers
+ */
+ prepare() {
+ this.enableModuleBindings();
+ }
+ /**
+ * Init rect params
+ *
+ * @param {number} pageX - X coord of mouse
+ * @param {number} pageY - Y coord of mouse
+ */
+ startSelection(e, t) {
+ const o = document.elementFromPoint(e - window.pageXOffset, t - window.pageYOffset);
+ o.closest(`.${this.Editor.Toolbar.CSS.toolbar}`) || (this.Editor.BlockSelection.allBlocksSelected = !1, this.clearSelection(), this.stackOfSelected = []);
+ const s = [
+ `.${R.CSS.content}`,
+ `.${this.Editor.Toolbar.CSS.toolbar}`,
+ `.${this.Editor.InlineToolbar.CSS.inlineToolbar}`
+ ], r = o.closest("." + this.Editor.UI.CSS.editorWrapper), a = s.some((l) => !!o.closest(l));
+ !r || a || (this.mousedown = !0, this.startX = e, this.startY = t);
+ }
+ /**
+ * Clear all params to end selection
+ */
+ endSelection() {
+ this.mousedown = !1, this.startX = 0, this.startY = 0, this.overlayRectangle.style.display = "none";
+ }
+ /**
+ * is RectSelection Activated
+ */
+ isRectActivated() {
+ return this.isRectSelectionActivated;
+ }
+ /**
+ * Mark that selection is end
+ */
+ clearSelection() {
+ this.isRectSelectionActivated = !1;
+ }
+ /**
+ * Sets Module necessary event handlers
+ */
+ enableModuleBindings() {
+ const { container: e } = this.genHTML();
+ this.listeners.on(e, "mousedown", (t) => {
+ this.processMouseDown(t);
+ }, !1), this.listeners.on(document.body, "mousemove", dt((t) => {
+ this.processMouseMove(t);
+ }, 10), {
+ passive: !0
+ }), this.listeners.on(document.body, "mouseleave", () => {
+ this.processMouseLeave();
+ }), this.listeners.on(window, "scroll", dt((t) => {
+ this.processScroll(t);
+ }, 10), {
+ passive: !0
+ }), this.listeners.on(document.body, "mouseup", () => {
+ this.processMouseUp();
+ }, !1);
+ }
+ /**
+ * Handle mouse down events
+ *
+ * @param {MouseEvent} mouseEvent - mouse event payload
+ */
+ processMouseDown(e) {
+ if (e.button !== this.MAIN_MOUSE_BUTTON)
+ return;
+ e.target.closest(d.allInputsSelector) !== null || this.startSelection(e.pageX, e.pageY);
+ }
+ /**
+ * Handle mouse move events
+ *
+ * @param {MouseEvent} mouseEvent - mouse event payload
+ */
+ processMouseMove(e) {
+ this.changingRectangle(e), this.scrollByZones(e.clientY);
+ }
+ /**
+ * Handle mouse leave
+ */
+ processMouseLeave() {
+ this.clearSelection(), this.endSelection();
+ }
+ /**
+ * @param {MouseEvent} mouseEvent - mouse event payload
+ */
+ processScroll(e) {
+ this.changingRectangle(e);
+ }
+ /**
+ * Handle mouse up
+ */
+ processMouseUp() {
+ this.clearSelection(), this.endSelection();
+ }
+ /**
+ * Scroll If mouse in scroll zone
+ *
+ * @param {number} clientY - Y coord of mouse
+ */
+ scrollByZones(e) {
+ if (this.inScrollZone = null, e <= this.HEIGHT_OF_SCROLL_ZONE && (this.inScrollZone = this.TOP_SCROLL_ZONE), document.documentElement.clientHeight - e <= this.HEIGHT_OF_SCROLL_ZONE && (this.inScrollZone = this.BOTTOM_SCROLL_ZONE), !this.inScrollZone) {
+ this.isScrolling = !1;
+ return;
+ }
+ this.isScrolling || (this.scrollVertical(this.inScrollZone === this.TOP_SCROLL_ZONE ? -this.SCROLL_SPEED : this.SCROLL_SPEED), this.isScrolling = !0);
+ }
+ /**
+ * Generates required HTML elements
+ *
+ * @returns {Object}
+ */
+ genHTML() {
+ const { UI: e } = this.Editor, t = e.nodes.holder.querySelector("." + e.CSS.editorWrapper), o = d.make("div", Be.CSS.overlay, {}), i = d.make("div", Be.CSS.overlayContainer, {}), s = d.make("div", Be.CSS.rect, {});
+ return i.appendChild(s), o.appendChild(i), t.appendChild(o), this.overlayRectangle = s, {
+ container: t,
+ overlay: o
+ };
+ }
+ /**
+ * Activates scrolling if blockSelection is active and mouse is in scroll zone
+ *
+ * @param {number} speed - speed of scrolling
+ */
+ scrollVertical(e) {
+ if (!(this.inScrollZone && this.mousedown))
+ return;
+ const t = window.pageYOffset;
+ window.scrollBy(0, e), this.mouseY += window.pageYOffset - t, setTimeout(() => {
+ this.scrollVertical(e);
+ }, 0);
+ }
+ /**
+ * Handles the change in the rectangle and its effect
+ *
+ * @param {MouseEvent} event - mouse event
+ */
+ changingRectangle(e) {
+ if (!this.mousedown)
+ return;
+ e.pageY !== void 0 && (this.mouseX = e.pageX, this.mouseY = e.pageY);
+ const { rightPos: t, leftPos: o, index: i } = this.genInfoForMouseSelection(), s = this.startX > t && this.mouseX > t, r = this.startX < o && this.mouseX < o;
+ this.rectCrossesBlocks = !(s || r), this.isRectSelectionActivated || (this.rectCrossesBlocks = !1, this.isRectSelectionActivated = !0, this.shrinkRectangleToPoint(), this.overlayRectangle.style.display = "block"), this.updateRectangleSize(), this.Editor.Toolbar.close(), i !== void 0 && (this.trySelectNextBlock(i), this.inverseSelection(), b.get().removeAllRanges());
+ }
+ /**
+ * Shrink rect to singular point
+ */
+ shrinkRectangleToPoint() {
+ this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`;
+ }
+ /**
+ * Select or unselect all of blocks in array if rect is out or in selectable area
+ */
+ inverseSelection() {
+ const t = this.Editor.BlockManager.getBlockByIndex(this.stackOfSelected[0]).selected;
+ if (this.rectCrossesBlocks && !t)
+ for (const o of this.stackOfSelected)
+ this.Editor.BlockSelection.selectBlockByIndex(o);
+ if (!this.rectCrossesBlocks && t)
+ for (const o of this.stackOfSelected)
+ this.Editor.BlockSelection.unSelectBlockByIndex(o);
+ }
+ /**
+ * Updates size of rectangle
+ */
+ updateRectangleSize() {
+ this.mouseY >= this.startY ? (this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.bottom = `calc(100% - ${this.mouseY - window.pageYOffset}px`) : (this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.top = `${this.mouseY - window.pageYOffset}px`), this.mouseX >= this.startX ? (this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.right = `calc(100% - ${this.mouseX - window.pageXOffset}px`) : (this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.left = `${this.mouseX - window.pageXOffset}px`);
+ }
+ /**
+ * Collects information needed to determine the behavior of the rectangle
+ *
+ * @returns {object} index - index next Block, leftPos - start of left border of Block, rightPos - right border
+ */
+ genInfoForMouseSelection() {
+ const t = document.body.offsetWidth / 2, o = this.mouseY - window.pageYOffset, i = document.elementFromPoint(t, o), s = this.Editor.BlockManager.getBlockByChildNode(i);
+ let r;
+ s !== void 0 && (r = this.Editor.BlockManager.blocks.findIndex((h) => h.holder === s.holder));
+ const a = this.Editor.BlockManager.lastBlock.holder.querySelector("." + R.CSS.content), l = Number.parseInt(window.getComputedStyle(a).width, 10) / 2, c = t - l, u = t + l;
+ return {
+ index: r,
+ leftPos: c,
+ rightPos: u
+ };
+ }
+ /**
+ * Select block with index index
+ *
+ * @param index - index of block in redactor
+ */
+ addBlockInSelection(e) {
+ this.rectCrossesBlocks && this.Editor.BlockSelection.selectBlockByIndex(e), this.stackOfSelected.push(e);
+ }
+ /**
+ * Adds a block to the selection and determines which blocks should be selected
+ *
+ * @param {object} index - index of new block in the reactor
+ */
+ trySelectNextBlock(e) {
+ const t = this.stackOfSelected[this.stackOfSelected.length - 1] === e, o = this.stackOfSelected.length, i = 1, s = -1, r = 0;
+ if (t)
+ return;
+ const a = this.stackOfSelected[o - 1] - this.stackOfSelected[o - 2] > 0;
+ let l = r;
+ o > 1 && (l = a ? i : s);
+ const c = e > this.stackOfSelected[o - 1] && l === i, u = e < this.stackOfSelected[o - 1] && l === s, p = !(c || u || l === r);
+ if (!p && (e > this.stackOfSelected[o - 1] || this.stackOfSelected[o - 1] === void 0)) {
+ let v = this.stackOfSelected[o - 1] + 1 || e;
+ for (v; v <= e; v++)
+ this.addBlockInSelection(v);
+ return;
+ }
+ if (!p && e < this.stackOfSelected[o - 1]) {
+ for (let v = this.stackOfSelected[o - 1] - 1; v >= e; v--)
+ this.addBlockInSelection(v);
+ return;
+ }
+ if (!p)
+ return;
+ let g = o - 1, f;
+ for (e > this.stackOfSelected[o - 1] ? f = () => e > this.stackOfSelected[g] : f = () => e < this.stackOfSelected[g]; f(); )
+ this.rectCrossesBlocks && this.Editor.BlockSelection.unSelectBlockByIndex(this.stackOfSelected[g]), this.stackOfSelected.pop(), g--;
+ }
+}
+class ga extends E {
+ /**
+ * Renders passed blocks as one batch
+ *
+ * @param blocksData - blocks to render
+ */
+ async render(e) {
+ return new Promise((t) => {
+ const { Tools: o, BlockManager: i } = this.Editor;
+ if (e.length === 0)
+ i.insert();
+ else {
+ const s = e.map(({ type: r, data: a, tunes: l, id: c }) => {
+ o.available.has(r) === !1 && (X(`Tool «${r}» is not found. Check 'tools' property at the Editor.js config.`, "warn"), a = this.composeStubDataForTool(r, a, c), r = o.stubTool);
+ let u;
+ try {
+ u = i.composeBlock({
+ id: c,
+ tool: r,
+ data: a,
+ tunes: l
+ });
+ } catch (h) {
+ S(`Block «${r}» skipped because of plugins error`, "error", {
+ data: a,
+ error: h
+ }), a = this.composeStubDataForTool(r, a, c), r = o.stubTool, u = i.composeBlock({
+ id: c,
+ tool: r,
+ data: a,
+ tunes: l
+ });
+ }
+ return u;
+ });
+ i.insertMany(s);
+ }
+ window.requestIdleCallback(() => {
+ t();
+ }, { timeout: 2e3 });
+ });
+ }
+ /**
+ * Create data for the Stub Tool that will be used instead of unavailable tool
+ *
+ * @param tool - unavailable tool name to stub
+ * @param data - data of unavailable block
+ * @param [id] - id of unavailable block
+ */
+ composeStubDataForTool(e, t, o) {
+ const { Tools: i } = this.Editor;
+ let s = e;
+ if (i.unavailable.has(e)) {
+ const r = i.unavailable.get(e).toolbox;
+ r !== void 0 && r[0].title !== void 0 && (s = r[0].title);
+ }
+ return {
+ savedData: {
+ id: o,
+ type: e,
+ data: t
+ },
+ title: s
+ };
+ }
+}
+class ma extends E {
+ /**
+ * Composes new chain of Promises to fire them alternatelly
+ *
+ * @returns {OutputData}
+ */
+ async save() {
+ const { BlockManager: e, Tools: t } = this.Editor, o = e.blocks, i = [];
+ try {
+ o.forEach((a) => {
+ i.push(this.getSavedData(a));
+ });
+ const s = await Promise.all(i), r = await yt(s, (a) => t.blockTools.get(a).sanitizeConfig);
+ return this.makeOutput(r);
+ } catch (s) {
+ X("Saving failed due to the Error %o", "error", s);
+ }
+ }
+ /**
+ * Saves and validates
+ *
+ * @param {Block} block - Editor's Tool
+ * @returns {ValidatedData} - Tool's validated data
+ */
+ async getSavedData(e) {
+ const t = await e.save(), o = t && await e.validate(t.data);
+ return {
+ ...t,
+ isValid: o
+ };
+ }
+ /**
+ * Creates output object with saved data, time and version of editor
+ *
+ * @param {ValidatedData} allExtractedData - data extracted from Blocks
+ * @returns {OutputData}
+ */
+ makeOutput(e) {
+ const t = [];
+ return e.forEach(({ id: o, tool: i, data: s, tunes: r, isValid: a }) => {
+ if (!a) {
+ S(`Block «${i}» skipped because saved data is invalid`);
+ return;
+ }
+ if (i === this.Editor.Tools.stubTool) {
+ t.push(s);
+ return;
+ }
+ const l = {
+ id: o,
+ type: i,
+ data: s,
+ ...!V(r) && {
+ tunes: r
+ }
+ };
+ t.push(l);
+ }), {
+ time: +/* @__PURE__ */ new Date(),
+ blocks: t,
+ version: "2.31.0-rc.8"
+ };
+ }
+}
+(function() {
+ try {
+ if (typeof document < "u") {
+ var n = document.createElement("style");
+ n.appendChild(document.createTextNode(".ce-paragraph{line-height:1.6em;outline:none}.ce-block:only-of-type .ce-paragraph[data-placeholder-active]:empty:before,.ce-block:only-of-type .ce-paragraph[data-placeholder-active][data-empty=true]:before{content:attr(data-placeholder-active)}.ce-paragraph p:first-of-type{margin-top:0}.ce-paragraph p:last-of-type{margin-bottom:0}")), document.head.appendChild(n);
+ }
+ } catch (e) {
+ console.error("vite-plugin-css-injected-by-js", e);
+ }
+})();
+const ba = '';
+function va(n) {
+ const e = document.createElement("div");
+ e.innerHTML = n.trim();
+ const t = document.createDocumentFragment();
+ return t.append(...Array.from(e.childNodes)), t;
+}
+/**
+ * Base Paragraph Block for the Editor.js.
+ * Represents a regular text block
+ *
+ * @author CodeX (team@codex.so)
+ * @copyright CodeX 2018
+ * @license The MIT License (MIT)
+ */
+class fo {
+ /**
+ * Default placeholder for Paragraph Tool
+ *
+ * @returns {string}
+ * @class
+ */
+ static get DEFAULT_PLACEHOLDER() {
+ return "";
+ }
+ /**
+ * Render plugin`s main Element and fill it with saved data
+ *
+ * @param {object} params - constructor params
+ * @param {ParagraphData} params.data - previously saved data
+ * @param {ParagraphConfig} params.config - user config for Tool
+ * @param {object} params.api - editor.js api
+ * @param {boolean} readOnly - read only mode flag
+ */
+ constructor({ data: e, config: t, api: o, readOnly: i }) {
+ this.api = o, this.readOnly = i, this._CSS = {
+ block: this.api.styles.block,
+ wrapper: "ce-paragraph"
+ }, this.readOnly || (this.onKeyUp = this.onKeyUp.bind(this)), this._placeholder = t.placeholder ? t.placeholder : fo.DEFAULT_PLACEHOLDER, this._data = e ?? {}, this._element = null, this._preserveBlank = t.preserveBlank ?? !1;
+ }
+ /**
+ * Check if text content is empty and set empty string to inner html.
+ * We need this because some browsers (e.g. Safari) insert
into empty contenteditanle elements
+ *
+ * @param {KeyboardEvent} e - key up event
+ */
+ onKeyUp(e) {
+ if (e.code !== "Backspace" && e.code !== "Delete" || !this._element)
+ return;
+ const { textContent: t } = this._element;
+ t === "" && (this._element.innerHTML = "");
+ }
+ /**
+ * Create Tool's view
+ *
+ * @returns {HTMLDivElement}
+ * @private
+ */
+ drawView() {
+ const e = document.createElement("DIV");
+ return e.classList.add(this._CSS.wrapper, this._CSS.block), e.contentEditable = "false", e.dataset.placeholderActive = this.api.i18n.t(this._placeholder), this._data.text && (e.innerHTML = this._data.text), this.readOnly || (e.contentEditable = "true", e.addEventListener("keyup", this.onKeyUp)), e;
+ }
+ /**
+ * Return Tool's view
+ *
+ * @returns {HTMLDivElement}
+ */
+ render() {
+ return this._element = this.drawView(), this._element;
+ }
+ /**
+ * Method that specified how to merge two Text blocks.
+ * Called by Editor.js by backspace at the beginning of the Block
+ *
+ * @param {ParagraphData} data
+ * @public
+ */
+ merge(e) {
+ if (!this._element)
+ return;
+ this._data.text += e.text;
+ const t = va(e.text);
+ this._element.appendChild(t), this._element.normalize();
+ }
+ /**
+ * Validate Paragraph block data:
+ * - check for emptiness
+ *
+ * @param {ParagraphData} savedData — data received after saving
+ * @returns {boolean} false if saved data is not correct, otherwise true
+ * @public
+ */
+ validate(e) {
+ return !(e.text.trim() === "" && !this._preserveBlank);
+ }
+ /**
+ * Extract Tool's data from the view
+ *
+ * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view
+ * @returns {ParagraphData} - saved data
+ * @public
+ */
+ save(e) {
+ return {
+ text: e.innerHTML
+ };
+ }
+ /**
+ * On paste callback fired from Editor.
+ *
+ * @param {HTMLPasteEvent} event - event with pasted data
+ */
+ onPaste(e) {
+ const t = {
+ text: e.detail.data.innerHTML
+ };
+ this._data = t, window.requestAnimationFrame(() => {
+ this._element && (this._element.innerHTML = this._data.text || "");
+ });
+ }
+ /**
+ * Enable Conversion Toolbar. Paragraph can be converted to/from other tools
+ * @returns {ConversionConfig}
+ */
+ static get conversionConfig() {
+ return {
+ export: "text",
+ // to convert Paragraph to other block, use 'text' property of saved data
+ import: "text"
+ // to covert other block's exported string to Paragraph, fill 'text' property of tool data
+ };
+ }
+ /**
+ * Sanitizer rules
+ * @returns {SanitizerConfig} - Edtior.js sanitizer config
+ */
+ static get sanitize() {
+ return {
+ text: {
+ br: !0
+ }
+ };
+ }
+ /**
+ * Returns true to notify the core that read-only mode is supported
+ *
+ * @returns {boolean}
+ */
+ static get isReadOnlySupported() {
+ return !0;
+ }
+ /**
+ * Used by Editor paste handling API.
+ * Provides configuration to handle P tags.
+ *
+ * @returns {PasteConfig} - Paragraph Paste Setting
+ */
+ static get pasteConfig() {
+ return {
+ tags: ["P"]
+ };
+ }
+ /**
+ * Icon and title for displaying at the Toolbox
+ *
+ * @returns {ToolboxConfig} - Paragraph Toolbox Setting
+ */
+ static get toolbox() {
+ return {
+ icon: ba,
+ title: "Text"
+ };
+ }
+}
+class go {
+ constructor() {
+ this.commandName = "bold";
+ }
+ /**
+ * Sanitizer Rule
+ * Leave tags
+ *
+ * @returns {object}
+ */
+ static get sanitize() {
+ return {
+ b: {}
+ };
+ }
+ /**
+ * Create button for Inline Toolbar
+ */
+ render() {
+ return {
+ icon: Ki,
+ name: "bold",
+ onActivate: () => {
+ document.execCommand(this.commandName);
+ },
+ isActive: () => document.queryCommandState(this.commandName)
+ };
+ }
+ /**
+ * Set a shortcut
+ *
+ * @returns {boolean}
+ */
+ get shortcut() {
+ return "CMD+B";
+ }
+}
+go.isInline = !0;
+go.title = "Bold";
+class mo {
+ constructor() {
+ this.commandName = "italic", this.CSS = {
+ button: "ce-inline-tool",
+ buttonActive: "ce-inline-tool--active",
+ buttonModifier: "ce-inline-tool--italic"
+ }, this.nodes = {
+ button: null
+ };
+ }
+ /**
+ * Sanitizer Rule
+ * Leave tags
+ *
+ * @returns {object}
+ */
+ static get sanitize() {
+ return {
+ i: {}
+ };
+ }
+ /**
+ * Create button for Inline Toolbar
+ */
+ render() {
+ return this.nodes.button = document.createElement("button"), this.nodes.button.type = "button", this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier), this.nodes.button.innerHTML = Ji, this.nodes.button;
+ }
+ /**
+ * Wrap range with tag
+ */
+ surround() {
+ document.execCommand(this.commandName);
+ }
+ /**
+ * Check selection and set activated state to button if there are tag
+ */
+ checkState() {
+ const e = document.queryCommandState(this.commandName);
+ return this.nodes.button.classList.toggle(this.CSS.buttonActive, e), e;
+ }
+ /**
+ * Set a shortcut
+ */
+ get shortcut() {
+ return "CMD+I";
+ }
+}
+mo.isInline = !0;
+mo.title = "Italic";
+class bo {
+ /**
+ * @param api - Editor.js API
+ */
+ constructor({ api: e }) {
+ this.commandLink = "createLink", this.commandUnlink = "unlink", this.ENTER_KEY = 13, this.CSS = {
+ button: "ce-inline-tool",
+ buttonActive: "ce-inline-tool--active",
+ buttonModifier: "ce-inline-tool--link",
+ buttonUnlink: "ce-inline-tool--unlink",
+ input: "ce-inline-tool-input",
+ inputShowed: "ce-inline-tool-input--showed"
+ }, this.nodes = {
+ button: null,
+ input: null
+ }, this.inputOpened = !1, this.toolbar = e.toolbar, this.inlineToolbar = e.inlineToolbar, this.notifier = e.notifier, this.i18n = e.i18n, this.selection = new b();
+ }
+ /**
+ * Sanitizer Rule
+ * Leave tags
+ *
+ * @returns {object}
+ */
+ static get sanitize() {
+ return {
+ a: {
+ href: !0,
+ target: "_blank",
+ rel: "nofollow"
+ }
+ };
+ }
+ /**
+ * Create button for Inline Toolbar
+ */
+ render() {
+ return this.nodes.button = document.createElement("button"), this.nodes.button.type = "button", this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier), this.nodes.button.innerHTML = Co, this.nodes.button;
+ }
+ /**
+ * Input for the link
+ */
+ renderActions() {
+ return this.nodes.input = document.createElement("input"), this.nodes.input.placeholder = this.i18n.t("Add a link"), this.nodes.input.enterKeyHint = "done", this.nodes.input.classList.add(this.CSS.input), this.nodes.input.addEventListener("keydown", (e) => {
+ e.keyCode === this.ENTER_KEY && this.enterPressed(e);
+ }), this.nodes.input;
+ }
+ /**
+ * Handle clicks on the Inline Toolbar icon
+ *
+ * @param {Range} range - range to wrap with link
+ */
+ surround(e) {
+ if (e) {
+ this.inputOpened ? (this.selection.restore(), this.selection.removeFakeBackground()) : (this.selection.setFakeBackground(), this.selection.save());
+ const t = this.selection.findParentTag("A");
+ if (t) {
+ this.selection.expandToTag(t), this.unlink(), this.closeActions(), this.checkState(), this.toolbar.close();
+ return;
+ }
+ }
+ this.toggleActions();
+ }
+ /**
+ * Check selection and set activated state to button if there are tag
+ */
+ checkState() {
+ const e = this.selection.findParentTag("A");
+ if (e) {
+ this.nodes.button.innerHTML = ns, this.nodes.button.classList.add(this.CSS.buttonUnlink), this.nodes.button.classList.add(this.CSS.buttonActive), this.openActions();
+ const t = e.getAttribute("href");
+ this.nodes.input.value = t !== "null" ? t : "", this.selection.save();
+ } else
+ this.nodes.button.innerHTML = Co, this.nodes.button.classList.remove(this.CSS.buttonUnlink), this.nodes.button.classList.remove(this.CSS.buttonActive);
+ return !!e;
+ }
+ /**
+ * Function called with Inline Toolbar closing
+ */
+ clear() {
+ this.closeActions();
+ }
+ /**
+ * Set a shortcut
+ */
+ get shortcut() {
+ return "CMD+K";
+ }
+ /**
+ * Show/close link input
+ */
+ toggleActions() {
+ this.inputOpened ? this.closeActions(!1) : this.openActions(!0);
+ }
+ /**
+ * @param {boolean} needFocus - on link creation we need to focus input. On editing - nope.
+ */
+ openActions(e = !1) {
+ this.nodes.input.classList.add(this.CSS.inputShowed), e && this.nodes.input.focus(), this.inputOpened = !0;
+ }
+ /**
+ * Close input
+ *
+ * @param {boolean} clearSavedSelection — we don't need to clear saved selection
+ * on toggle-clicks on the icon of opened Toolbar
+ */
+ closeActions(e = !0) {
+ if (this.selection.isFakeBackgroundEnabled) {
+ const t = new b();
+ t.save(), this.selection.restore(), this.selection.removeFakeBackground(), t.restore();
+ }
+ this.nodes.input.classList.remove(this.CSS.inputShowed), this.nodes.input.value = "", e && this.selection.clearSaved(), this.inputOpened = !1;
+ }
+ /**
+ * Enter pressed on input
+ *
+ * @param {KeyboardEvent} event - enter keydown event
+ */
+ enterPressed(e) {
+ let t = this.nodes.input.value || "";
+ if (!t.trim()) {
+ this.selection.restore(), this.unlink(), e.preventDefault(), this.closeActions();
+ return;
+ }
+ if (!this.validateURL(t)) {
+ this.notifier.show({
+ message: "Pasted link is not valid.",
+ style: "error"
+ }), S("Incorrect Link pasted", "warn", t);
+ return;
+ }
+ t = this.prepareLink(t), this.selection.restore(), this.selection.removeFakeBackground(), this.insertLink(t), e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation(), this.selection.collapseToEnd(), this.inlineToolbar.close();
+ }
+ /**
+ * Detects if passed string is URL
+ *
+ * @param {string} str - string to validate
+ * @returns {boolean}
+ */
+ validateURL(e) {
+ return !/\s/.test(e);
+ }
+ /**
+ * Process link before injection
+ * - sanitize
+ * - add protocol for links like 'google.com'
+ *
+ * @param {string} link - raw user input
+ */
+ prepareLink(e) {
+ return e = e.trim(), e = this.addProtocol(e), e;
+ }
+ /**
+ * Add 'http' protocol to the links like 'vc.ru', 'google.com'
+ *
+ * @param {string} link - string to process
+ */
+ addProtocol(e) {
+ if (/^(\w+):(\/\/)?/.test(e))
+ return e;
+ const t = /^\/[^/\s]/.test(e), o = e.substring(0, 1) === "#", i = /^\/\/[^/\s]/.test(e);
+ return !t && !o && !i && (e = "http://" + e), e;
+ }
+ /**
+ * Inserts tag with "href"
+ *
+ * @param {string} link - "href" value
+ */
+ insertLink(e) {
+ const t = this.selection.findParentTag("A");
+ t && this.selection.expandToTag(t), document.execCommand(this.commandLink, !1, e);
+ }
+ /**
+ * Removes tag
+ */
+ unlink() {
+ document.execCommand(this.commandUnlink);
+ }
+}
+bo.isInline = !0;
+bo.title = "Link";
+class Fn {
+ /**
+ * @param api - Editor.js API
+ */
+ constructor({ api: e }) {
+ this.i18nAPI = e.i18n, this.blocksAPI = e.blocks, this.selectionAPI = e.selection, this.toolsAPI = e.tools, this.caretAPI = e.caret;
+ }
+ /**
+ * Returns tool's UI config
+ */
+ async render() {
+ const e = b.get(), t = this.blocksAPI.getBlockByElement(e.anchorNode);
+ if (t === void 0)
+ return [];
+ const o = this.toolsAPI.getBlockTools(), i = await Yo(t, o);
+ if (i.length === 0)
+ return [];
+ const s = i.reduce((c, u) => {
+ var h;
+ return (h = u.toolbox) == null || h.forEach((p) => {
+ c.push({
+ icon: p.icon,
+ title: z.t(K.toolNames, p.title),
+ name: u.name,
+ closeOnActivate: !0,
+ onActivate: async () => {
+ const g = await this.blocksAPI.convert(t.id, u.name, p.data);
+ this.caretAPI.setToBlock(g, "end");
+ }
+ });
+ }), c;
+ }, []), r = await t.getActiveToolboxEntry(), a = r !== void 0 ? r.icon : Go, l = !be();
+ return {
+ icon: a,
+ name: "convert-to",
+ hint: {
+ title: this.i18nAPI.t("Convert to")
+ },
+ children: {
+ searchable: l,
+ items: s,
+ onOpen: () => {
+ l && (this.selectionAPI.setFakeBackground(), this.selectionAPI.save());
+ },
+ onClose: () => {
+ l && (this.selectionAPI.restore(), this.selectionAPI.removeFakeBackground());
+ }
+ }
+ };
+ }
+}
+Fn.isInline = !0;
+class jn {
+ /**
+ * @param options - constructor options
+ * @param options.data - stub tool data
+ * @param options.api - Editor.js API
+ */
+ constructor({ data: e, api: t }) {
+ this.CSS = {
+ wrapper: "ce-stub",
+ info: "ce-stub__info",
+ title: "ce-stub__title",
+ subtitle: "ce-stub__subtitle"
+ }, this.api = t, this.title = e.title || this.api.i18n.t("Error"), this.subtitle = this.api.i18n.t("The block can not be displayed correctly."), this.savedData = e.savedData, this.wrapper = this.make();
+ }
+ /**
+ * Returns stub holder
+ *
+ * @returns {HTMLElement}
+ */
+ render() {
+ return this.wrapper;
+ }
+ /**
+ * Return original Tool data
+ *
+ * @returns {BlockToolData}
+ */
+ save() {
+ return this.savedData;
+ }
+ /**
+ * Create Tool html markup
+ *
+ * @returns {HTMLElement}
+ */
+ make() {
+ const e = d.make("div", this.CSS.wrapper), t = is, o = d.make("div", this.CSS.info), i = d.make("div", this.CSS.title, {
+ textContent: this.title
+ }), s = d.make("div", this.CSS.subtitle, {
+ textContent: this.subtitle
+ });
+ return e.innerHTML = t, o.appendChild(i), o.appendChild(s), e.appendChild(o), e;
+ }
+}
+jn.isReadOnlySupported = !0;
+class ka extends Tt {
+ constructor() {
+ super(...arguments), this.type = ae.Inline;
+ }
+ /**
+ * Returns title for Inline Tool if specified by user
+ */
+ get title() {
+ return this.constructable[We.Title];
+ }
+ /**
+ * Constructs new InlineTool instance from constructable
+ */
+ create() {
+ return new this.constructable({
+ api: this.api,
+ config: this.settings
+ });
+ }
+ /**
+ * Allows inline tool to be available in read-only mode
+ * Can be used, for example, by comments tool
+ */
+ get isReadOnlySupported() {
+ return this.constructable[We.IsReadOnlySupported] ?? !1;
+ }
+}
+class ya extends Tt {
+ constructor() {
+ super(...arguments), this.type = ae.Tune;
+ }
+ /**
+ * Constructs new BlockTune instance from constructable
+ *
+ * @param data - Tune data
+ * @param block - Block API object
+ */
+ create(e, t) {
+ return new this.constructable({
+ api: this.api,
+ config: this.settings,
+ block: t,
+ data: e
+ });
+ }
+}
+class j extends Map {
+ /**
+ * Returns Block Tools collection
+ */
+ get blockTools() {
+ const e = Array.from(this.entries()).filter(([, t]) => t.isBlock());
+ return new j(e);
+ }
+ /**
+ * Returns Inline Tools collection
+ */
+ get inlineTools() {
+ const e = Array.from(this.entries()).filter(([, t]) => t.isInline());
+ return new j(e);
+ }
+ /**
+ * Returns Block Tunes collection
+ */
+ get blockTunes() {
+ const e = Array.from(this.entries()).filter(([, t]) => t.isTune());
+ return new j(e);
+ }
+ /**
+ * Returns internal Tools collection
+ */
+ get internalTools() {
+ const e = Array.from(this.entries()).filter(([, t]) => t.isInternal);
+ return new j(e);
+ }
+ /**
+ * Returns Tools collection provided by user
+ */
+ get externalTools() {
+ const e = Array.from(this.entries()).filter(([, t]) => !t.isInternal);
+ return new j(e);
+ }
+}
+var wa = Object.defineProperty, Ea = Object.getOwnPropertyDescriptor, Hn = (n, e, t, o) => {
+ for (var i = o > 1 ? void 0 : o ? Ea(e, t) : e, s = n.length - 1, r; s >= 0; s--)
+ (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);
+ return o && i && wa(e, t, i), i;
+};
+class vo extends Tt {
+ constructor() {
+ super(...arguments), this.type = ae.Block, this.inlineTools = new j(), this.tunes = new j();
+ }
+ /**
+ * Creates new Tool instance
+ *
+ * @param data - Tool data
+ * @param block - BlockAPI for current Block
+ * @param readOnly - True if Editor is in read-only mode
+ */
+ create(e, t, o) {
+ return new this.constructable({
+ data: e,
+ block: t,
+ readOnly: o,
+ api: this.api,
+ config: this.settings
+ });
+ }
+ /**
+ * Returns true if read-only mode is supported by Tool
+ */
+ get isReadOnlySupported() {
+ return this.constructable[pe.IsReadOnlySupported] === !0;
+ }
+ /**
+ * Returns true if Tool supports linebreaks
+ */
+ get isLineBreaksEnabled() {
+ return this.constructable[pe.IsEnabledLineBreaks];
+ }
+ /**
+ * Returns Tool toolbox configuration (internal or user-specified).
+ *
+ * Merges internal and user-defined toolbox configs based on the following rules:
+ *
+ * - If both internal and user-defined toolbox configs are arrays their items are merged.
+ * Length of the second one is kept.
+ *
+ * - If both are objects their properties are merged.
+ *
+ * - If one is an object and another is an array than internal config is replaced with user-defined
+ * config. This is made to allow user to override default tool's toolbox representation (single/multiple entries)
+ */
+ get toolbox() {
+ const e = this.constructable[pe.Toolbox], t = this.config[Pe.Toolbox];
+ if (!V(e) && t !== !1)
+ return t ? Array.isArray(e) ? Array.isArray(t) ? t.map((o, i) => {
+ const s = e[i];
+ return s ? {
+ ...s,
+ ...o
+ } : o;
+ }) : [t] : Array.isArray(t) ? t : [
+ {
+ ...e,
+ ...t
+ }
+ ] : Array.isArray(e) ? e : [e];
+ }
+ /**
+ * Returns Tool conversion configuration
+ */
+ get conversionConfig() {
+ return this.constructable[pe.ConversionConfig];
+ }
+ /**
+ * Returns enabled inline tools for Tool
+ */
+ get enabledInlineTools() {
+ return this.config[Pe.EnabledInlineTools] || !1;
+ }
+ /**
+ * Returns enabled tunes for Tool
+ */
+ get enabledBlockTunes() {
+ return this.config[Pe.EnabledBlockTunes];
+ }
+ /**
+ * Returns Tool paste configuration
+ */
+ get pasteConfig() {
+ return this.constructable[pe.PasteConfig] ?? {};
+ }
+ get sanitizeConfig() {
+ const e = super.sanitizeConfig, t = this.baseSanitizeConfig;
+ if (V(e))
+ return t;
+ const o = {};
+ for (const i in e)
+ if (Object.prototype.hasOwnProperty.call(e, i)) {
+ const s = e[i];
+ D(s) ? o[i] = Object.assign({}, t, s) : o[i] = s;
+ }
+ return o;
+ }
+ get baseSanitizeConfig() {
+ const e = {};
+ return Array.from(this.inlineTools.values()).forEach((t) => Object.assign(e, t.sanitizeConfig)), Array.from(this.tunes.values()).forEach((t) => Object.assign(e, t.sanitizeConfig)), e;
+ }
+}
+Hn([
+ me
+], vo.prototype, "sanitizeConfig", 1);
+Hn([
+ me
+], vo.prototype, "baseSanitizeConfig", 1);
+class xa {
+ /**
+ * @class
+ * @param config - tools config
+ * @param editorConfig - EditorJS config
+ * @param api - EditorJS API module
+ */
+ constructor(e, t, o) {
+ this.api = o, this.config = e, this.editorConfig = t;
+ }
+ /**
+ * Returns Tool object based on it's type
+ *
+ * @param name - tool name
+ */
+ get(e) {
+ const { class: t, isInternal: o = !1, ...i } = this.config[e], s = this.getConstructor(t), r = t[mt.IsTune];
+ return new s({
+ name: e,
+ constructable: t,
+ config: i,
+ api: this.api.getMethodsForTool(e, r),
+ isDefault: e === this.editorConfig.defaultBlock,
+ defaultPlaceholder: this.editorConfig.placeholder,
+ isInternal: o
+ });
+ }
+ /**
+ * Find appropriate Tool object constructor for Tool constructable
+ *
+ * @param constructable - Tools constructable
+ */
+ getConstructor(e) {
+ switch (!0) {
+ case e[We.IsInline]:
+ return ka;
+ case e[mt.IsTune]:
+ return ya;
+ default:
+ return vo;
+ }
+ }
+}
+class $n {
+ /**
+ * MoveDownTune constructor
+ *
+ * @param {API} api — Editor's API
+ */
+ constructor({ api: e }) {
+ this.CSS = {
+ animation: "wobble"
+ }, this.api = e;
+ }
+ /**
+ * Tune's appearance in block settings menu
+ */
+ render() {
+ return {
+ icon: Xi,
+ title: this.api.i18n.t("Move down"),
+ onActivate: () => this.handleClick(),
+ name: "move-down"
+ };
+ }
+ /**
+ * Handle clicks on 'move down' button
+ */
+ handleClick() {
+ const e = this.api.blocks.getCurrentBlockIndex(), t = this.api.blocks.getBlockByIndex(e + 1);
+ if (!t)
+ throw new Error("Unable to move Block down since it is already the last");
+ const o = t.holder, i = o.getBoundingClientRect();
+ let s = Math.abs(window.innerHeight - o.offsetHeight);
+ i.top < window.innerHeight && (s = window.scrollY + o.offsetHeight), window.scrollTo(0, s), this.api.blocks.move(e + 1), this.api.toolbar.toggleBlockSettings(!0);
+ }
+}
+$n.isTune = !0;
+class zn {
+ /**
+ * DeleteTune constructor
+ *
+ * @param {API} api - Editor's API
+ */
+ constructor({ api: e }) {
+ this.api = e;
+ }
+ /**
+ * Tune's appearance in block settings menu
+ */
+ render() {
+ return {
+ icon: Gi,
+ title: this.api.i18n.t("Delete"),
+ name: "delete",
+ confirmation: {
+ title: this.api.i18n.t("Click to delete"),
+ onActivate: () => this.handleClick()
+ }
+ };
+ }
+ /**
+ * Delete block conditions passed
+ */
+ handleClick() {
+ this.api.blocks.delete();
+ }
+}
+zn.isTune = !0;
+class Un {
+ /**
+ * MoveUpTune constructor
+ *
+ * @param {API} api - Editor's API
+ */
+ constructor({ api: e }) {
+ this.CSS = {
+ animation: "wobble"
+ }, this.api = e;
+ }
+ /**
+ * Tune's appearance in block settings menu
+ */
+ render() {
+ return {
+ icon: Zi,
+ title: this.api.i18n.t("Move up"),
+ onActivate: () => this.handleClick(),
+ name: "move-up"
+ };
+ }
+ /**
+ * Move current block up
+ */
+ handleClick() {
+ const e = this.api.blocks.getCurrentBlockIndex(), t = this.api.blocks.getBlockByIndex(e), o = this.api.blocks.getBlockByIndex(e - 1);
+ if (e === 0 || !t || !o)
+ throw new Error("Unable to move Block up since it is already the first");
+ const i = t.holder, s = o.holder, r = i.getBoundingClientRect(), a = s.getBoundingClientRect();
+ let l;
+ a.top > 0 ? l = Math.abs(r.top) - Math.abs(a.top) : l = Math.abs(r.top) + a.height, window.scrollBy(0, -1 * l), this.api.blocks.move(e - 1), this.api.toolbar.toggleBlockSettings(!0);
+ }
+}
+Un.isTune = !0;
+var Ba = Object.defineProperty, Ca = Object.getOwnPropertyDescriptor, Ta = (n, e, t, o) => {
+ for (var i = o > 1 ? void 0 : o ? Ca(e, t) : e, s = n.length - 1, r; s >= 0; s--)
+ (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);
+ return o && i && Ba(e, t, i), i;
+};
+class Wn extends E {
+ constructor() {
+ super(...arguments), this.stubTool = "stub", this.toolsAvailable = new j(), this.toolsUnavailable = new j();
+ }
+ /**
+ * Returns available Tools
+ */
+ get available() {
+ return this.toolsAvailable;
+ }
+ /**
+ * Returns unavailable Tools
+ */
+ get unavailable() {
+ return this.toolsUnavailable;
+ }
+ /**
+ * Return Tools for the Inline Toolbar
+ */
+ get inlineTools() {
+ return this.available.inlineTools;
+ }
+ /**
+ * Return editor block tools
+ */
+ get blockTools() {
+ return this.available.blockTools;
+ }
+ /**
+ * Return available Block Tunes
+ *
+ * @returns {object} - object of Inline Tool's classes
+ */
+ get blockTunes() {
+ return this.available.blockTunes;
+ }
+ /**
+ * Returns default Tool object
+ */
+ get defaultTool() {
+ return this.blockTools.get(this.config.defaultBlock);
+ }
+ /**
+ * Returns internal tools
+ */
+ get internal() {
+ return this.available.internalTools;
+ }
+ /**
+ * Creates instances via passed or default configuration
+ *
+ * @returns {Promise}
+ */
+ async prepare() {
+ if (this.validateTools(), this.config.tools = ut({}, this.internalTools, this.config.tools), !Object.prototype.hasOwnProperty.call(this.config, "tools") || Object.keys(this.config.tools).length === 0)
+ throw Error("Can't start without tools");
+ const e = this.prepareConfig();
+ this.factory = new xa(e, this.config, this.Editor.API);
+ const t = this.getListOfPrepareFunctions(e);
+ if (t.length === 0)
+ return Promise.resolve();
+ await Qn(t, (o) => {
+ this.toolPrepareMethodSuccess(o);
+ }, (o) => {
+ this.toolPrepareMethodFallback(o);
+ }), this.prepareBlockTools();
+ }
+ getAllInlineToolsSanitizeConfig() {
+ const e = {};
+ return Array.from(this.inlineTools.values()).forEach((t) => {
+ Object.assign(e, t.sanitizeConfig);
+ }), e;
+ }
+ /**
+ * Calls each Tool reset method to clean up anything set by Tool
+ */
+ destroy() {
+ Object.values(this.available).forEach(async (e) => {
+ A(e.reset) && await e.reset();
+ });
+ }
+ /**
+ * Returns internal tools
+ * Includes Bold, Italic, Link and Paragraph
+ */
+ get internalTools() {
+ return {
+ convertTo: {
+ class: Fn,
+ isInternal: !0
+ },
+ link: {
+ class: bo,
+ isInternal: !0
+ },
+ bold: {
+ class: go,
+ isInternal: !0
+ },
+ italic: {
+ class: mo,
+ isInternal: !0
+ },
+ paragraph: {
+ class: fo,
+ inlineToolbar: !0,
+ isInternal: !0
+ },
+ stub: {
+ class: jn,
+ isInternal: !0
+ },
+ moveUp: {
+ class: Un,
+ isInternal: !0
+ },
+ delete: {
+ class: zn,
+ isInternal: !0
+ },
+ moveDown: {
+ class: $n,
+ isInternal: !0
+ }
+ };
+ }
+ /**
+ * Tool prepare method success callback
+ *
+ * @param {object} data - append tool to available list
+ */
+ toolPrepareMethodSuccess(e) {
+ const t = this.factory.get(e.toolName);
+ if (t.isInline()) {
+ const i = ["render"].filter((s) => !t.create()[s]);
+ if (i.length) {
+ S(
+ `Incorrect Inline Tool: ${t.name}. Some of required methods is not implemented %o`,
+ "warn",
+ i
+ ), this.toolsUnavailable.set(t.name, t);
+ return;
+ }
+ }
+ this.toolsAvailable.set(t.name, t);
+ }
+ /**
+ * Tool prepare method fail callback
+ *
+ * @param {object} data - append tool to unavailable list
+ */
+ toolPrepareMethodFallback(e) {
+ this.toolsUnavailable.set(e.toolName, this.factory.get(e.toolName));
+ }
+ /**
+ * Binds prepare function of plugins with user or default config
+ *
+ * @returns {Array} list of functions that needs to be fired sequentially
+ * @param config - tools config
+ */
+ getListOfPrepareFunctions(e) {
+ const t = [];
+ return Object.entries(e).forEach(([o, i]) => {
+ t.push({
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ function: A(i.class.prepare) ? i.class.prepare : () => {
+ },
+ data: {
+ toolName: o,
+ config: i.config
+ }
+ });
+ }), t;
+ }
+ /**
+ * Assign enabled Inline Tools and Block Tunes for Block Tool
+ */
+ prepareBlockTools() {
+ Array.from(this.blockTools.values()).forEach((e) => {
+ this.assignInlineToolsToBlockTool(e), this.assignBlockTunesToBlockTool(e);
+ });
+ }
+ /**
+ * Assign enabled Inline Tools for Block Tool
+ *
+ * @param tool - Block Tool
+ */
+ assignInlineToolsToBlockTool(e) {
+ if (this.config.inlineToolbar !== !1) {
+ if (e.enabledInlineTools === !0) {
+ e.inlineTools = new j(
+ Array.isArray(this.config.inlineToolbar) ? this.config.inlineToolbar.map((t) => [t, this.inlineTools.get(t)]) : Array.from(this.inlineTools.entries())
+ );
+ return;
+ }
+ Array.isArray(e.enabledInlineTools) && (e.inlineTools = new j(
+ /** Prepend ConvertTo Inline Tool */
+ ["convertTo", ...e.enabledInlineTools].map((t) => [t, this.inlineTools.get(t)])
+ ));
+ }
+ }
+ /**
+ * Assign enabled Block Tunes for Block Tool
+ *
+ * @param tool — Block Tool
+ */
+ assignBlockTunesToBlockTool(e) {
+ if (e.enabledBlockTunes !== !1) {
+ if (Array.isArray(e.enabledBlockTunes)) {
+ const t = new j(
+ e.enabledBlockTunes.map((o) => [o, this.blockTunes.get(o)])
+ );
+ e.tunes = new j([...t, ...this.blockTunes.internalTools]);
+ return;
+ }
+ if (Array.isArray(this.config.tunes)) {
+ const t = new j(
+ this.config.tunes.map((o) => [o, this.blockTunes.get(o)])
+ );
+ e.tunes = new j([...t, ...this.blockTunes.internalTools]);
+ return;
+ }
+ e.tunes = this.blockTunes.internalTools;
+ }
+ }
+ /**
+ * Validate Tools configuration objects and throw Error for user if it is invalid
+ */
+ validateTools() {
+ for (const e in this.config.tools)
+ if (Object.prototype.hasOwnProperty.call(this.config.tools, e)) {
+ if (e in this.internalTools)
+ return;
+ const t = this.config.tools[e];
+ if (!A(t) && !A(t.class))
+ throw Error(
+ `Tool «${e}» must be a constructor function or an object with function in the «class» property`
+ );
+ }
+ }
+ /**
+ * Unify tools config
+ */
+ prepareConfig() {
+ const e = {};
+ for (const t in this.config.tools)
+ D(this.config.tools[t]) ? e[t] = this.config.tools[t] : e[t] = { class: this.config.tools[t] };
+ return e;
+ }
+}
+Ta([
+ me
+], Wn.prototype, "getAllInlineToolsSanitizeConfig", 1);
+const Sa = `:root{--selectionColor: #e1f2ff;--inlineSelectionColor: #d4ecff;--bg-light: #eff2f5;--grayText: #707684;--color-dark: #1D202B;--color-active-icon: #388AE5;--color-gray-border: rgba(201, 201, 204, .48);--content-width: 650px;--narrow-mode-right-padding: 50px;--toolbox-buttons-size: 26px;--toolbox-buttons-size--mobile: 36px;--icon-size: 20px;--icon-size--mobile: 28px;--block-padding-vertical: .4em;--color-line-gray: #EFF0F1 }.codex-editor{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;z-index:1}.codex-editor .hide{display:none}.codex-editor__redactor [contenteditable]:empty:after{content:"\\feff"}@media (min-width: 651px){.codex-editor--narrow .codex-editor__redactor{margin-right:50px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .codex-editor__redactor{margin-left:50px;margin-right:0}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__actions{right:-5px}}.codex-editor-copyable{position:absolute;height:1px;width:1px;top:-400%;opacity:.001}.codex-editor-overlay{position:fixed;top:0;left:0;right:0;bottom:0;z-index:999;pointer-events:none;overflow:hidden}.codex-editor-overlay__container{position:relative;pointer-events:auto;z-index:0}.codex-editor-overlay__rectangle{position:absolute;pointer-events:none;background-color:#2eaadc33;border:1px solid transparent}.codex-editor svg{max-height:100%}.codex-editor path{stroke:currentColor}.codex-editor ::-moz-selection{background-color:#d4ecff}.codex-editor ::selection{background-color:#d4ecff}.codex-editor--toolbox-opened [contentEditable=true][data-placeholder]:focus:before{opacity:0!important}.ce-scroll-locked{overflow:hidden}.ce-scroll-locked--hard{overflow:hidden;top:calc(-1 * var(--window-scroll-offset));position:fixed;width:100%}.ce-toolbar{position:absolute;left:0;right:0;top:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;will-change:opacity,top;display:none}.ce-toolbar--opened{display:block}.ce-toolbar__content{max-width:650px;margin:0 auto;position:relative}.ce-toolbar__plus{color:#1d202b;cursor:pointer;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-flex-negative:0;flex-shrink:0}@media (max-width: 650px){.ce-toolbar__plus{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__plus:hover{background-color:#eff2f5}}.ce-toolbar__plus--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.ce-toolbar__plus-shortcut{opacity:.6;word-spacing:-2px;margin-top:5px}@media (max-width: 650px){.ce-toolbar__plus{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__plus--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__plus--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__actions{position:absolute;right:100%;opacity:0;display:-webkit-box;display:-ms-flexbox;display:flex;padding-right:5px}.ce-toolbar__actions--opened{opacity:1}@media (max-width: 650px){.ce-toolbar__actions{right:auto}}.ce-toolbar__settings-btn{color:#1d202b;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;margin-left:3px;cursor:pointer;user-select:none}@media (max-width: 650px){.ce-toolbar__settings-btn{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__settings-btn:hover{background-color:#eff2f5}}.ce-toolbar__settings-btn--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (min-width: 651px){.ce-toolbar__settings-btn{width:24px}}.ce-toolbar__settings-btn--hidden{display:none}@media (max-width: 650px){.ce-toolbar__settings-btn{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__settings-btn--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__settings-btn--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__plus svg,.ce-toolbar__settings-btn svg{width:24px;height:24px}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__plus{left:5px}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbox .ce-popover{right:0;left:auto;left:initial}}.ce-inline-toolbar{--y-offset: 8px;--color-background-icon-active: rgba(56, 138, 229, .1);--color-text-icon-active: #388AE5;--color-text-primary: black;position:absolute;visibility:hidden;-webkit-transition:opacity .25s ease;transition:opacity .25s ease;will-change:opacity,left,top;top:0;left:0;z-index:3;opacity:1;visibility:visible}.ce-inline-toolbar [hidden]{display:none!important}.ce-inline-toolbar__toggler-and-button-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;padding:0 6px}.ce-inline-toolbar__buttons{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown{display:-webkit-box;display:-ms-flexbox;display:flex;padding:6px;margin:0 6px 0 -6px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border-right:1px solid rgba(201,201,204,.48);-webkit-box-sizing:border-box;box-sizing:border-box}@media (hover: hover){.ce-inline-toolbar__dropdown:hover{background:#eff2f5}}.ce-inline-toolbar__dropdown--hidden{display:none}.ce-inline-toolbar__dropdown-content,.ce-inline-toolbar__dropdown-arrow{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown-content svg,.ce-inline-toolbar__dropdown-arrow svg{width:20px;height:20px}.ce-inline-toolbar__shortcut{opacity:.6;word-spacing:-3px;margin-top:3px}.ce-inline-tool{color:var(--color-text-primary);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:0;border-radius:4px;line-height:normal;height:100%;padding:0;width:28px;background-color:transparent;cursor:pointer}@media (max-width: 650px){.ce-inline-tool{width:36px;height:36px}}@media (hover: hover){.ce-inline-tool:hover{background-color:#f8f8f8}}.ce-inline-tool svg{display:block;width:20px;height:20px}@media (max-width: 650px){.ce-inline-tool svg{width:28px;height:28px}}.ce-inline-tool--link .icon--unlink,.ce-inline-tool--unlink .icon--link{display:none}.ce-inline-tool--unlink .icon--unlink{display:inline-block;margin-bottom:-1px}.ce-inline-tool-input{background:#F8F8F8;border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:4px 8px;font-size:14px;line-height:22px;outline:none;margin:0;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;display:none;font-weight:500;-webkit-appearance:none;font-family:inherit}@media (max-width: 650px){.ce-inline-tool-input{font-size:15px;font-weight:500}}.ce-inline-tool-input::-webkit-input-placeholder{color:#707684}.ce-inline-tool-input::-moz-placeholder{color:#707684}.ce-inline-tool-input:-ms-input-placeholder{color:#707684}.ce-inline-tool-input::-ms-input-placeholder{color:#707684}.ce-inline-tool-input::placeholder{color:#707684}.ce-inline-tool-input--showed{display:block}.ce-inline-tool--active{background:var(--color-background-icon-active);color:var(--color-text-icon-active)}@-webkit-keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.ce-block{-webkit-animation:fade-in .3s ease;animation:fade-in .3s ease;-webkit-animation-fill-mode:none;animation-fill-mode:none;-webkit-animation-fill-mode:initial;animation-fill-mode:initial}.ce-block:first-of-type{margin-top:0}.ce-block--selected .ce-block__content{background:#e1f2ff}.ce-block--selected .ce-block__content [contenteditable]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ce-block--selected .ce-block__content img,.ce-block--selected .ce-block__content .ce-stub{opacity:.55}.ce-block--stretched .ce-block__content{max-width:none}.ce-block__content{position:relative;max-width:650px;margin:0 auto;-webkit-transition:background-color .15s ease;transition:background-color .15s ease}.ce-block--drop-target .ce-block__content:before{content:"";position:absolute;top:100%;left:-20px;margin-top:-1px;height:8px;width:8px;border:solid #388AE5;border-width:1px 1px 0 0;-webkit-transform-origin:right;transform-origin:right;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ce-block--drop-target .ce-block__content:after{content:"";position:absolute;top:100%;height:1px;width:100%;color:#388ae5;background:repeating-linear-gradient(90deg,#388AE5,#388AE5 1px,#fff 1px,#fff 6px)}.ce-block a{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline}.ce-block b{font-weight:700}.ce-block i{font-style:italic}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}.cdx-block{padding:.4em 0}.cdx-block::-webkit-input-placeholder{line-height:normal!important}.cdx-input{border:1px solid rgba(201,201,204,.48);-webkit-box-shadow:inset 0 1px 2px 0 rgba(35,44,72,.06);box-shadow:inset 0 1px 2px #232c480f;border-radius:3px;padding:10px 12px;outline:none;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.cdx-input[data-placeholder]:before{position:static!important}.cdx-input[data-placeholder]:before{display:inline-block;width:0;white-space:nowrap;pointer-events:none}.cdx-settings-button{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:3px;cursor:pointer;border:0;outline:none;background-color:transparent;vertical-align:bottom;color:inherit;margin:0;min-width:26px;min-height:26px}.cdx-settings-button--focused{background:rgba(34,186,255,.08)!important}.cdx-settings-button--focused{-webkit-box-shadow:inset 0 0 0px 1px rgba(7,161,227,.08);box-shadow:inset 0 0 0 1px #07a1e314}.cdx-settings-button--focused-animated{-webkit-animation-name:buttonClicked;animation-name:buttonClicked;-webkit-animation-duration:.25s;animation-duration:.25s}.cdx-settings-button--active{color:#388ae5}.cdx-settings-button svg{width:auto;height:auto}@media (max-width: 650px){.cdx-settings-button svg{width:28px;height:28px}}@media (max-width: 650px){.cdx-settings-button{width:36px;height:36px;border-radius:8px}}@media (hover: hover){.cdx-settings-button:hover{background-color:#eff2f5}}.cdx-loader{position:relative;border:1px solid rgba(201,201,204,.48)}.cdx-loader:before{content:"";position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-11px 0 0 -11px;border:2px solid rgba(201,201,204,.48);border-left-color:#388ae5;border-radius:50%;-webkit-animation:cdxRotation 1.2s infinite linear;animation:cdxRotation 1.2s infinite linear}@-webkit-keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cdx-button{padding:13px;border-radius:3px;border:1px solid rgba(201,201,204,.48);font-size:14.9px;background:#fff;-webkit-box-shadow:0 2px 2px 0 rgba(18,30,57,.04);box-shadow:0 2px 2px #121e390a;color:#707684;text-align:center;cursor:pointer}@media (hover: hover){.cdx-button:hover{background:#FBFCFE;-webkit-box-shadow:0 1px 3px 0 rgba(18,30,57,.08);box-shadow:0 1px 3px #121e3914}}.cdx-button svg{height:20px;margin-right:.2em;margin-top:-2px}.ce-stub{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:12px 18px;margin:10px 0;border-radius:10px;background:#eff2f5;border:1px solid #EFF0F1;color:#707684;font-size:14px}.ce-stub svg{width:20px;height:20px}.ce-stub__info{margin-left:14px}.ce-stub__title{font-weight:500;text-transform:capitalize}.codex-editor.codex-editor--rtl{direction:rtl}.codex-editor.codex-editor--rtl .cdx-list{padding-left:0;padding-right:40px}.codex-editor.codex-editor--rtl .ce-toolbar__plus{right:-26px;left:auto}.codex-editor.codex-editor--rtl .ce-toolbar__actions{right:auto;left:-26px}@media (max-width: 650px){.codex-editor.codex-editor--rtl .ce-toolbar__actions{margin-left:0;margin-right:auto;padding-right:0;padding-left:10px}}.codex-editor.codex-editor--rtl .ce-settings{left:5px;right:auto}.codex-editor.codex-editor--rtl .ce-settings:before{right:auto;left:25px}.codex-editor.codex-editor--rtl .ce-settings__button:not(:nth-child(3n+3)){margin-left:3px;margin-right:0}.codex-editor.codex-editor--rtl .ce-conversion-tool__icon{margin-right:0;margin-left:10px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown{border-right:0px solid transparent;border-left:1px solid rgba(201,201,204,.48);margin:0 -6px 0 6px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown .icon--toggler-down{margin-left:0;margin-right:4px}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__plus{left:0;right:5px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__actions{left:-5px}}.cdx-search-field{--icon-margin-right: 10px;background:#F8F8F8;border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:2px;display:grid;grid-template-columns:auto auto 1fr;grid-template-rows:auto}.cdx-search-field__icon{width:26px;height:26px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-right:var(--icon-margin-right)}.cdx-search-field__icon svg{width:20px;height:20px;color:#707684}.cdx-search-field__input{font-size:14px;outline:none;font-weight:500;font-family:inherit;border:0;background:transparent;margin:0;padding:0;line-height:22px;min-width:calc(100% - 26px - var(--icon-margin-right))}.cdx-search-field__input::-webkit-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-moz-placeholder{color:#707684;font-weight:500}.cdx-search-field__input:-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::placeholder{color:#707684;font-weight:500}.ce-popover{--border-radius: 6px;--width: 200px;--max-height: 270px;--padding: 6px;--offset-from-target: 8px;--color-border: #EFF0F1;--color-shadow: rgba(13, 20, 33, .1);--color-background: white;--color-text-primary: black;--color-text-secondary: #707684;--color-border-icon: rgba(201, 201, 204, .48);--color-border-icon-disabled: #EFF0F1;--color-text-icon-active: #388AE5;--color-background-icon-active: rgba(56, 138, 229, .1);--color-background-item-focus: rgba(34, 186, 255, .08);--color-shadow-item-focus: rgba(7, 161, 227, .08);--color-background-item-hover: #F8F8F8;--color-background-item-confirm: #E24A4A;--color-background-item-confirm-hover: #CE4343;--popover-top: calc(100% + var(--offset-from-target));--popover-left: 0;--nested-popover-overlap: 4px;--icon-size: 20px;--item-padding: 3px;--item-height: calc(var(--icon-size) + 2 * var(--item-padding))}.ce-popover__container{min-width:var(--width);width:var(--width);max-height:var(--max-height);border-radius:var(--border-radius);overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0px 3px 15px -3px var(--color-shadow);box-shadow:0 3px 15px -3px var(--color-shadow);position:absolute;left:var(--popover-left);top:var(--popover-top);background:var(--color-background);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;z-index:4;opacity:0;max-height:0;pointer-events:none;padding:0;border:none}.ce-popover--opened>.ce-popover__container{opacity:1;padding:var(--padding);max-height:var(--max-height);pointer-events:auto;-webkit-animation:panelShowing .1s ease;animation:panelShowing .1s ease;border:1px solid var(--color-border)}@media (max-width: 650px){.ce-popover--opened>.ce-popover__container{-webkit-animation:panelShowingMobile .25s ease;animation:panelShowingMobile .25s ease}}.ce-popover--open-top .ce-popover__container{--popover-top: calc(-1 * (var(--offset-from-target) + var(--popover-height)))}.ce-popover--open-left .ce-popover__container{--popover-left: calc(-1 * var(--width) + 100%)}.ce-popover__items{overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain}@media (max-width: 650px){.ce-popover__overlay{position:fixed;top:0;bottom:0;left:0;right:0;background:#1D202B;z-index:3;opacity:.5;-webkit-transition:opacity .12s ease-in;transition:opacity .12s ease-in;will-change:opacity;visibility:visible}}.ce-popover__overlay--hidden{display:none}@media (max-width: 650px){.ce-popover .ce-popover__container{--offset: 5px;position:fixed;max-width:none;min-width:calc(100% - var(--offset) * 2);left:var(--offset);right:var(--offset);bottom:calc(var(--offset) + env(safe-area-inset-bottom));top:auto;border-radius:10px}}.ce-popover__search{margin-bottom:5px}.ce-popover__nothing-found-message{color:#707684;display:none;cursor:default;padding:3px;font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ce-popover__nothing-found-message--displayed{display:block}.ce-popover--nested .ce-popover__container{--popover-left: calc(var(--nesting-level) * (var(--width) - var(--nested-popover-overlap)));top:calc(var(--trigger-item-top) - var(--nested-popover-overlap));position:absolute}.ce-popover--open-top.ce-popover--nested .ce-popover__container{top:calc(var(--trigger-item-top) - var(--popover-height) + var(--item-height) + var(--offset-from-target) + var(--nested-popover-overlap))}.ce-popover--open-left .ce-popover--nested .ce-popover__container{--popover-left: calc(-1 * (var(--nesting-level) + 1) * var(--width) + 100%)}.ce-popover-item-separator{padding:4px 3px}.ce-popover-item-separator--hidden{display:none}.ce-popover-item-separator__line{height:1px;background:var(--color-border);width:100%}.ce-popover-item-html--hidden{display:none}.ce-popover-item{--border-radius: 6px;border-radius:var(--border-radius);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:var(--item-padding);color:var(--color-text-primary);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;background:transparent}@media (max-width: 650px){.ce-popover-item{padding:4px}}.ce-popover-item:not(:last-of-type){margin-bottom:1px}.ce-popover-item__icon{width:26px;height:26px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ce-popover-item__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-popover-item__icon{width:36px;height:36px;border-radius:8px}.ce-popover-item__icon svg{width:28px;height:28px}}.ce-popover-item__icon--tool{margin-right:4px}.ce-popover-item__title{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-right:auto}@media (max-width: 650px){.ce-popover-item__title{font-size:16px}}.ce-popover-item__secondary-title{color:var(--color-text-secondary);font-size:12px;white-space:nowrap;letter-spacing:-.1em;padding-right:5px;opacity:.6}@media (max-width: 650px){.ce-popover-item__secondary-title{display:none}}.ce-popover-item--active{background:var(--color-background-icon-active);color:var(--color-text-icon-active)}.ce-popover-item--disabled{color:var(--color-text-secondary);cursor:default;pointer-events:none}.ce-popover-item--focused:not(.ce-popover-item--no-focus){background:var(--color-background-item-focus)!important}.ce-popover-item--hidden{display:none}@media (hover: hover){.ce-popover-item:hover{cursor:pointer}.ce-popover-item:hover:not(.ce-popover-item--no-hover){background-color:var(--color-background-item-hover)}}.ce-popover-item--confirmation{background:var(--color-background-item-confirm)}.ce-popover-item--confirmation .ce-popover-item__title,.ce-popover-item--confirmation .ce-popover-item__icon{color:#fff}@media (hover: hover){.ce-popover-item--confirmation:not(.ce-popover-item--no-hover):hover{background:var(--color-background-item-confirm-hover)}}.ce-popover-item--confirmation:not(.ce-popover-item--no-focus).ce-popover-item--focused{background:var(--color-background-item-confirm-hover)!important}@-webkit-keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble;-webkit-animation-duration:.4s;animation-duration:.4s}@-webkit-keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}.ce-popover-header{margin-bottom:8px;margin-top:4px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ce-popover-header__text{font-size:18px;font-weight:600}.ce-popover-header__back-button{border:0;background:transparent;width:36px;height:36px;color:var(--color-text-primary)}.ce-popover-header__back-button svg{display:block;width:28px;height:28px}.ce-popover--inline{--height: 38px;--height-mobile: 46px;--container-padding: 4px;position:relative}.ce-popover--inline .ce-popover__custom-content{margin-bottom:0}.ce-popover--inline .ce-popover__items{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-popover--inline .ce-popover__container{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;padding:var(--container-padding);height:var(--height);top:0;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;width:-webkit-max-content;width:-moz-max-content;width:max-content;-webkit-animation:none;animation:none}@media (max-width: 650px){.ce-popover--inline .ce-popover__container{height:var(--height-mobile);position:absolute}}.ce-popover--inline .ce-popover-item-separator{padding:0 4px}.ce-popover--inline .ce-popover-item-separator__line{height:100%;width:1px}.ce-popover--inline .ce-popover-item{border-radius:4px;padding:4px}.ce-popover--inline .ce-popover-item__icon--tool{-webkit-box-shadow:none;box-shadow:none;background:transparent;margin-right:0}.ce-popover--inline .ce-popover-item__icon{width:auto;width:initial;height:auto;height:initial}.ce-popover--inline .ce-popover-item__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-popover--inline .ce-popover-item__icon svg{width:28px;height:28px}}.ce-popover--inline .ce-popover-item:not(:last-of-type){margin-bottom:0;margin-bottom:initial}.ce-popover--inline .ce-popover-item-html{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ce-popover--inline .ce-popover-item__icon--chevron-right{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ce-popover--inline .ce-popover--nested-level-1 .ce-popover__container{--offset: 3px;left:0;top:calc(var(--height) + var(--offset))}@media (max-width: 650px){.ce-popover--inline .ce-popover--nested-level-1 .ce-popover__container{top:calc(var(--height-mobile) + var(--offset))}}.ce-popover--inline .ce-popover--nested .ce-popover__container{min-width:var(--width);width:var(--width);height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;padding:6px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ce-popover--inline .ce-popover--nested .ce-popover__items{display:block;width:100%}.ce-popover--inline .ce-popover--nested .ce-popover-item{border-radius:6px;padding:3px}@media (max-width: 650px){.ce-popover--inline .ce-popover--nested .ce-popover-item{padding:4px}}.ce-popover--inline .ce-popover--nested .ce-popover-item__icon--tool{margin-right:4px}.ce-popover--inline .ce-popover--nested .ce-popover-item__icon{width:26px;height:26px}.ce-popover--inline .ce-popover--nested .ce-popover-item-separator{padding:4px 3px}.ce-popover--inline .ce-popover--nested .ce-popover-item-separator__line{width:100%;height:1px}.codex-editor [data-placeholder]:empty:before,.codex-editor [data-placeholder][data-empty=true]:before{pointer-events:none;color:#707684;cursor:text;content:attr(data-placeholder)}.codex-editor [data-placeholder-active]:empty:before,.codex-editor [data-placeholder-active][data-empty=true]:before{pointer-events:none;color:#707684;cursor:text}.codex-editor [data-placeholder-active]:empty:focus:before,.codex-editor [data-placeholder-active][data-empty=true]:focus:before{content:attr(data-placeholder-active)}
+`;
+class Ia extends E {
+ constructor() {
+ super(...arguments), this.isMobile = !1, this.contentRectCache = null, this.resizeDebouncer = Eo(() => {
+ this.windowResize();
+ }, 200), this.selectionChangeDebounced = Eo(() => {
+ this.selectionChanged();
+ }, da), this.documentTouchedListener = (e) => {
+ this.documentTouched(e);
+ };
+ }
+ /**
+ * Editor.js UI CSS class names
+ *
+ * @returns {{editorWrapper: string, editorZone: string}}
+ */
+ get CSS() {
+ return {
+ editorWrapper: "codex-editor",
+ editorWrapperNarrow: "codex-editor--narrow",
+ editorZone: "codex-editor__redactor",
+ editorZoneHidden: "codex-editor__redactor--hidden",
+ editorEmpty: "codex-editor--empty",
+ editorRtlFix: "codex-editor--rtl"
+ };
+ }
+ /**
+ * Return Width of center column of Editor
+ *
+ * @returns {DOMRect}
+ */
+ get contentRect() {
+ if (this.contentRectCache !== null)
+ return this.contentRectCache;
+ const e = this.nodes.wrapper.querySelector(`.${R.CSS.content}`);
+ return e ? (this.contentRectCache = e.getBoundingClientRect(), this.contentRectCache) : {
+ width: 650,
+ left: 0,
+ right: 0
+ };
+ }
+ /**
+ * Making main interface
+ */
+ async prepare() {
+ this.setIsMobile(), this.make(), this.loadStyles();
+ }
+ /**
+ * Toggle read-only state
+ *
+ * If readOnly is true:
+ * - removes all listeners from main UI module elements
+ *
+ * if readOnly is false:
+ * - enables all listeners to UI module elements
+ *
+ * @param {boolean} readOnlyEnabled - "read only" state
+ */
+ toggleReadOnly(e) {
+ e ? this.unbindReadOnlySensitiveListeners() : window.requestIdleCallback(() => {
+ this.bindReadOnlySensitiveListeners();
+ }, {
+ timeout: 2e3
+ });
+ }
+ /**
+ * Check if Editor is empty and set CSS class to wrapper
+ */
+ checkEmptiness() {
+ const { BlockManager: e } = this.Editor;
+ this.nodes.wrapper.classList.toggle(this.CSS.editorEmpty, e.isEditorEmpty);
+ }
+ /**
+ * Check if one of Toolbar is opened
+ * Used to prevent global keydowns (for example, Enter) conflicts with Enter-on-toolbar
+ *
+ * @returns {boolean}
+ */
+ get someToolbarOpened() {
+ const { Toolbar: e, BlockSettings: t, InlineToolbar: o } = this.Editor;
+ return !!(t.opened || o.opened || e.toolbox.opened);
+ }
+ /**
+ * Check for some Flipper-buttons is under focus
+ */
+ get someFlipperButtonFocused() {
+ return this.Editor.Toolbar.toolbox.hasFocus() ? !0 : Object.entries(this.Editor).filter(([e, t]) => t.flipper instanceof ce).some(([e, t]) => t.flipper.hasFocus());
+ }
+ /**
+ * Clean editor`s UI
+ */
+ destroy() {
+ this.nodes.holder.innerHTML = "", this.unbindReadOnlyInsensitiveListeners();
+ }
+ /**
+ * Close all Editor's toolbars
+ */
+ closeAllToolbars() {
+ const { Toolbar: e, BlockSettings: t, InlineToolbar: o } = this.Editor;
+ t.close(), o.close(), e.toolbox.close();
+ }
+ /**
+ * Check for mobile mode and save the result
+ */
+ setIsMobile() {
+ const e = window.innerWidth < Ro;
+ e !== this.isMobile && this.eventsDispatcher.emit(Te, {
+ isEnabled: this.isMobile
+ }), this.isMobile = e;
+ }
+ /**
+ * Makes Editor.js interface
+ */
+ make() {
+ this.nodes.holder = d.getHolder(this.config.holder), this.nodes.wrapper = d.make("div", [
+ this.CSS.editorWrapper,
+ ...this.isRtl ? [this.CSS.editorRtlFix] : []
+ ]), this.nodes.redactor = d.make("div", this.CSS.editorZone), this.nodes.holder.offsetWidth < this.contentRect.width && this.nodes.wrapper.classList.add(this.CSS.editorWrapperNarrow), this.nodes.redactor.style.paddingBottom = this.config.minHeight + "px", this.nodes.wrapper.appendChild(this.nodes.redactor), this.nodes.holder.appendChild(this.nodes.wrapper), this.bindReadOnlyInsensitiveListeners();
+ }
+ /**
+ * Appends CSS
+ */
+ loadStyles() {
+ const e = "editor-js-styles";
+ if (d.get(e))
+ return;
+ const t = d.make("style", null, {
+ id: e,
+ textContent: Sa.toString()
+ });
+ this.config.style && !V(this.config.style) && this.config.style.nonce && t.setAttribute("nonce", this.config.style.nonce), d.prepend(document.head, t);
+ }
+ /**
+ * Adds listeners that should work both in read-only and read-write modes
+ */
+ bindReadOnlyInsensitiveListeners() {
+ this.listeners.on(document, "selectionchange", this.selectionChangeDebounced), this.listeners.on(window, "resize", this.resizeDebouncer, {
+ passive: !0
+ }), this.listeners.on(this.nodes.redactor, "mousedown", this.documentTouchedListener, {
+ capture: !0,
+ passive: !0
+ }), this.listeners.on(this.nodes.redactor, "touchstart", this.documentTouchedListener, {
+ capture: !0,
+ passive: !0
+ });
+ }
+ /**
+ * Removes listeners that should work both in read-only and read-write modes
+ */
+ unbindReadOnlyInsensitiveListeners() {
+ this.listeners.off(document, "selectionchange", this.selectionChangeDebounced), this.listeners.off(window, "resize", this.resizeDebouncer), this.listeners.off(this.nodes.redactor, "mousedown", this.documentTouchedListener), this.listeners.off(this.nodes.redactor, "touchstart", this.documentTouchedListener);
+ }
+ /**
+ * Adds listeners that should work only in read-only mode
+ */
+ bindReadOnlySensitiveListeners() {
+ this.readOnlyMutableListeners.on(this.nodes.redactor, "click", (e) => {
+ this.redactorClicked(e);
+ }, !1), this.readOnlyMutableListeners.on(document, "keydown", (e) => {
+ this.documentKeydown(e);
+ }, !0), this.readOnlyMutableListeners.on(document, "mousedown", (e) => {
+ this.documentClicked(e);
+ }, !0), this.watchBlockHoveredEvents(), this.enableInputsEmptyMark();
+ }
+ /**
+ * Listen redactor mousemove to emit 'block-hovered' event
+ */
+ watchBlockHoveredEvents() {
+ let e;
+ this.readOnlyMutableListeners.on(this.nodes.redactor, "mousemove", dt((t) => {
+ const o = t.target.closest(".ce-block");
+ this.Editor.BlockSelection.anyBlockSelected || o && e !== o && (e = o, this.eventsDispatcher.emit(ln, {
+ block: this.Editor.BlockManager.getBlockByChildNode(o)
+ }));
+ }, 20), {
+ passive: !0
+ });
+ }
+ /**
+ * Unbind events that should work only in read-only mode
+ */
+ unbindReadOnlySensitiveListeners() {
+ this.readOnlyMutableListeners.clearAll();
+ }
+ /**
+ * Resize window handler
+ */
+ windowResize() {
+ this.contentRectCache = null, this.setIsMobile();
+ }
+ /**
+ * All keydowns on document
+ *
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ documentKeydown(e) {
+ switch (e.keyCode) {
+ case y.ENTER:
+ this.enterPressed(e);
+ break;
+ case y.BACKSPACE:
+ case y.DELETE:
+ this.backspacePressed(e);
+ break;
+ case y.ESC:
+ this.escapePressed(e);
+ break;
+ default:
+ this.defaultBehaviour(e);
+ break;
+ }
+ }
+ /**
+ * Ignore all other document's keydown events
+ *
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ defaultBehaviour(e) {
+ const { currentBlock: t } = this.Editor.BlockManager, o = e.target.closest(`.${this.CSS.editorWrapper}`), i = e.altKey || e.ctrlKey || e.metaKey || e.shiftKey;
+ if (t !== void 0 && o === null) {
+ this.Editor.BlockEvents.keydown(e);
+ return;
+ }
+ o || t && i || (this.Editor.BlockManager.unsetCurrentBlock(), this.Editor.Toolbar.close());
+ }
+ /**
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ backspacePressed(e) {
+ const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor;
+ if (o.anyBlockSelected && !b.isSelectionExists) {
+ const s = t.removeSelectedBlocks(), r = t.insertDefaultBlockAtIndex(s, !0);
+ i.setToBlock(r, i.positions.START), o.clearSelection(e), e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation();
+ }
+ }
+ /**
+ * Escape pressed
+ * If some of Toolbar components are opened, then close it otherwise close Toolbar
+ *
+ * @param {Event} event - escape keydown event
+ */
+ escapePressed(e) {
+ this.Editor.BlockSelection.clearSelection(e), this.Editor.Toolbar.toolbox.opened ? (this.Editor.Toolbar.toolbox.close(), this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock, this.Editor.Caret.positions.END)) : this.Editor.BlockSettings.opened ? this.Editor.BlockSettings.close() : this.Editor.InlineToolbar.opened ? this.Editor.InlineToolbar.close() : this.Editor.Toolbar.close();
+ }
+ /**
+ * Enter pressed on document
+ *
+ * @param {KeyboardEvent} event - keyboard event
+ */
+ enterPressed(e) {
+ const { BlockManager: t, BlockSelection: o } = this.Editor;
+ if (this.someToolbarOpened)
+ return;
+ const i = t.currentBlockIndex >= 0;
+ if (o.anyBlockSelected && !b.isSelectionExists) {
+ o.clearSelection(e), e.preventDefault(), e.stopImmediatePropagation(), e.stopPropagation();
+ return;
+ }
+ if (!this.someToolbarOpened && i && e.target.tagName === "BODY") {
+ const s = this.Editor.BlockManager.insert();
+ e.preventDefault(), this.Editor.Caret.setToBlock(s), this.Editor.Toolbar.moveAndOpen(s);
+ }
+ this.Editor.BlockSelection.clearSelection(e);
+ }
+ /**
+ * All clicks on document
+ *
+ * @param {MouseEvent} event - Click event
+ */
+ documentClicked(e) {
+ var a, l;
+ if (!e.isTrusted)
+ return;
+ const t = e.target;
+ this.nodes.holder.contains(t) || b.isAtEditor || (this.Editor.BlockManager.unsetCurrentBlock(), this.Editor.Toolbar.close());
+ const i = (a = this.Editor.BlockSettings.nodes.wrapper) == null ? void 0 : a.contains(t), s = (l = this.Editor.Toolbar.nodes.settingsToggler) == null ? void 0 : l.contains(t), r = i || s;
+ if (this.Editor.BlockSettings.opened && !r) {
+ this.Editor.BlockSettings.close();
+ const c = this.Editor.BlockManager.getBlockByChildNode(t);
+ this.Editor.Toolbar.moveAndOpen(c);
+ }
+ this.Editor.BlockSelection.clearSelection(e);
+ }
+ /**
+ * First touch on editor
+ * Fired before click
+ *
+ * Used to change current block — we need to do it before 'selectionChange' event.
+ * Also:
+ * - Move and show the Toolbar
+ * - Set a Caret
+ *
+ * @param event - touch or mouse event
+ */
+ documentTouched(e) {
+ let t = e.target;
+ if (t === this.nodes.redactor) {
+ const o = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX, i = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;
+ t = document.elementFromPoint(o, i);
+ }
+ try {
+ this.Editor.BlockManager.setCurrentBlockByChildNode(t);
+ } catch {
+ this.Editor.RectangleSelection.isRectActivated() || this.Editor.Caret.setToTheLastBlock();
+ }
+ this.Editor.ReadOnly.isEnabled || this.Editor.Toolbar.moveAndOpen();
+ }
+ /**
+ * All clicks on the redactor zone
+ *
+ * @param {MouseEvent} event - click event
+ * @description
+ * - By clicks on the Editor's bottom zone:
+ * - if last Block is empty, set a Caret to this
+ * - otherwise, add a new empty Block and set a Caret to that
+ */
+ redactorClicked(e) {
+ if (!b.isCollapsed)
+ return;
+ const t = e.target, o = e.metaKey || e.ctrlKey;
+ if (d.isAnchor(t) && o) {
+ e.stopImmediatePropagation(), e.stopPropagation();
+ const i = t.getAttribute("href"), s = oi(i);
+ ii(s);
+ return;
+ }
+ this.processBottomZoneClick(e);
+ }
+ /**
+ * Check if user clicks on the Editor's bottom zone:
+ * - set caret to the last block
+ * - or add new empty block
+ *
+ * @param event - click event
+ */
+ processBottomZoneClick(e) {
+ const t = this.Editor.BlockManager.getBlockByIndex(-1), o = d.offset(t.holder).bottom, i = e.pageY, { BlockSelection: s } = this.Editor;
+ if (e.target instanceof Element && e.target.isEqualNode(this.nodes.redactor) && /**
+ * If there is cross block selection started, target will be equal to redactor so we need additional check
+ */
+ !s.anyBlockSelected && /**
+ * Prevent caret jumping (to last block) when clicking between blocks
+ */
+ o < i) {
+ e.stopImmediatePropagation(), e.stopPropagation();
+ const { BlockManager: a, Caret: l, Toolbar: c } = this.Editor;
+ (!a.lastBlock.tool.isDefault || !a.lastBlock.isEmpty) && a.insertAtEnd(), l.setToTheLastBlock(), c.moveAndOpen(a.lastBlock);
+ }
+ }
+ /**
+ * Handle selection changes on mobile devices
+ * Uses for showing the Inline Toolbar
+ */
+ selectionChanged() {
+ const { CrossBlockSelection: e, BlockSelection: t } = this.Editor, o = b.anchorElement;
+ if (e.isCrossBlockSelectionStarted && t.anyBlockSelected && b.get().removeAllRanges(), !o) {
+ b.range || this.Editor.InlineToolbar.close();
+ return;
+ }
+ const i = o.closest(`.${R.CSS.content}`);
+ (i === null || i.closest(`.${b.CSS.editorWrapper}`) !== this.nodes.wrapper) && (this.Editor.InlineToolbar.containsNode(o) || this.Editor.InlineToolbar.close(), !(o.dataset.inlineToolbar === "true")) || (this.Editor.BlockManager.currentBlock || this.Editor.BlockManager.setCurrentBlockByChildNode(o), this.Editor.InlineToolbar.tryToShow(!0));
+ }
+ /**
+ * Editor.js provides and ability to show placeholders for empty contenteditable elements
+ *
+ * This method watches for input and focus events and toggles 'data-empty' attribute
+ * to workaroud the case, when inputs contains only
s and has no visible content
+ * Then, CSS could rely on this attribute to show placeholders
+ */
+ enableInputsEmptyMark() {
+ function e(t) {
+ const o = t.target;
+ Do(o);
+ }
+ this.readOnlyMutableListeners.on(this.nodes.wrapper, "input", e), this.readOnlyMutableListeners.on(this.nodes.wrapper, "focusin", e), this.readOnlyMutableListeners.on(this.nodes.wrapper, "focusout", e);
+ }
+}
+const Oa = {
+ // API Modules
+ BlocksAPI: gi,
+ CaretAPI: bi,
+ EventsAPI: vi,
+ I18nAPI: kt,
+ API: ki,
+ InlineToolbarAPI: yi,
+ ListenersAPI: wi,
+ NotifierAPI: Ci,
+ ReadOnlyAPI: Ti,
+ SanitizerAPI: Li,
+ SaverAPI: Pi,
+ SelectionAPI: Ni,
+ ToolsAPI: Ri,
+ StylesAPI: Di,
+ ToolbarAPI: Fi,
+ TooltipAPI: Ui,
+ UiAPI: Wi,
+ // Toolbar Modules
+ BlockSettings: ms,
+ Toolbar: Bs,
+ InlineToolbar: Cs,
+ // Modules
+ BlockEvents: na,
+ BlockManager: ra,
+ BlockSelection: aa,
+ Caret: Ye,
+ CrossBlockSelection: la,
+ DragNDrop: ca,
+ ModificationsObserver: ha,
+ Paste: pa,
+ ReadOnly: fa,
+ RectangleSelection: Be,
+ Renderer: ga,
+ Saver: ma,
+ Tools: Wn,
+ UI: Ia
+};
+class _a {
+ /**
+ * @param {EditorConfig} config - user configuration
+ */
+ constructor(e) {
+ this.moduleInstances = {}, this.eventsDispatcher = new Oe();
+ let t, o;
+ this.isReady = new Promise((i, s) => {
+ t = i, o = s;
+ }), Promise.resolve().then(async () => {
+ this.configuration = e, this.validate(), this.init(), await this.start(), await this.render();
+ const { BlockManager: i, Caret: s, UI: r, ModificationsObserver: a } = this.moduleInstances;
+ r.checkEmptiness(), a.enable(), this.configuration.autofocus === !0 && this.configuration.readOnly !== !0 && s.setToBlock(i.blocks[0], s.positions.START), t();
+ }).catch((i) => {
+ S(`Editor.js is not ready because of ${i}`, "error"), o(i);
+ });
+ }
+ /**
+ * Setting for configuration
+ *
+ * @param {EditorConfig|string} config - Editor's config to set
+ */
+ set configuration(e) {
+ var o, i;
+ D(e) ? this.config = {
+ ...e
+ } : this.config = {
+ holder: e
+ }, ht(!!this.config.holderId, "config.holderId", "config.holder"), this.config.holderId && !this.config.holder && (this.config.holder = this.config.holderId, this.config.holderId = null), this.config.holder == null && (this.config.holder = "editorjs"), this.config.logLevel || (this.config.logLevel = Lo.VERBOSE), Zn(this.config.logLevel), ht(!!this.config.initialBlock, "config.initialBlock", "config.defaultBlock"), this.config.defaultBlock = this.config.defaultBlock || this.config.initialBlock || "paragraph", this.config.minHeight = this.config.minHeight !== void 0 ? this.config.minHeight : 300;
+ const t = {
+ type: this.config.defaultBlock,
+ data: {}
+ };
+ this.config.placeholder = this.config.placeholder || !1, this.config.sanitizer = this.config.sanitizer || {
+ p: !0,
+ b: !0,
+ a: !0
+ }, this.config.hideToolbar = this.config.hideToolbar ? this.config.hideToolbar : !1, this.config.tools = this.config.tools || {}, this.config.i18n = this.config.i18n || {}, this.config.data = this.config.data || { blocks: [] }, this.config.onReady = this.config.onReady || (() => {
+ }), this.config.onChange = this.config.onChange || (() => {
+ }), this.config.inlineToolbar = this.config.inlineToolbar !== void 0 ? this.config.inlineToolbar : !0, (V(this.config.data) || !this.config.data.blocks || this.config.data.blocks.length === 0) && (this.config.data = { blocks: [t] }), this.config.readOnly = this.config.readOnly || !1, (o = this.config.i18n) != null && o.messages && z.setDictionary(this.config.i18n.messages), this.config.i18n.direction = ((i = this.config.i18n) == null ? void 0 : i.direction) || "ltr";
+ }
+ /**
+ * Returns private property
+ *
+ * @returns {EditorConfig}
+ */
+ get configuration() {
+ return this.config;
+ }
+ /**
+ * Checks for required fields in Editor's config
+ */
+ validate() {
+ const { holderId: e, holder: t } = this.config;
+ if (e && t)
+ throw Error("«holderId» and «holder» param can't assign at the same time.");
+ if (te(t) && !d.get(t))
+ throw Error(`element with ID «${t}» is missing. Pass correct holder's ID.`);
+ if (t && D(t) && !d.isElement(t))
+ throw Error("«holder» value must be an Element node");
+ }
+ /**
+ * Initializes modules:
+ * - make and save instances
+ * - configure
+ */
+ init() {
+ this.constructModules(), this.configureModules();
+ }
+ /**
+ * Start Editor!
+ *
+ * Get list of modules that needs to be prepared and return a sequence (Promise)
+ *
+ * @returns {Promise}
+ */
+ async start() {
+ await [
+ "Tools",
+ "UI",
+ "BlockManager",
+ "Paste",
+ "BlockSelection",
+ "RectangleSelection",
+ "CrossBlockSelection",
+ "ReadOnly"
+ ].reduce(
+ (t, o) => t.then(async () => {
+ try {
+ await this.moduleInstances[o].prepare();
+ } catch (i) {
+ if (i instanceof Ho)
+ throw new Error(i.message);
+ S(`Module ${o} was skipped because of %o`, "warn", i);
+ }
+ }),
+ Promise.resolve()
+ );
+ }
+ /**
+ * Render initial data
+ */
+ render() {
+ return this.moduleInstances.Renderer.render(this.config.data.blocks);
+ }
+ /**
+ * Make modules instances and save it to the @property this.moduleInstances
+ */
+ constructModules() {
+ Object.entries(Oa).forEach(([e, t]) => {
+ try {
+ this.moduleInstances[e] = new t({
+ config: this.configuration,
+ eventsDispatcher: this.eventsDispatcher
+ });
+ } catch (o) {
+ S("[constructModules]", `Module ${e} skipped because`, "error", o);
+ }
+ });
+ }
+ /**
+ * Modules instances configuration:
+ * - pass other modules to the 'state' property
+ * - ...
+ */
+ configureModules() {
+ for (const e in this.moduleInstances)
+ Object.prototype.hasOwnProperty.call(this.moduleInstances, e) && (this.moduleInstances[e].state = this.getModulesDiff(e));
+ }
+ /**
+ * Return modules without passed name
+ *
+ * @param {string} name - module for witch modules difference should be calculated
+ */
+ getModulesDiff(e) {
+ const t = {};
+ for (const o in this.moduleInstances)
+ o !== e && (t[o] = this.moduleInstances[o]);
+ return t;
+ }
+}
+/**
+ * Editor.js
+ *
+ * @license Apache-2.0
+ * @see Editor.js
+ * @author CodeX Team
+ */
+class Aa {
+ /** Editor version */
+ static get version() {
+ return "2.31.0-rc.8";
+ }
+ /**
+ * @param {EditorConfig|string|undefined} [configuration] - user configuration
+ */
+ constructor(e) {
+ let t = () => {
+ };
+ D(e) && A(e.onReady) && (t = e.onReady);
+ const o = new _a(e);
+ this.isReady = o.isReady.then(() => {
+ this.exportAPI(o), t();
+ });
+ }
+ /**
+ * Export external API methods
+ *
+ * @param {Core} editor — Editor's instance
+ */
+ exportAPI(e) {
+ const t = ["configuration"], o = () => {
+ Object.values(e.moduleInstances).forEach((s) => {
+ A(s.destroy) && s.destroy(), s.listeners.removeAll();
+ }), zi(), e = null;
+ for (const s in this)
+ Object.prototype.hasOwnProperty.call(this, s) && delete this[s];
+ Object.setPrototypeOf(this, null);
+ };
+ t.forEach((s) => {
+ this[s] = e[s];
+ }), this.destroy = o, Object.setPrototypeOf(this, e.moduleInstances.API.methods), delete this.exportAPI, Object.entries({
+ blocks: {
+ clear: "clear",
+ render: "render"
+ },
+ caret: {
+ focus: "focus"
+ },
+ events: {
+ on: "on",
+ off: "off",
+ emit: "emit"
+ },
+ saver: {
+ save: "save"
+ }
+ }).forEach(([s, r]) => {
+ Object.entries(r).forEach(([a, l]) => {
+ this[l] = e.moduleInstances.API.methods[s][a];
+ });
+ });
+ }
+}
+export {
+ Aa as default
+};
diff --git a/httpdocs/themes/vuexy/js/editorjs/alert.js b/httpdocs/themes/vuexy/js/editorjs/alert.js
new file mode 100644
index 00000000..877bb228
--- /dev/null
+++ b/httpdocs/themes/vuexy/js/editorjs/alert.js
@@ -0,0 +1,2 @@
+/*! For license information please see bundle.js.LICENSE.txt */
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Alert=t():e.Alert=t()}(self,(()=>(()=>{var e={800:(e,t,r)=>{"use strict";r.d(t,{Z:()=>c});var n=r(81),o=r.n(n),a=r(645),i=r.n(a)()(o());i.push([e.id,".cdx-alert{position:relative;padding:10px;border-radius:5px;margin-bottom:10px}.cdx-alert-primary{background-color:#ebf8ff;border:1px solid #4299e1;color:#2b6cb0}.cdx-alert-secondary{background-color:#f7fafc;border:1px solid #cbd5e0;color:#222731}.cdx-alert-info{background-color:#e6fdff;border:1px solid #4cd4ce;color:#00727c}.cdx-alert-success{background-color:#f0fff4;border:1px solid #68d391;color:#2f855a}.cdx-alert-warning{background-color:#fffaf0;border:1px solid #ed8936;color:#c05621}.cdx-alert-danger{background-color:#fff5f5;border:1px solid #fc8181;color:#c53030}.cdx-alert-light{background-color:#fff;border:1px solid #edf2f7;color:#1a202c}.cdx-alert-dark{background-color:#2d3748;border:1px solid #1a202c;color:#d3d3d3}.cdx-alert-align-left{text-align:left}.cdx-alert-align-center{text-align:center}.cdx-alert-align-right{text-align:right}.cdx-alert__message{outline:none}.cdx-alert [contentEditable=true][data-placeholder]::before{position:absolute;content:attr(data-placeholder);color:#707684;font-weight:normal;opacity:0}.cdx-alert [contentEditable=true][data-placeholder]:empty::before{opacity:1}.cdx-alert [contentEditable=true][data-placeholder]:empty:focus::before{opacity:0}.ce-popover__item[data-item-name=alert-primary] .ce-popover__item-icon svg #background{fill:#ebf8ff;stroke:#4299e1}.ce-popover__item[data-item-name=alert-primary] .ce-popover__item-icon svg #content{fill:#2b6cb0}.ce-popover__item[data-item-name=alert-secondary] .ce-popover__item-icon svg #background{fill:#f7fafc;stroke:#cbd5e0}.ce-popover__item[data-item-name=alert-secondary] .ce-popover__item-icon svg #content{fill:#222731}.ce-popover__item[data-item-name=alert-info] .ce-popover__item-icon svg #background{fill:#e6fdff;stroke:#4cd4ce}.ce-popover__item[data-item-name=alert-info] .ce-popover__item-icon svg #content{fill:#00727c}.ce-popover__item[data-item-name=alert-success] .ce-popover__item-icon svg #background{fill:#f0fff4;stroke:#68d391}.ce-popover__item[data-item-name=alert-success] .ce-popover__item-icon svg #content{fill:#2f855a}.ce-popover__item[data-item-name=alert-warning] .ce-popover__item-icon svg #background{fill:#fffaf0;stroke:#ed8936}.ce-popover__item[data-item-name=alert-warning] .ce-popover__item-icon svg #content{fill:#c05621}.ce-popover__item[data-item-name=alert-danger] .ce-popover__item-icon svg #background{fill:#fff5f5;stroke:#fc8181}.ce-popover__item[data-item-name=alert-danger] .ce-popover__item-icon svg #content{fill:#c53030}.ce-popover__item[data-item-name=alert-light] .ce-popover__item-icon svg #background{fill:#fff;stroke:#edf2f7}.ce-popover__item[data-item-name=alert-light] .ce-popover__item-icon svg #content{fill:#1a202c}.ce-popover__item[data-item-name=alert-dark] .ce-popover__item-icon svg #background{fill:#2d3748;stroke:#1a202c}.ce-popover__item[data-item-name=alert-dark] .ce-popover__item-icon svg #content{fill:#d3d3d3}",""]);const c=i},645:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var r="",n=void 0!==t[5];return t[4]&&(r+="@supports (".concat(t[4],") {")),t[2]&&(r+="@media ".concat(t[2]," {")),n&&(r+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),r+=e(t),n&&(r+="}"),t[2]&&(r+="}"),t[4]&&(r+="}"),r})).join("")},t.i=function(e,r,n,o,a){"string"==typeof e&&(e=[[null,e,void 0]]);var i={};if(n)for(var c=0;c0?" ".concat(p[5]):""," {").concat(p[1],"}")),p[5]=a),r&&(p[2]?(p[1]="@media ".concat(p[2]," {").concat(p[1],"}"),p[2]=r):p[2]=r),o&&(p[4]?(p[1]="@supports (".concat(p[4],") {").concat(p[1],"}"),p[4]=o):p[4]="".concat(o)),t.push(p))}},t}},81:e=>{"use strict";e.exports=function(e){return e[1]}},620:(e,t,r)=>{"use strict";var n=r(379),o=r.n(n),a=r(795),i=r.n(a),c=r(569),l=r.n(c),s=r(565),p=r.n(s),d=r(216),u=r.n(d),f=r(589),g=r.n(f),m=r(800),v={};v.styleTagTransform=g(),v.setAttributes=p(),v.insert=l().bind(null,"head"),v.domAPI=i(),v.insertStyleElement=u(),o()(m.Z,v),m.Z&&m.Z.locals&&m.Z.locals},379:e=>{"use strict";var t=[];function r(e){for(var r=-1,n=0;n{"use strict";var t={};e.exports=function(e,r){var n=function(e){if(void 0===t[e]){var r=document.querySelector(e);if(window.HTMLIFrameElement&&r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(e){r=null}t[e]=r}return t[e]}(e);if(!n)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");n.appendChild(r)}},216:e=>{"use strict";e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},565:(e,t,r)=>{"use strict";e.exports=function(e){var t=r.nc;t&&e.setAttribute("nonce",t)}},795:e=>{"use strict";e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=e.insertStyleElement(e);return{update:function(r){!function(e,t,r){var n="";r.supports&&(n+="@supports (".concat(r.supports,") {")),r.media&&(n+="@media ".concat(r.media," {"));var o=void 0!==r.layer;o&&(n+="@layer".concat(r.layer.length>0?" ".concat(r.layer):""," {")),n+=r.css,o&&(n+="}"),r.media&&(n+="}"),r.supports&&(n+="}");var a=r.sourceMap;a&&"undefined"!=typeof btoa&&(n+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),t.styleTagTransform(n,e,t.options)}(t,e,r)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},589:e=>{"use strict";e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},749:e=>{e.exports=''},454:e=>{e.exports=''},431:e=>{e.exports=''},654:e=>{e.exports=''},338:e=>{e.exports=''}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={id:n,exports:{}};return e[n](a,a.exports,r),a.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.nc=void 0;var n={};return(()=>{"use strict";r.d(n,{default:()=>_});var e=r(654),t=r.n(e),o=r(338),a=r.n(o),i=r(454),c=r.n(i),l=r(749),s=r.n(l),p=r(431),d=r.n(p);function u(e){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},u(e)}function f(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function g(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r1&&void 0!==arguments[1]?arguments[1]:null,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=document.createElement(e);for(var a in Array.isArray(r)?(t=o.classList).add.apply(t,v(r)):r&&o.classList.add(r),n)o[a]=n[a];return o}},{key:"onPaste",value:function(e){var t=e.detail.data;this.data={type:this.defaultType,message:t.innerHTML||""}}}],o=[{key:"toolbox",get:function(){return{icon:t(),title:"Alert"}}},{key:"enableLineBreaks",get:function(){return!0}},{key:"DEFAULT_TYPE",get:function(){return"info"}},{key:"DEFAULT_ALIGN_TYPE",get:function(){return"left"}},{key:"DEFAULT_MESSAGE_PLACEHOLDER",get:function(){return"Type here..."}},{key:"ALERT_TYPES",get:function(){return["primary","secondary","info","success","warning","danger","light","dark"]}},{key:"ALIGN_TYPES",get:function(){return["left","center","right"]}},{key:"isReadOnlySupported",get:function(){return!0}},{key:"conversionConfig",get:function(){var e=this;return{export:function(e){return e.message},import:function(t){return{message:t,type:e.DEFAULT_TYPE,alignType:e.DEFAULT_ALIGN_TYPE}}}}},{key:"sanitize",get:function(){return{message:!0,type:!1,alignType:!1}}}],n&&y(r.prototype,n),o&&y(r,o),Object.defineProperty(r,"prototype",{writable:!1}),e}()})(),n.default})()));
\ No newline at end of file
diff --git a/httpdocs/themes/vuexy/js/editorjs/drag-drop.js b/httpdocs/themes/vuexy/js/editorjs/drag-drop.js
new file mode 100644
index 00000000..b9fa8dd2
--- /dev/null
+++ b/httpdocs/themes/vuexy/js/editorjs/drag-drop.js
@@ -0,0 +1,7 @@
+/**
+ * Skipped minification because the original files appears to be already minified.
+ * Original file: /npm/editorjs-drag-drop@1.1.16/dist/bundle.js
+ *
+ * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
+ */
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.DragDrop=t():e.DragDrop=t()}(self,(()=>(()=>{"use strict";var e={523:(e,t,r)=>{r.d(t,{A:()=>c});var n=r(601),o=r.n(n),i=r(314),a=r.n(i)()(o());a.push([e.id,'.ce-block--drop-target .ce-block__content:before {\n content: "";\n position: absolute;\n top: 50%;\n left: -20px;\n margin-top: -1px;\n height: 8px;\n width: 8px;\n border: solid #a0a0a0;\n border-width: 1px 1px 0 0;\n -webkit-transform-origin: right;\n transform-origin: right;\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n}\n\n.ce-block--drop-target .ce-block__content:after {\n background: none;\n}\n',""]);const c=a},314:e=>{e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var r="",n=void 0!==t[5];return t[4]&&(r+="@supports (".concat(t[4],") {")),t[2]&&(r+="@media ".concat(t[2]," {")),n&&(r+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),r+=e(t),n&&(r+="}"),t[2]&&(r+="}"),t[4]&&(r+="}"),r})).join("")},t.i=function(e,r,n,o,i){"string"==typeof e&&(e=[[null,e,void 0]]);var a={};if(n)for(var c=0;c0?" ".concat(u[5]):""," {").concat(u[1],"}")),u[5]=i),r&&(u[2]?(u[1]="@media ".concat(u[2]," {").concat(u[1],"}"),u[2]=r):u[2]=r),o&&(u[4]?(u[1]="@supports (".concat(u[4],") {").concat(u[1],"}"),u[4]=o):u[4]="".concat(o)),t.push(u))}},t}},601:e=>{e.exports=function(e){return e[1]}},72:e=>{var t=[];function r(e){for(var r=-1,n=0;n{var t={};e.exports=function(e,r){var n=function(e){if(void 0===t[e]){var r=document.querySelector(e);if(window.HTMLIFrameElement&&r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(e){r=null}t[e]=r}return t[e]}(e);if(!n)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");n.appendChild(r)}},540:e=>{e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},56:(e,t,r)=>{e.exports=function(e){var t=r.nc;t&&e.setAttribute("nonce",t)}},825:e=>{e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=e.insertStyleElement(e);return{update:function(r){!function(e,t,r){var n="";r.supports&&(n+="@supports (".concat(r.supports,") {")),r.media&&(n+="@media ".concat(r.media," {"));var o=void 0!==r.layer;o&&(n+="@layer".concat(r.layer.length>0?" ".concat(r.layer):""," {")),n+=r.css,o&&(n+="}"),r.media&&(n+="}"),r.supports&&(n+="}");var i=r.sourceMap;i&&"undefined"!=typeof btoa&&(n+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i))))," */")),t.styleTagTransform(n,e,t.options)}(t,e,r)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},113:e=>{e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={id:n,exports:{}};return e[n](i,i.exports,r),i.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.nc=void 0;var n={};return(()=>{r.d(n,{default:()=>g});var e=r(72),t=r.n(e),o=r(825),i=r.n(o),a=r(659),c=r.n(a),s=r(56),l=r.n(s),u=r(540),d=r.n(u),f=r(113),p=r.n(f),v=r(523),y={};function h(e){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},h(e)}function b(e,t){for(var r=0;rr.startBlock?o.style.borderBottom=r.borderStyle:o.style.borderTop=r.borderStyle}))}},{key:"setDropListener",value:function(){var e=this;document.addEventListener("drop",(function(t){var r=t.target;if(e.holder.contains(r)&&null!==e.startBlock){var n=e.getDropTarget(r);if(n){var o=n.querySelector(".ce-block__content");o.style.removeProperty("border-top"),o.style.removeProperty("border-bottom"),e.endBlock=e.getTargetPosition(n),e.moveBlocks()}}e.startBlock=null}))}},{key:"getDropTarget",value:function(e){return e.classList.contains("ce-block")?e:e.closest(".ce-block")}},{key:"getTargetPosition",value:function(e){return Array.from(e.parentNode.children).indexOf(e)}},{key:"isTheOnlyBlock",value:function(){return 1===this.api.getBlocksCount()}},{key:"moveBlocks",value:function(){this.isTheOnlyBlock()||this.api.move(this.endBlock,this.startBlock)}}])&&b(e.prototype,t),r&&b(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e;var e,t,r}()})(),n.default})()));
\ No newline at end of file
diff --git a/httpdocs/themes/vuexy/js/editorjs/header.js b/httpdocs/themes/vuexy/js/editorjs/header.js
new file mode 100644
index 00000000..df564934
--- /dev/null
+++ b/httpdocs/themes/vuexy/js/editorjs/header.js
@@ -0,0 +1,15 @@
+/**
+ * Skipped minification because the original files appears to be already minified.
+ * Original file: /npm/@editorjs/header@2.8.8/dist/header.umd.js
+ *
+ * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
+ */
+(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".ce-header{padding:.6em 0 3px;margin:0;line-height:1.25em;outline:none}.ce-header p,.ce-header div{padding:0!important;margin:0!important}")),document.head.appendChild(e)}}catch(n){console.error("vite-plugin-css-injected-by-js",n)}})();
+(function(n,s){typeof exports=="object"&&typeof module<"u"?module.exports=s():typeof define=="function"&&define.amd?define(s):(n=typeof globalThis<"u"?globalThis:n||self,n.Header=s())})(this,function(){"use strict";const n="",s='',a='',h='',d='',u='',g='',c='';/**
+ * Header block for the Editor.js.
+ *
+ * @author CodeX (team@ifmo.su)
+ * @copyright CodeX 2018
+ * @license MIT
+ * @version 2.0.0
+ */class v{constructor({data:e,config:t,api:i,readOnly:r}){this.api=i,this.readOnly=r,this._settings=t,this._data=this.normalizeData(e),this._element=this.getTag()}get _CSS(){return{block:this.api.styles.block,wrapper:"ce-header"}}isHeaderData(e){return e.text!==void 0}normalizeData(e){const t={text:"",level:this.defaultLevel.number};return this.isHeaderData(e)&&(t.text=e.text||"",e.level!==void 0&&!isNaN(parseInt(e.level.toString()))&&(t.level=parseInt(e.level.toString()))),t}render(){return this._element}renderSettings(){return this.levels.map(e=>({icon:e.svg,label:this.api.i18n.t(`Heading ${e.number}`),onActivate:()=>this.setLevel(e.number),closeOnActivate:!0,isActive:this.currentLevel.number===e.number,render:()=>document.createElement("div")}))}setLevel(e){this.data={level:e,text:this.data.text}}merge(e){this._element.insertAdjacentHTML("beforeend",e.text)}validate(e){return e.text.trim()!==""}save(e){return{text:e.innerHTML,level:this.currentLevel.number}}static get conversionConfig(){return{export:"text",import:"text"}}static get sanitize(){return{level:!1,text:{}}}static get isReadOnlySupported(){return!0}get data(){return this._data.text=this._element.innerHTML,this._data.level=this.currentLevel.number,this._data}set data(e){if(this._data=this.normalizeData(e),e.level!==void 0&&this._element.parentNode){const t=this.getTag();t.innerHTML=this._element.innerHTML,this._element.parentNode.replaceChild(t,this._element),this._element=t}e.text!==void 0&&(this._element.innerHTML=this._data.text||"")}getTag(){const e=document.createElement(this.currentLevel.tag);return e.innerHTML=this._data.text||"",e.classList.add(this._CSS.wrapper),e.contentEditable=this.readOnly?"false":"true",e.dataset.placeholder=this.api.i18n.t(this._settings.placeholder||""),e}get currentLevel(){let e=this.levels.find(t=>t.number===this._data.level);return e||(e=this.defaultLevel),e}get defaultLevel(){if(this._settings.defaultLevel){const e=this.levels.find(t=>t.number===this._settings.defaultLevel);if(e)return e;console.warn("(ง'̀-'́)ง Heading Tool: the default level specified was not found in available levels")}return this.levels[1]}get levels(){const e=[{number:1,tag:"H1",svg:s},{number:2,tag:"H2",svg:a},{number:3,tag:"H3",svg:h},{number:4,tag:"H4",svg:d},{number:5,tag:"H5",svg:u},{number:6,tag:"H6",svg:g}];return this._settings.levels?e.filter(t=>this._settings.levels.includes(t.number)):e}onPaste(e){const t=e.detail;if("data"in t){const i=t.data;let r=this.defaultLevel.number;switch(i.tagName){case"H1":r=1;break;case"H2":r=2;break;case"H3":r=3;break;case"H4":r=4;break;case"H5":r=5;break;case"H6":r=6;break}this._settings.levels&&(r=this._settings.levels.reduce((o,l)=>Math.abs(l-r)',R='',x='',B='';function M(C,a=null,i={}){const s=document.createElement(C);Array.isArray(a)?s.classList.add(...a):a!==null&&s.classList.add(a);for(const r in i)i.hasOwnProperty(r)&&(s[r]=i[r]);return s}var O=(C=>(C.Empty="empty",C.Uploading="uploading",C.Filled="filled",C))(O||{});class D{constructor({api:a,config:i,onSelectFile:s,readOnly:r}){this.api=a,this.config=i,this.onSelectFile=s,this.readOnly=r,this.nodes={wrapper:M("div",[this.CSS.baseClass,this.CSS.wrapper]),imageContainer:M("div",[this.CSS.imageContainer]),fileButton:this.createFileButton(),imageEl:void 0,imagePreloader:M("div",this.CSS.imagePreloader),caption:M("div",[this.CSS.input,this.CSS.caption],{contentEditable:!this.readOnly})},this.nodes.caption.dataset.placeholder=this.config.captionPlaceholder,this.nodes.imageContainer.appendChild(this.nodes.imagePreloader),this.nodes.wrapper.appendChild(this.nodes.imageContainer),this.nodes.wrapper.appendChild(this.nodes.caption),this.nodes.wrapper.appendChild(this.nodes.fileButton)}applyTune(a,i){this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${a}`,i)}render(){return this.toggleStatus("empty"),this.nodes.wrapper}showPreloader(a){this.nodes.imagePreloader.style.backgroundImage=`url(${a})`,this.toggleStatus("uploading")}hidePreloader(){this.nodes.imagePreloader.style.backgroundImage="",this.toggleStatus("empty")}fillImage(a){const i=/\.mp4$/.test(a)?"VIDEO":"IMG",s={src:a};let r="load";i==="VIDEO"&&(s.autoplay=!0,s.loop=!0,s.muted=!0,s.playsinline=!0,r="loadeddata"),this.nodes.imageEl=M(i,this.CSS.imageEl,s),this.nodes.imageEl.addEventListener(r,()=>{this.toggleStatus("filled"),this.nodes.imagePreloader!==void 0&&(this.nodes.imagePreloader.style.backgroundImage="")}),this.nodes.imageContainer.appendChild(this.nodes.imageEl)}fillCaption(a){this.nodes.caption!==void 0&&(this.nodes.caption.innerHTML=a)}toggleStatus(a){for(const i in O)if(Object.prototype.hasOwnProperty.call(O,i)){const s=O[i];this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${s}`,s===a)}}get CSS(){return{baseClass:this.api.styles.block,loading:this.api.styles.loader,input:this.api.styles.input,button:this.api.styles.button,wrapper:"image-tool",imageContainer:"image-tool__image",imagePreloader:"image-tool__image-preloader",imageEl:"image-tool__image-picture",caption:"image-tool__caption"}}createFileButton(){const a=M("div",[this.CSS.button]);return a.innerHTML=this.config.buttonContent??`${R} ${this.api.i18n.t("Select an Image")}`,a.addEventListener("click",()=>{this.onSelectFile()}),a}}function U(C){return C&&C.__esModule&&Object.prototype.hasOwnProperty.call(C,"default")?C.default:C}var I={exports:{}};(function(C,a){(function(i,s){C.exports=s()})(window,function(){return function(i){var s={};function r(o){if(s[o])return s[o].exports;var e=s[o]={i:o,l:!1,exports:{}};return i[o].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=i,r.c=s,r.d=function(o,e,d){r.o(o,e)||Object.defineProperty(o,e,{enumerable:!0,get:d})},r.r=function(o){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},r.t=function(o,e){if(1&e&&(o=r(o)),8&e||4&e&&typeof o=="object"&&o&&o.__esModule)return o;var d=Object.create(null);if(r.r(d),Object.defineProperty(d,"default",{enumerable:!0,value:o}),2&e&&typeof o!="string")for(var v in o)r.d(d,v,(function(l){return o[l]}).bind(null,v));return d},r.n=function(o){var e=o&&o.__esModule?function(){return o.default}:function(){return o};return r.d(e,"a",e),e},r.o=function(o,e){return Object.prototype.hasOwnProperty.call(o,e)},r.p="",r(r.s=3)}([function(i,s){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch{typeof window=="object"&&(r=window)}i.exports=r},function(i,s,r){(function(o){var e=r(2),d=setTimeout;function v(){}function l(n){if(!(this instanceof l))throw new TypeError("Promises must be constructed via new");if(typeof n!="function")throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],t(n,this)}function f(n,c){for(;n._state===3;)n=n._value;n._state!==0?(n._handled=!0,l._immediateFn(function(){var u=n._state===1?c.onFulfilled:c.onRejected;if(u!==null){var g;try{g=u(n._value)}catch(m){return void y(c.promise,m)}p(c.promise,g)}else(n._state===1?p:y)(c.promise,n._value)})):n._deferreds.push(c)}function p(n,c){try{if(c===n)throw new TypeError("A promise cannot be resolved with itself.");if(c&&(typeof c=="object"||typeof c=="function")){var u=c.then;if(c instanceof l)return n._state=3,n._value=c,void w(n);if(typeof u=="function")return void t((g=u,m=c,function(){g.apply(m,arguments)}),n)}n._state=1,n._value=c,w(n)}catch(h){y(n,h)}var g,m}function y(n,c){n._state=2,n._value=c,w(n)}function w(n){n._state===2&&n._deferreds.length===0&&l._immediateFn(function(){n._handled||l._unhandledRejectionFn(n._value)});for(var c=0,u=n._deferreds.length;c0&&arguments[0]!==void 0?arguments[0]:{};if(t.url&&typeof t.url!="string")throw new Error("Url must be a string");if(t.url=t.url||"",t.method&&typeof t.method!="string")throw new Error("`method` must be a string or null");if(t.method=t.method?t.method.toUpperCase():"GET",t.headers&&o(t.headers)!=="object")throw new Error("`headers` must be an object or null");if(t.headers=t.headers||{},t.type&&(typeof t.type!="string"||!Object.values(e).includes(t.type)))throw new Error("`type` must be taken from module's «contentType» library");if(t.progress&&typeof t.progress!="function")throw new Error("`progress` must be a function or null");if(t.progress=t.progress||function(n){},t.beforeSend=t.beforeSend||function(n){},t.ratio&&typeof t.ratio!="number")throw new Error("`ratio` must be a number");if(t.ratio<0||t.ratio>100)throw new Error("`ratio` must be in a 0-100 interval");if(t.ratio=t.ratio||90,t.accept&&typeof t.accept!="string")throw new Error("`accept` must be a string with a list of allowed mime-types");if(t.accept=t.accept||"*/*",t.multiple&&typeof t.multiple!="boolean")throw new Error("`multiple` must be a true or false");if(t.multiple=t.multiple||!1,t.fieldName&&typeof t.fieldName!="string")throw new Error("`fieldName` must be a string");return t.fieldName=t.fieldName||"files",t},f=function(t){switch(t.method){case"GET":var n=p(t.data,e.URLENCODED);delete t.data,t.url=/\?/.test(t.url)?t.url+"&"+n:t.url+"?"+n;break;case"POST":case"PUT":case"DELETE":case"UPDATE":var c=function(){return(arguments.length>0&&arguments[0]!==void 0?arguments[0]:{}).type||e.JSON}(t);(w.isFormData(t.data)||w.isFormElement(t.data))&&(c=e.FORM),t.data=p(t.data,c),c!==b.contentType.FORM&&(t.headers["content-type"]=c)}return t},p=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};switch(arguments.length>1?arguments[1]:void 0){case e.URLENCODED:return w.urlEncode(t);case e.JSON:return w.jsonEncode(t);case e.FORM:return w.formEncode(t);default:return t}},y=function(t){return t>=200&&t<300},{contentType:e={URLENCODED:"application/x-www-form-urlencoded; charset=utf-8",FORM:"multipart/form-data",JSON:"application/json; charset=utf-8"},request:d,get:function(t){return t.method="GET",d(t)},post:v,transport:function(t){return t=l(t),w.selectFiles(t).then(function(n){for(var c=new FormData,u=0;u=0&&(l._idleTimeoutId=setTimeout(function(){l._onTimeout&&l._onTimeout()},f))},r(6),s.setImmediate=typeof self<"u"&&self.setImmediate||o!==void 0&&o.setImmediate||this&&this.setImmediate,s.clearImmediate=typeof self<"u"&&self.clearImmediate||o!==void 0&&o.clearImmediate||this&&this.clearImmediate}).call(this,r(0))},function(i,s,r){(function(o,e){(function(d,v){if(!d.setImmediate){var l,f,p,y,w,b=1,t={},n=!1,c=d.document,u=Object.getPrototypeOf&&Object.getPrototypeOf(d);u=u&&u.setTimeout?u:d,{}.toString.call(d.process)==="[object process]"?l=function(h){e.nextTick(function(){m(h)})}:function(){if(d.postMessage&&!d.importScripts){var h=!0,k=d.onmessage;return d.onmessage=function(){h=!1},d.postMessage("","*"),d.onmessage=k,h}}()?(y="setImmediate$"+Math.random()+"$",w=function(h){h.source===d&&typeof h.data=="string"&&h.data.indexOf(y)===0&&m(+h.data.slice(y.length))},d.addEventListener?d.addEventListener("message",w,!1):d.attachEvent("onmessage",w),l=function(h){d.postMessage(y+h,"*")}):d.MessageChannel?((p=new MessageChannel).port1.onmessage=function(h){m(h.data)},l=function(h){p.port2.postMessage(h)}):c&&"onreadystatechange"in c.createElement("script")?(f=c.documentElement,l=function(h){var k=c.createElement("script");k.onreadystatechange=function(){m(h),k.onreadystatechange=null,f.removeChild(k),k=null},f.appendChild(k)}):l=function(h){setTimeout(m,0,h)},u.setImmediate=function(h){typeof h!="function"&&(h=new Function(""+h));for(var k=new Array(arguments.length-1),T=0;T"u"?o===void 0?this:o:self)}).call(this,r(0),r(7))},function(i,s){var r,o,e=i.exports={};function d(){throw new Error("setTimeout has not been defined")}function v(){throw new Error("clearTimeout has not been defined")}function l(u){if(r===setTimeout)return setTimeout(u,0);if((r===d||!r)&&setTimeout)return r=setTimeout,setTimeout(u,0);try{return r(u,0)}catch{try{return r.call(null,u,0)}catch{return r.call(this,u,0)}}}(function(){try{r=typeof setTimeout=="function"?setTimeout:d}catch{r=d}try{o=typeof clearTimeout=="function"?clearTimeout:v}catch{o=v}})();var f,p=[],y=!1,w=-1;function b(){y&&f&&(y=!1,f.length?p=f.concat(p):w=-1,p.length&&t())}function t(){if(!y){var u=l(b);y=!0;for(var g=p.length;g;){for(f=p,p=[];++w1)for(var m=1;m HTMLElement")}},{key:"isObject",value:function(p){return Object.prototype.toString.call(p)==="[object Object]"}},{key:"isFormData",value:function(p){return p instanceof FormData}},{key:"isFormElement",value:function(p){return p instanceof HTMLFormElement}},{key:"selectFiles",value:function(){var p=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return new Promise(function(y,w){var b=document.createElement("INPUT");b.type="file",p.multiple&&b.setAttribute("multiple","multiple"),p.accept&&b.setAttribute("accept",p.accept),b.style.display="none",document.body.appendChild(b),b.addEventListener("change",function(t){var n=t.target.files;y(n),document.body.removeChild(b)},!1),b.click()})}},{key:"parseHeaders",value:function(p){var y=p.trim().split(/[\r\n]+/),w={};return y.forEach(function(b){var t=b.split(": "),n=t.shift(),c=t.join(": ");n&&(w[n]=c)}),w}}],(l=null)&&o(v.prototype,l),f&&o(v,f),d}()},function(i,s){var r=function(e){return encodeURIComponent(e).replace(/[!'()*]/g,escape).replace(/%20/g,"+")},o=function(e,d,v,l){return d=d||null,v=v||"&",l=l||null,e?function(f){for(var p=new Array,y=0;y{a(e.target.result)}};let s;if(this.config.uploader&&typeof this.config.uploader.uploadByFile=="function"){const r=this.config.uploader.uploadByFile;s=S.selectFiles({accept:this.config.types??"image/*"}).then(o=>{i(o[0]);const e=r(o[0]);return L(e)||console.warn("Custom uploader method uploadByFile should return a Promise"),e})}else s=S.transport({url:this.config.endpoints.byFile,data:this.config.additionalRequestData,accept:this.config.types??"image/*",headers:this.config.additionalRequestHeaders,beforeSend:r=>{i(r[0])},fieldName:this.config.field??"image"}).then(r=>r.body);s.then(r=>{this.onUpload(r)}).catch(r=>{this.onError(r)})}uploadByUrl(a){let i;this.config.uploader&&typeof this.config.uploader.uploadByUrl=="function"?(i=this.config.uploader.uploadByUrl(a),L(i)||console.warn("Custom uploader method uploadByUrl should return a Promise")):i=S.post({url:this.config.endpoints.byUrl,data:Object.assign({url:a},this.config.additionalRequestData),type:S.contentType.JSON,headers:this.config.additionalRequestHeaders}).then(s=>s.body),i.then(s=>{this.onUpload(s)}).catch(s=>{this.onError(s)})}uploadByFile(a,{onPreview:i}){const s=new FileReader;s.readAsDataURL(a),s.onload=o=>{i(o.target.result)};let r;if(this.config.uploader&&typeof this.config.uploader.uploadByFile=="function")r=this.config.uploader.uploadByFile(a),L(r)||console.warn("Custom uploader method uploadByFile should return a Promise");else{const o=new FormData;o.append(this.config.field??"image",a),this.config.additionalRequestData&&Object.keys(this.config.additionalRequestData).length&&Object.entries(this.config.additionalRequestData).forEach(([e,d])=>{o.append(e,d)}),r=S.post({url:this.config.endpoints.byFile,data:o,type:S.contentType.JSON,headers:this.config.additionalRequestHeaders}).then(e=>e.body)}r.then(o=>{this.onUpload(o)}).catch(o=>{this.onError(o)})}}/**
+ * Image Tool for the Editor.js
+ * @author CodeX
+ * @license MIT
+ * @see {@link https://github.com/editor-js/image}
+ *
+ * To developers.
+ * To simplify Tool structure, we split it to 4 parts:
+ * 1) index.ts — main Tool's interface, public API and methods for working with data
+ * 2) uploader.ts — module that has methods for sending files via AJAX: from device, by URL or File pasting
+ * 3) ui.ts — module for UI manipulations: render, showing preloader, etc
+ *
+ * For debug purposes there is a testing server
+ * that can save uploaded files and return a Response {@link UploadResponseFormat}
+ *
+ * $ node dev/server.js
+ *
+ * It will expose 8008 port, so you can pass http://localhost:8008 with the Tools config:
+ *
+ * image: {
+ * class: ImageTool,
+ * config: {
+ * endpoints: {
+ * byFile: 'http://localhost:8008/uploadFile',
+ * byUrl: 'http://localhost:8008/fetchUrl',
+ * }
+ * },
+ * },
+ */class P{constructor({data:a,config:i,api:s,readOnly:r,block:o}){this.isCaptionEnabled=null,this.api=s,this.block=o,this.config={endpoints:i.endpoints,additionalRequestData:i.additionalRequestData,additionalRequestHeaders:i.additionalRequestHeaders,field:i.field,types:i.types,captionPlaceholder:this.api.i18n.t(i.captionPlaceholder??"Caption"),buttonContent:i.buttonContent,uploader:i.uploader,actions:i.actions,features:i.features||{}},this.uploader=new A({config:this.config,onUpload:e=>this.onUpload(e),onError:e=>this.uploadingFailed(e)}),this.ui=new D({api:s,config:this.config,onSelectFile:()=>{this.uploader.uploadSelectedFile({onPreview:e=>{this.ui.showPreloader(e)}})},readOnly:r}),this._data={caption:"",withBorder:!1,withBackground:!1,stretched:!1,file:{url:""}},this.data=a}static get isReadOnlySupported(){return!0}static get toolbox(){return{icon:R,title:"Image"}}static get tunes(){return[{name:"withBorder",icon:F,title:"With border",toggle:!0},{name:"stretched",icon:x,title:"Stretch image",toggle:!0},{name:"withBackground",icon:_,title:"With background",toggle:!0}]}render(){var a,i,s;return(((a=this.config.features)==null?void 0:a.caption)===!0||((i=this.config.features)==null?void 0:i.caption)===void 0||((s=this.config.features)==null?void 0:s.caption)==="optional"&&this.data.caption)&&(this.isCaptionEnabled=!0),this.ui.render()}validate(a){return!!a.file.url}save(){const a=this.ui.nodes.caption;return this._data.caption=a.innerHTML,this.data}renderSettings(){var o;const a=P.tunes.concat(this.config.actions||[]),i={border:"withBorder",background:"withBackground",stretch:"stretched",caption:"caption"};((o=this.config.features)==null?void 0:o.caption)==="optional"&&a.push({name:"caption",icon:B,title:"With caption",toggle:!0});const s=a.filter(e=>{var v,l;const d=Object.keys(i).find(f=>i[f]===e.name);return d==="caption"?((v=this.config.features)==null?void 0:v.caption)!==!1:d==null||((l=this.config.features)==null?void 0:l[d])!==!1}),r=e=>{let d=this.data[e.name];return e.name==="caption"&&(d=this.isCaptionEnabled??d),d};return s.map(e=>({icon:e.icon,label:this.api.i18n.t(e.title),name:e.name,toggle:e.toggle,isActive:r(e),onActivate:()=>{if(typeof e.action=="function"){e.action(e.name);return}let d=!r(e);e.name==="caption"&&(this.isCaptionEnabled=!(this.isCaptionEnabled??!1),d=this.isCaptionEnabled),this.tuneToggled(e.name,d)}}))}appendCallback(){this.ui.nodes.fileButton.click()}static get pasteConfig(){return{tags:[{img:{src:!0}}],patterns:{image:/https?:\/\/\S+\.(gif|jpe?g|tiff|png|svg|webp)(\?[a-z0-9=]*)?$/i},files:{mimeTypes:["image/*"]}}}async onPaste(a){switch(a.type){case"tag":{const i=a.detail.data;if(/^blob:/.test(i.src)){const r=await(await fetch(i.src)).blob();this.uploadFile(r);break}this.uploadUrl(i.src);break}case"pattern":{const i=a.detail.data;this.uploadUrl(i);break}case"file":{const i=a.detail.file;this.uploadFile(i);break}}}set data(a){this.image=a.file,this._data.caption=a.caption||"",this.ui.fillCaption(this._data.caption),P.tunes.forEach(({name:i})=>{const s=typeof a[i]<"u"?a[i]===!0||a[i]==="true":!1;this.setTune(i,s)}),a.caption&&this.setTune("caption",!0)}get data(){return this._data}set image(a){this._data.file=a||{url:""},a&&a.url&&this.ui.fillImage(a.url)}onUpload(a){a.success&&a.file?this.image=a.file:this.uploadingFailed("incorrect response: "+JSON.stringify(a))}uploadingFailed(a){console.log("Image Tool: uploading failed because of",a),this.api.notifier.show({message:this.api.i18n.t("Couldn’t upload image. Please try another."),style:"error"}),this.ui.hidePreloader()}tuneToggled(a,i){a==="caption"?(this.ui.applyTune(a,i),i==!1&&(this._data.caption="",this.ui.fillCaption(""))):this.setTune(a,i)}setTune(a,i){this._data[a]=i,this.ui.applyTune(a,i),a==="stretched"&&Promise.resolve().then(()=>{this.block.stretched=i}).catch(s=>{console.error(s)})}uploadFile(a){this.uploader.uploadByFile(a,{onPreview:i=>{this.ui.showPreloader(i)}})}uploadUrl(a){this.ui.showPreloader(a),this.uploader.uploadByUrl(a)}}return P});
diff --git a/httpdocs/themes/vuexy/js/editorjs/list.js b/httpdocs/themes/vuexy/js/editorjs/list.js
new file mode 100644
index 00000000..5b301395
--- /dev/null
+++ b/httpdocs/themes/vuexy/js/editorjs/list.js
@@ -0,0 +1,8 @@
+/**
+ * Skipped minification because the original files appears to be already minified.
+ * Original file: /npm/@editorjs/list@2.0.4/dist/editorjs-list.umd.js
+ *
+ * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
+ */
+(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode('.cdx-list{margin:0;padding:0;outline:none;display:grid;counter-reset:item;gap:var(--spacing-s);padding:var(--spacing-xs);--spacing-s: 8px;--spacing-xs: 6px;--list-counter-type: numeric;--radius-border: 5px;--checkbox-background: #fff;--color-border: #C9C9C9;--color-bg-checked: #369FFF;--line-height: 1.45em;--color-bg-checked-hover: #0059AB;--color-tick: #fff;--size-checkbox: 1.2em}.cdx-list__item{line-height:var(--line-height);display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;grid-template-areas:"checkbox content" ". child"}.cdx-list__item-children{display:grid;grid-area:child;gap:var(--spacing-s);padding-top:var(--spacing-s)}.cdx-list__item [contenteditable]{outline:none}.cdx-list__item-content{word-break:break-word;white-space:pre-wrap;grid-area:content;padding-left:var(--spacing-s)}.cdx-list__item:before{counter-increment:item;white-space:nowrap}.cdx-list-ordered .cdx-list__item:before{content:counters(item,".",var(--list-counter-type)) "."}.cdx-list-ordered{counter-reset:item}.cdx-list-unordered .cdx-list__item:before{content:"•"}.cdx-list-checklist .cdx-list__item:before{content:""}.cdx-list__settings .cdx-settings-button{width:50%}.cdx-list__checkbox{padding-top:calc((var(--line-height) - var(--size-checkbox)) / 2);grid-area:checkbox;width:var(--size-checkbox);height:var(--size-checkbox);display:flex;cursor:pointer}.cdx-list__checkbox svg{opacity:0;height:var(--size-checkbox);width:var(--size-checkbox);left:-1px;top:-1px;position:absolute}@media (hover: hover){.cdx-list__checkbox:not(.cdx-list__checkbox--no-hover):hover .cdx-list__checkbox-check svg{opacity:1}}.cdx-list__checkbox--checked{line-height:var(--line-height)}@media (hover: hover){.cdx-list__checkbox--checked:not(.cdx-list__checkbox--checked--no-hover):hover .cdx-checklist__checkbox-check{background:var(--color-bg-checked-hover);border-color:var(--color-bg-checked-hover)}}.cdx-list__checkbox--checked .cdx-list__checkbox-check{background:var(--color-bg-checked);border-color:var(--color-bg-checked)}.cdx-list__checkbox--checked .cdx-list__checkbox-check svg{opacity:1}.cdx-list__checkbox--checked .cdx-list__checkbox-check svg path{stroke:var(--color-tick)}.cdx-list__checkbox--checked .cdx-list__checkbox-check:before{opacity:0;visibility:visible;transform:scale(2.5)}.cdx-list__checkbox-check{cursor:pointer;display:inline-block;position:relative;margin:0 auto;width:var(--size-checkbox);height:var(--size-checkbox);box-sizing:border-box;border-radius:var(--radius-border);border:1px solid var(--color-border);background:var(--checkbox-background)}.cdx-list__checkbox-check:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:100%;background-color:var(--color-bg-checked);visibility:hidden;pointer-events:none;transform:scale(1);transition:transform .4s ease-out,opacity .4s}.cdx-list-start-with-field{background:#F8F8F8;border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:2px;display:grid;grid-template-columns:auto auto 1fr;grid-template-rows:auto}.cdx-list-start-with-field--invalid{background:#FFECED;border:1px solid #E13F3F}.cdx-list-start-with-field--invalid .cdx-list-start-with-field__input{color:#e13f3f}.cdx-list-start-with-field__input{font-size:14px;outline:none;font-weight:500;font-family:inherit;border:0;background:transparent;margin:0;padding:0;line-height:22px;min-width:calc(100% - var(--toolbox-buttons-size) - var(--icon-margin-right))}.cdx-list-start-with-field__input::placeholder{color:var(--grayText);font-weight:500}')),document.head.appendChild(e)}}catch(c){console.error("vite-plugin-css-injected-by-js",c)}})();
+(function(P,_){typeof exports=="object"&&typeof module<"u"?module.exports=_():typeof define=="function"&&define.amd?define(_):(P=typeof globalThis<"u"?globalThis:P||self,P.EditorjsList=_())})(this,function(){"use strict";const P='',_='',Be='',We='',ct='',dt='',ft='',pt='',mt='',ht='';var L=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function gt(e){if(e.__esModule)return e;var t=e.default;if(typeof t=="function"){var n=function r(){return this instanceof r?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(r){var i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(n,r,i.get?i:{enumerable:!0,get:function(){return e[r]}})}),n}var c={},X={},G={};Object.defineProperty(G,"__esModule",{value:!0}),G.allInputsSelector=vt;function vt(){var e=["text","password","email","number","search","tel","url"];return"[contenteditable=true], textarea, input:not([type]), "+e.map(function(t){return'input[type="'.concat(t,'"]')}).join(", ")}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.allInputsSelector=void 0;var t=G;Object.defineProperty(e,"allInputsSelector",{enumerable:!0,get:function(){return t.allInputsSelector}})})(X);var O={},V={};Object.defineProperty(V,"__esModule",{value:!0}),V.isNativeInput=bt;function bt(e){var t=["INPUT","TEXTAREA"];return e&&e.tagName?t.includes(e.tagName):!1}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.isNativeInput=void 0;var t=V;Object.defineProperty(e,"isNativeInput",{enumerable:!0,get:function(){return t.isNativeInput}})})(O);var De={},Y={};Object.defineProperty(Y,"__esModule",{value:!0}),Y.append=yt;function yt(e,t){Array.isArray(t)?t.forEach(function(n){e.appendChild(n)}):e.appendChild(t)}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.append=void 0;var t=Y;Object.defineProperty(e,"append",{enumerable:!0,get:function(){return t.append}})})(De);var J={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.blockElements=Ct;function Ct(){return["address","article","aside","blockquote","canvas","div","dl","dt","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","li","main","nav","noscript","ol","output","p","pre","ruby","section","table","tbody","thead","tr","tfoot","ul","video"]}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.blockElements=void 0;var t=Q;Object.defineProperty(e,"blockElements",{enumerable:!0,get:function(){return t.blockElements}})})(J);var He={},Z={};Object.defineProperty(Z,"__esModule",{value:!0}),Z.calculateBaseline=St;function St(e){var t=window.getComputedStyle(e),n=parseFloat(t.fontSize),r=parseFloat(t.lineHeight)||n*1.2,i=parseFloat(t.paddingTop),a=parseFloat(t.borderTopWidth),l=parseFloat(t.marginTop),s=n*.8,o=(r-n)/2,d=l+a+i+o+s;return d}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.calculateBaseline=void 0;var t=Z;Object.defineProperty(e,"calculateBaseline",{enumerable:!0,get:function(){return t.calculateBaseline}})})(He);var Fe={},x={},ee={},te={};Object.defineProperty(te,"__esModule",{value:!0}),te.isContentEditable=Ot;function Ot(e){return e.contentEditable==="true"}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.isContentEditable=void 0;var t=te;Object.defineProperty(e,"isContentEditable",{enumerable:!0,get:function(){return t.isContentEditable}})})(ee),Object.defineProperty(x,"__esModule",{value:!0}),x.canSetCaret=Et;var kt=O,_t=ee;function Et(e){var t=!0;if((0,kt.isNativeInput)(e))switch(e.type){case"file":case"checkbox":case"radio":case"hidden":case"submit":case"button":case"image":case"reset":t=!1;break}else t=(0,_t.isContentEditable)(e);return t}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.canSetCaret=void 0;var t=x;Object.defineProperty(e,"canSetCaret",{enumerable:!0,get:function(){return t.canSetCaret}})})(Fe);var M={},ne={};function It(e,t,n){const r=n.value!==void 0?"value":"get",i=n[r],a=`#${t}Cache`;if(n[r]=function(...l){return this[a]===void 0&&(this[a]=i.apply(this,l)),this[a]},r==="get"&&n.set){const l=n.set;n.set=function(s){delete e[a],l.apply(this,s)}}return n}function Re(){const e={win:!1,mac:!1,x11:!1,linux:!1},t=Object.keys(e).find(n=>window.navigator.appVersion.toLowerCase().indexOf(n)!==-1);return t!==void 0&&(e[t]=!0),e}function re(e){return e!=null&&e!==""&&(typeof e!="object"||Object.keys(e).length>0)}function wt(e){return!re(e)}const Pt=()=>typeof window<"u"&&window.navigator!==null&&re(window.navigator.platform)&&(/iP(ad|hone|od)/.test(window.navigator.platform)||window.navigator.platform==="MacIntel"&&window.navigator.maxTouchPoints>1);function jt(e){const t=Re();return e=e.replace(/shift/gi,"⇧").replace(/backspace/gi,"⌫").replace(/enter/gi,"⏎").replace(/up/gi,"↑").replace(/left/gi,"→").replace(/down/gi,"↓").replace(/right/gi,"←").replace(/escape/gi,"⎋").replace(/insert/gi,"Ins").replace(/delete/gi,"␡").replace(/\+/gi,"+"),t.mac?e=e.replace(/ctrl|cmd/gi,"⌘").replace(/alt/gi,"⌥"):e=e.replace(/cmd/gi,"Ctrl").replace(/windows/gi,"WIN"),e}function Tt(e){return e[0].toUpperCase()+e.slice(1)}function Lt(e){const t=document.createElement("div");t.style.position="absolute",t.style.left="-999px",t.style.bottom="-999px",t.innerHTML=e,document.body.appendChild(t);const n=window.getSelection(),r=document.createRange();if(r.selectNode(t),n===null)throw new Error("Cannot copy text to clipboard");n.removeAllRanges(),n.addRange(r),document.execCommand("copy"),document.body.removeChild(t)}function Mt(e,t,n){let r;return(...i)=>{const a=this,l=()=>{r=void 0,n!==!0&&e.apply(a,i)},s=n===!0&&r!==void 0;window.clearTimeout(r),r=window.setTimeout(l,t),s&&e.apply(a,i)}}function C(e){return Object.prototype.toString.call(e).match(/\s([a-zA-Z]+)/)[1].toLowerCase()}function Nt(e){return C(e)==="boolean"}function qe(e){return C(e)==="function"||C(e)==="asyncfunction"}function At(e){return qe(e)&&/^\s*class\s+/.test(e.toString())}function $t(e){return C(e)==="number"}function N(e){return C(e)==="object"}function Bt(e){return Promise.resolve(e)===e}function Wt(e){return C(e)==="string"}function Dt(e){return C(e)==="undefined"}function ie(e,...t){if(!t.length)return e;const n=t.shift();if(N(e)&&N(n))for(const r in n)N(n[r])?(e[r]===void 0&&Object.assign(e,{[r]:{}}),ie(e[r],n[r])):Object.assign(e,{[r]:n[r]});return ie(e,...t)}function Ht(e,t,n){const r=`«${t}» is deprecated and will be removed in the next major release. Please use the «${n}» instead.`;e&&console.warn(r)}function Ft(e){try{return new URL(e).href}catch{}return e.substring(0,2)==="//"?window.location.protocol+e:window.location.origin+e}function Rt(e){return e>47&&e<58||e===32||e===13||e===229||e>64&&e<91||e>95&&e<112||e>185&&e<193||e>218&&e<223}const qt={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,LEFT:37,UP:38,DOWN:40,RIGHT:39,DELETE:46,META:91,SLASH:191},Ut={LEFT:0,WHEEL:1,RIGHT:2,BACKWARD:3,FORWARD:4};class zt{constructor(){this.completed=Promise.resolve()}add(t){return new Promise((n,r)=>{this.completed=this.completed.then(t).then(n).catch(r)})}}function Kt(e,t,n=void 0){let r,i,a,l=null,s=0;n||(n={});const o=function(){s=n.leading===!1?0:Date.now(),l=null,a=e.apply(r,i),l===null&&(r=i=null)};return function(){const d=Date.now();!s&&n.leading===!1&&(s=d);const u=t-(d-s);return r=this,i=arguments,u<=0||u>t?(l&&(clearTimeout(l),l=null),s=d,a=e.apply(r,i),l===null&&(r=i=null)):!l&&n.trailing!==!1&&(l=setTimeout(o,u)),a}}const ae=gt(Object.freeze(Object.defineProperty({__proto__:null,PromiseQueue:zt,beautifyShortcut:jt,cacheable:It,capitalize:Tt,copyTextToClipboard:Lt,debounce:Mt,deepMerge:ie,deprecationAssert:Ht,getUserOS:Re,getValidUrl:Ft,isBoolean:Nt,isClass:At,isEmpty:wt,isFunction:qe,isIosDevice:Pt,isNumber:$t,isObject:N,isPrintableKey:Rt,isPromise:Bt,isString:Wt,isUndefined:Dt,keyCodes:qt,mouseButtons:Ut,notEmpty:re,throttle:Kt,typeOf:C},Symbol.toStringTag,{value:"Module"})));Object.defineProperty(ne,"__esModule",{value:!0}),ne.containsOnlyInlineElements=Vt;var Xt=ae,Gt=J;function Vt(e){var t;(0,Xt.isString)(e)?(t=document.createElement("div"),t.innerHTML=e):t=e;var n=function(r){return!(0,Gt.blockElements)().includes(r.tagName.toLowerCase())&&Array.from(r.children).every(n)};return Array.from(t.children).every(n)}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.containsOnlyInlineElements=void 0;var t=ne;Object.defineProperty(e,"containsOnlyInlineElements",{enumerable:!0,get:function(){return t.containsOnlyInlineElements}})})(M);var Ue={},le={},A={},se={};Object.defineProperty(se,"__esModule",{value:!0}),se.make=Yt;function Yt(e,t,n){var r;t===void 0&&(t=null),n===void 0&&(n={});var i=document.createElement(e);if(Array.isArray(t)){var a=t.filter(function(s){return s!==void 0});(r=i.classList).add.apply(r,a)}else t!==null&&i.classList.add(t);for(var l in n)Object.prototype.hasOwnProperty.call(n,l)&&(i[l]=n[l]);return i}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.make=void 0;var t=se;Object.defineProperty(e,"make",{enumerable:!0,get:function(){return t.make}})})(A),Object.defineProperty(le,"__esModule",{value:!0}),le.fragmentToString=Qt;var Jt=A;function Qt(e){var t=(0,Jt.make)("div");return t.appendChild(e),t.innerHTML}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.fragmentToString=void 0;var t=le;Object.defineProperty(e,"fragmentToString",{enumerable:!0,get:function(){return t.fragmentToString}})})(Ue);var ze={},oe={};Object.defineProperty(oe,"__esModule",{value:!0}),oe.getContentLength=xt;var Zt=O;function xt(e){var t,n;return(0,Zt.isNativeInput)(e)?e.value.length:e.nodeType===Node.TEXT_NODE?e.length:(n=(t=e.textContent)===null||t===void 0?void 0:t.length)!==null&&n!==void 0?n:0}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.getContentLength=void 0;var t=oe;Object.defineProperty(e,"getContentLength",{enumerable:!0,get:function(){return t.getContentLength}})})(ze);var ue={},ce={},Ke=L&&L.__spreadArray||function(e,t,n){if(n||arguments.length===2)for(var r=0,i=t.length,a;r0;){var r=n.shift();if(r){if(e=r,(0,Sn.isLeaf)(e)&&!(0,On.isNodeEmpty)(e,t))return!1;n.push.apply(n,Array.from(e.childNodes))}}return!0}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.isEmpty=void 0;var t=be;Object.defineProperty(e,"isEmpty",{enumerable:!0,get:function(){return t.isEmpty}})})(Qe);var Ze={},ke={};Object.defineProperty(ke,"__esModule",{value:!0}),ke.isFragment=En;var _n=ae;function En(e){return(0,_n.isNumber)(e)?!1:!!e&&!!e.nodeType&&e.nodeType===Node.DOCUMENT_FRAGMENT_NODE}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.isFragment=void 0;var t=ke;Object.defineProperty(e,"isFragment",{enumerable:!0,get:function(){return t.isFragment}})})(Ze);var xe={},_e={};Object.defineProperty(_e,"__esModule",{value:!0}),_e.isHTMLString=wn;var In=A;function wn(e){var t=(0,In.make)("div");return t.innerHTML=e,t.childElementCount>0}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.isHTMLString=void 0;var t=_e;Object.defineProperty(e,"isHTMLString",{enumerable:!0,get:function(){return t.isHTMLString}})})(xe);var et={},Ee={};Object.defineProperty(Ee,"__esModule",{value:!0}),Ee.offset=Pn;function Pn(e){var t=e.getBoundingClientRect(),n=window.pageXOffset||document.documentElement.scrollLeft,r=window.pageYOffset||document.documentElement.scrollTop,i=t.top+r,a=t.left+n;return{top:i,left:a,bottom:i+t.height,right:a+t.width}}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.offset=void 0;var t=Ee;Object.defineProperty(e,"offset",{enumerable:!0,get:function(){return t.offset}})})(et);var tt={},Ie={};Object.defineProperty(Ie,"__esModule",{value:!0}),Ie.prepend=jn;function jn(e,t){Array.isArray(t)?(t=t.reverse(),t.forEach(function(n){return e.prepend(n)})):e.prepend(t)}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.prepend=void 0;var t=Ie;Object.defineProperty(e,"prepend",{enumerable:!0,get:function(){return t.prepend}})})(tt),function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.prepend=e.offset=e.make=e.isLineBreakTag=e.isSingleTag=e.isNodeEmpty=e.isLeaf=e.isHTMLString=e.isFragment=e.isEmpty=e.isElement=e.isContentEditable=e.isCollapsedWhitespaces=e.findAllInputs=e.isNativeInput=e.allInputsSelector=e.getDeepestNode=e.getDeepestBlockElements=e.getContentLength=e.fragmentToString=e.containsOnlyInlineElements=e.canSetCaret=e.calculateBaseline=e.blockElements=e.append=void 0;var t=X;Object.defineProperty(e,"allInputsSelector",{enumerable:!0,get:function(){return t.allInputsSelector}});var n=O;Object.defineProperty(e,"isNativeInput",{enumerable:!0,get:function(){return n.isNativeInput}});var r=De;Object.defineProperty(e,"append",{enumerable:!0,get:function(){return r.append}});var i=J;Object.defineProperty(e,"blockElements",{enumerable:!0,get:function(){return i.blockElements}});var a=He;Object.defineProperty(e,"calculateBaseline",{enumerable:!0,get:function(){return a.calculateBaseline}});var l=Fe;Object.defineProperty(e,"canSetCaret",{enumerable:!0,get:function(){return l.canSetCaret}});var s=M;Object.defineProperty(e,"containsOnlyInlineElements",{enumerable:!0,get:function(){return s.containsOnlyInlineElements}});var o=Ue;Object.defineProperty(e,"fragmentToString",{enumerable:!0,get:function(){return o.fragmentToString}});var d=ze;Object.defineProperty(e,"getContentLength",{enumerable:!0,get:function(){return d.getContentLength}});var u=ue;Object.defineProperty(e,"getDeepestBlockElements",{enumerable:!0,get:function(){return u.getDeepestBlockElements}});var m=Ge;Object.defineProperty(e,"getDeepestNode",{enumerable:!0,get:function(){return m.getDeepestNode}});var g=Ye;Object.defineProperty(e,"findAllInputs",{enumerable:!0,get:function(){return g.findAllInputs}});var T=Je;Object.defineProperty(e,"isCollapsedWhitespaces",{enumerable:!0,get:function(){return T.isCollapsedWhitespaces}});var w=ee;Object.defineProperty(e,"isContentEditable",{enumerable:!0,get:function(){return w.isContentEditable}});var nr=ge;Object.defineProperty(e,"isElement",{enumerable:!0,get:function(){return nr.isElement}});var rr=Qe;Object.defineProperty(e,"isEmpty",{enumerable:!0,get:function(){return rr.isEmpty}});var ir=Ze;Object.defineProperty(e,"isFragment",{enumerable:!0,get:function(){return ir.isFragment}});var ar=xe;Object.defineProperty(e,"isHTMLString",{enumerable:!0,get:function(){return ar.isHTMLString}});var lr=ye;Object.defineProperty(e,"isLeaf",{enumerable:!0,get:function(){return lr.isLeaf}});var sr=Se;Object.defineProperty(e,"isNodeEmpty",{enumerable:!0,get:function(){return sr.isNodeEmpty}});var or=$;Object.defineProperty(e,"isLineBreakTag",{enumerable:!0,get:function(){return or.isLineBreakTag}});var ur=B;Object.defineProperty(e,"isSingleTag",{enumerable:!0,get:function(){return ur.isSingleTag}});var cr=A;Object.defineProperty(e,"make",{enumerable:!0,get:function(){return cr.make}});var dr=et;Object.defineProperty(e,"offset",{enumerable:!0,get:function(){return dr.offset}});var fr=tt;Object.defineProperty(e,"prepend",{enumerable:!0,get:function(){return fr.prepend}})}(c);const h="cdx-list",p={wrapper:h,item:`${h}__item`,itemContent:`${h}__item-content`,itemChildren:`${h}__item-children`};class v{static get CSS(){return{...p,orderedList:`${h}-ordered`}}constructor(t,n){this.config=n,this.readOnly=t}renderWrapper(t){let n;return t===!0?n=c.make("ol",[v.CSS.wrapper,v.CSS.orderedList]):n=c.make("ol",[v.CSS.orderedList,v.CSS.itemChildren]),n}renderItem(t,n){const r=c.make("li",v.CSS.item),i=c.make("div",v.CSS.itemContent,{innerHTML:t,contentEditable:(!this.readOnly).toString()});return r.appendChild(i),r}getItemContent(t){const n=t.querySelector(`.${v.CSS.itemContent}`);return!n||c.isEmpty(n)?"":n.innerHTML}getItemMeta(){return{}}composeDefaultMeta(){return{}}}class b{static get CSS(){return{...p,unorderedList:`${h}-unordered`}}constructor(t,n){this.config=n,this.readOnly=t}renderWrapper(t){let n;return t===!0?n=c.make("ul",[b.CSS.wrapper,b.CSS.unorderedList]):n=c.make("ul",[b.CSS.unorderedList,b.CSS.itemChildren]),n}renderItem(t,n){const r=c.make("li",b.CSS.item),i=c.make("div",b.CSS.itemContent,{innerHTML:t,contentEditable:(!this.readOnly).toString()});return r.appendChild(i),r}getItemContent(t){const n=t.querySelector(`.${b.CSS.itemContent}`);return!n||c.isEmpty(n)?"":n.innerHTML}getItemMeta(){return{}}composeDefaultMeta(){return{}}}function k(e){return e.nodeType===Node.ELEMENT_NODE}var j={},we={},D={},H={};Object.defineProperty(H,"__esModule",{value:!0}),H.getContenteditableSlice=Ln;var Tn=c;function Ln(e,t,n,r,i){var a;i===void 0&&(i=!1);var l=document.createRange();if(r==="left"?(l.setStart(e,0),l.setEnd(t,n)):(l.setStart(t,n),l.setEnd(e,e.childNodes.length)),i===!0){var s=l.extractContents();return(0,Tn.fragmentToString)(s)}var o=l.cloneContents(),d=document.createElement("div");d.appendChild(o);var u=(a=d.textContent)!==null&&a!==void 0?a:"";return u}Object.defineProperty(D,"__esModule",{value:!0}),D.checkContenteditableSliceForEmptiness=An;var Mn=c,Nn=H;function An(e,t,n,r){var i=(0,Nn.getContenteditableSlice)(e,t,n,r);return(0,Mn.isCollapsedWhitespaces)(i)}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.checkContenteditableSliceForEmptiness=void 0;var t=D;Object.defineProperty(e,"checkContenteditableSliceForEmptiness",{enumerable:!0,get:function(){return t.checkContenteditableSliceForEmptiness}})})(we);var nt={};(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.getContenteditableSlice=void 0;var t=H;Object.defineProperty(e,"getContenteditableSlice",{enumerable:!0,get:function(){return t.getContenteditableSlice}})})(nt);var rt={},Pe={};Object.defineProperty(Pe,"__esModule",{value:!0}),Pe.focus=Bn;var $n=c;function Bn(e,t){var n,r;if(t===void 0&&(t=!0),(0,$n.isNativeInput)(e)){e.focus();var i=t?0:e.value.length;e.setSelectionRange(i,i)}else{var a=document.createRange(),l=window.getSelection();if(!l)return;var s=function(g,T){T===void 0&&(T=!1);var w=document.createTextNode("");T?g.insertBefore(w,g.firstChild):g.appendChild(w),a.setStart(w,0),a.setEnd(w,0)},o=function(g){return g!=null},d=e.childNodes,u=t?d[0]:d[d.length-1];if(o(u)){for(;o(u)&&u.nodeType!==Node.TEXT_NODE;)u=t?u.firstChild:u.lastChild;if(o(u)&&u.nodeType===Node.TEXT_NODE){var m=(r=(n=u.textContent)===null||n===void 0?void 0:n.length)!==null&&r!==void 0?r:0,i=t?0:m;a.setStart(u,i),a.setEnd(u,i)}else s(e,t)}else s(e);l.removeAllRanges(),l.addRange(a)}}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.focus=void 0;var t=Pe;Object.defineProperty(e,"focus",{enumerable:!0,get:function(){return t.focus}})})(rt);var je={},F={};Object.defineProperty(F,"__esModule",{value:!0}),F.getCaretNodeAndOffset=Wn;function Wn(){var e=window.getSelection();if(e===null)return[null,0];var t=e.focusNode,n=e.focusOffset;return t===null?[null,0]:(t.nodeType!==Node.TEXT_NODE&&t.childNodes.length>0&&(t.childNodes[n]!==void 0?(t=t.childNodes[n],n=0):(t=t.childNodes[n-1],t.textContent!==null&&(n=t.textContent.length))),[t,n])}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.getCaretNodeAndOffset=void 0;var t=F;Object.defineProperty(e,"getCaretNodeAndOffset",{enumerable:!0,get:function(){return t.getCaretNodeAndOffset}})})(je);var it={},R={};Object.defineProperty(R,"__esModule",{value:!0}),R.getRange=Dn;function Dn(){var e=window.getSelection();return e&&e.rangeCount?e.getRangeAt(0):null}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.getRange=void 0;var t=R;Object.defineProperty(e,"getRange",{enumerable:!0,get:function(){return t.getRange}})})(it);var at={},Te={};Object.defineProperty(Te,"__esModule",{value:!0}),Te.isCaretAtEndOfInput=Rn;var lt=c,Hn=je,Fn=we;function Rn(e){var t=(0,lt.getDeepestNode)(e,!0);if(t===null)return!0;if((0,lt.isNativeInput)(t))return t.selectionEnd===t.value.length;var n=(0,Hn.getCaretNodeAndOffset)(),r=n[0],i=n[1];return r===null?!1:(0,Fn.checkContenteditableSliceForEmptiness)(e,r,i,"right")}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.isCaretAtEndOfInput=void 0;var t=Te;Object.defineProperty(e,"isCaretAtEndOfInput",{enumerable:!0,get:function(){return t.isCaretAtEndOfInput}})})(at);var st={},Le={};Object.defineProperty(Le,"__esModule",{value:!0}),Le.isCaretAtStartOfInput=zn;var q=c,qn=F,Un=D;function zn(e){var t=(0,q.getDeepestNode)(e);if(t===null||(0,q.isEmpty)(e))return!0;if((0,q.isNativeInput)(t))return t.selectionEnd===0;if((0,q.isEmpty)(e))return!0;var n=(0,qn.getCaretNodeAndOffset)(),r=n[0],i=n[1];return r===null?!1:(0,Un.checkContenteditableSliceForEmptiness)(e,r,i,"left")}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.isCaretAtStartOfInput=void 0;var t=Le;Object.defineProperty(e,"isCaretAtStartOfInput",{enumerable:!0,get:function(){return t.isCaretAtStartOfInput}})})(st);var ot={},Me={};Object.defineProperty(Me,"__esModule",{value:!0}),Me.save=Gn;var Kn=c,Xn=R;function Gn(){var e=(0,Xn.getRange)(),t=(0,Kn.make)("span");if(t.id="cursor",t.hidden=!0,!!e)return e.insertNode(t),function(){var r=window.getSelection();r&&(e.setStartAfter(t),e.setEndAfter(t),r.removeAllRanges(),r.addRange(e),setTimeout(function(){t.remove()},150))}}(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.save=void 0;var t=Me;Object.defineProperty(e,"save",{enumerable:!0,get:function(){return t.save}})})(ot),function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.save=e.isCaretAtStartOfInput=e.isCaretAtEndOfInput=e.getRange=e.getCaretNodeAndOffset=e.focus=e.getContenteditableSlice=e.checkContenteditableSliceForEmptiness=void 0;var t=we;Object.defineProperty(e,"checkContenteditableSliceForEmptiness",{enumerable:!0,get:function(){return t.checkContenteditableSliceForEmptiness}});var n=nt;Object.defineProperty(e,"getContenteditableSlice",{enumerable:!0,get:function(){return n.getContenteditableSlice}});var r=rt;Object.defineProperty(e,"focus",{enumerable:!0,get:function(){return r.focus}});var i=je;Object.defineProperty(e,"getCaretNodeAndOffset",{enumerable:!0,get:function(){return i.getCaretNodeAndOffset}});var a=it;Object.defineProperty(e,"getRange",{enumerable:!0,get:function(){return a.getRange}});var l=at;Object.defineProperty(e,"isCaretAtEndOfInput",{enumerable:!0,get:function(){return l.isCaretAtEndOfInput}});var s=st;Object.defineProperty(e,"isCaretAtStartOfInput",{enumerable:!0,get:function(){return s.isCaretAtStartOfInput}});var o=ot;Object.defineProperty(e,"save",{enumerable:!0,get:function(){return o.save}})}(j);class f{static get CSS(){return{...p,checklist:`${h}-checklist`,itemChecked:`${h}__checkbox--checked`,noHover:`${h}__checkbox--no-hover`,checkbox:`${h}__checkbox-check`,checkboxContainer:`${h}__checkbox`}}constructor(t,n){this.config=n,this.readOnly=t}renderWrapper(t){let n;return t===!0?(n=c.make("ul",[f.CSS.wrapper,f.CSS.checklist]),n.addEventListener("click",r=>{const i=r.target;if(i){const a=i.closest(`.${f.CSS.checkboxContainer}`);a&&a.contains(i)&&this.toggleCheckbox(a)}})):n=c.make("ul",[f.CSS.checklist,f.CSS.itemChildren]),n}renderItem(t,n){const r=c.make("li",[f.CSS.item,f.CSS.item]),i=c.make("div",f.CSS.itemContent,{innerHTML:t,contentEditable:(!this.readOnly).toString()}),a=c.make("span",f.CSS.checkbox),l=c.make("div",f.CSS.checkboxContainer);return n.checked===!0&&l.classList.add(f.CSS.itemChecked),a.innerHTML=P,l.appendChild(a),r.appendChild(l),r.appendChild(i),r}getItemContent(t){const n=t.querySelector(`.${f.CSS.itemContent}`);return!n||c.isEmpty(n)?"":n.innerHTML}getItemMeta(t){const n=t.querySelector(`.${f.CSS.checkboxContainer}`);return{checked:n?n.classList.contains(f.CSS.itemChecked):!1}}composeDefaultMeta(){return{checked:!1}}toggleCheckbox(t){t.classList.toggle(f.CSS.itemChecked),t.classList.add(f.CSS.noHover),t.addEventListener("mouseleave",()=>this.removeSpecialHoverBehavior(t),{once:!0})}removeSpecialHoverBehavior(t){t.classList.remove(f.CSS.noHover)}}function Ne(e,t="after"){const n=[];let r;function i(a){switch(t){case"after":return a.nextElementSibling;case"before":return a.previousElementSibling}}for(r=i(e);r!==null;)n.push(r),r=i(r);return n.length!==0?n:null}function y(e,t=!0){let n=e;return e.classList.contains(p.item)&&(n=e.querySelector(`.${p.itemChildren}`)),n===null?[]:t?Array.from(n.querySelectorAll(`:scope > .${p.item}`)):Array.from(n.querySelectorAll(`.${p.item}`))}function Vn(e){return e.nextElementSibling===null}function Yn(e){return e.querySelector(`.${p.itemChildren}`)!==null}function S(e){return e.querySelector(`.${p.itemChildren}`)}function Ae(e){let t=e;e.classList.contains(p.item)&&(t=S(e)),t!==null&&y(t).length===0&&t.remove()}function U(e){return e.querySelector(`.${p.itemContent}`)}function E(e,t=!0){const n=U(e);n&&j.focus(n,t)}class $e{get currentItem(){const t=window.getSelection();if(!t)return null;let n=t.anchorNode;return!n||(k(n)||(n=n.parentNode),!n)||!k(n)?null:n.closest(`.${p.item}`)}get currentItemLevel(){const t=this.currentItem;if(t===null)return null;let n=t.parentNode,r=0;for(;n!==null&&n!==this.listWrapper;)k(n)&&n.classList.contains(p.item)&&(r+=1),n=n.parentNode;return r+1}constructor({data:t,config:n,api:r,readOnly:i,block:a},l){this.config=n,this.data=t,this.readOnly=i,this.api=r,this.block=a,this.renderer=l}render(){return this.listWrapper=this.renderer.renderWrapper(!0),this.data.items.length?this.appendItems(this.data.items,this.listWrapper):this.appendItems([{content:"",meta:{},items:[]}],this.listWrapper),this.readOnly||this.listWrapper.addEventListener("keydown",t=>{switch(t.key){case"Enter":this.enterPressed(t);break;case"Backspace":this.backspace(t);break;case"Tab":t.shiftKey?this.shiftTab(t):this.addTab(t);break}},!1),"start"in this.data.meta&&this.data.meta.start!==void 0&&this.changeStartWith(this.data.meta.start),"counterType"in this.data.meta&&this.data.meta.counterType!==void 0&&this.changeCounters(this.data.meta.counterType),this.listWrapper}save(t){const n=t??this.listWrapper,r=l=>y(l).map(o=>{const d=S(o),u=this.renderer.getItemContent(o),m=this.renderer.getItemMeta(o),g=d?r(d):[];return{content:u,meta:m,items:g}}),i=n?r(n):[];let a={style:this.data.style,meta:{},items:i};return this.data.style==="ordered"&&(a.meta={start:this.data.meta.start,counterType:this.data.meta.counterType}),a}static get pasteConfig(){return{tags:["OL","UL","LI"]}}merge(t){const n=this.block.holder.querySelectorAll(`.${p.item}`),r=n[n.length-1],i=U(r);if(r===null||i===null||(i.insertAdjacentHTML("beforeend",t.items[0].content),this.listWrapper===void 0))return;const a=y(this.listWrapper);if(a.length===0)return;const l=a[a.length-1];let s=S(l);const o=t.items.shift();o!==void 0&&(o.items.length!==0&&(s===null&&(s=this.renderer.renderWrapper(!1)),this.appendItems(o.items,s)),t.items.length>0&&this.appendItems(t.items,this.listWrapper))}onPaste(t){const n=t.detail.data;this.data=this.pasteHandler(n);const r=this.listWrapper;r&&r.parentNode&&r.parentNode.replaceChild(this.render(),r)}pasteHandler(t){const{tagName:n}=t;let r="unordered",i;switch(n){case"OL":r="ordered",i="ol";break;case"UL":case"LI":r="unordered",i="ul"}const a={style:r,meta:{},items:[]};r==="ordered"&&(this.data.meta.counterType="numeric",this.data.meta.start=1);const l=s=>Array.from(s.querySelectorAll(":scope > li")).map(d=>{const u=d.querySelector(`:scope > ${i}`),m=u?l(u):[];return{content:d.innerHTML??"",meta:{},items:m}});return a.items=l(t),a}changeStartWith(t){this.listWrapper.style.setProperty("counter-reset",`item ${t-1}`),this.data.meta.start=t}changeCounters(t){this.listWrapper.style.setProperty("--list-counter-type",t),this.data.meta.counterType=t}enterPressed(t){var s;const n=this.currentItem;if(t.stopPropagation(),t.preventDefault(),t.isComposing||n===null)return;const r=((s=this.renderer)==null?void 0:s.getItemContent(n).trim().length)===0,i=n.parentNode===this.listWrapper,a=n.previousElementSibling===null,l=this.api.blocks.getCurrentBlockIndex();if(i&&r)if(Vn(n)&&!Yn(n)){a?this.convertItemToDefaultBlock(l,!0):this.convertItemToDefaultBlock();return}else{this.splitList(n);return}else if(r){this.unshiftItem(n);return}else this.splitItem(n)}backspace(t){var r;const n=this.currentItem;if(n!==null&&j.isCaretAtStartOfInput(n)&&((r=window.getSelection())==null?void 0:r.isCollapsed)!==!1){if(t.stopPropagation(),n.parentNode===this.listWrapper&&n.previousElementSibling===null){this.convertFirstItemToDefaultBlock();return}t.preventDefault(),this.mergeItemWithPrevious(n)}}shiftTab(t){t.stopPropagation(),t.preventDefault(),this.currentItem!==null&&this.unshiftItem(this.currentItem)}unshiftItem(t){if(!t.parentNode||!k(t.parentNode))return;const n=t.parentNode.closest(`.${p.item}`);if(!n)return;let r=S(t);if(t.parentElement===null)return;const i=Ne(t);i!==null&&(r===null&&(r=this.renderer.renderWrapper(!1)),i.forEach(a=>{r.appendChild(a)}),t.appendChild(r)),n.after(t),E(t,!1),Ae(n)}splitList(t){const n=y(t),r=this.block,i=this.api.blocks.getCurrentBlockIndex();if(n.length!==0){const o=n[0];this.unshiftItem(o),E(t,!1)}if(t.previousElementSibling===null&&t.parentNode===this.listWrapper){this.convertItemToDefaultBlock(i);return}const a=Ne(t);if(a===null)return;const l=this.renderer.renderWrapper(!0);a.forEach(o=>{l.appendChild(o)});const s=this.save(l);s.meta.start=this.data.style=="ordered"?1:void 0,this.api.blocks.insert(r==null?void 0:r.name,s,this.config,i+1),this.convertItemToDefaultBlock(i+1),l.remove()}splitItem(t){const[n,r]=j.getCaretNodeAndOffset();if(n===null)return;const i=U(t);let a;i===null?a="":a=j.getContenteditableSlice(i,n,r,"right",!0);const l=S(t),s=this.renderItem(a);t==null||t.after(s),l&&s.appendChild(l),E(s)}mergeItemWithPrevious(t){const n=t.previousElementSibling,r=t.parentNode;if(r===null||!k(r))return;const i=r.closest(`.${p.item}`);if(!n&&!i||n&&!k(n))return;let a;if(n){const m=y(n,!1);m.length!==0&&m.length!==0?a=m[m.length-1]:a=n}else a=i;const l=this.renderer.getItemContent(t);if(!a)return;E(a,!1);const s=U(a);if(s===null)return;s.insertAdjacentHTML("beforeend",l);const o=y(t);if(o.length===0){t.remove(),Ae(a);return}const d=n||i,u=S(d)??this.renderer.renderWrapper(!1);n?o.forEach(m=>{u.appendChild(m)}):o.forEach(m=>{u.prepend(m)}),S(d)===null&&a.appendChild(u),t.remove()}addTab(t){var a;t.stopPropagation(),t.preventDefault();const n=this.currentItem;if(!n)return;if(((a=this.config)==null?void 0:a.maxLevel)!==void 0){const l=this.currentItemLevel;if(l!==null&&l===this.config.maxLevel)return}const r=n.previousSibling;if(r===null||!k(r))return;const i=S(r);if(i)i.appendChild(n),y(n).forEach(s=>{i.appendChild(s)});else{const l=this.renderer.renderWrapper(!1);l.appendChild(n),y(n).forEach(o=>{l.appendChild(o)}),r.appendChild(l)}Ae(n),E(n,!1)}convertItemToDefaultBlock(t,n){let r;const i=this.currentItem,a=i!==null?this.renderer.getItemContent(i):"";n===!0&&this.api.blocks.delete(),t!==void 0?r=this.api.blocks.insert(void 0,{text:a},void 0,t):r=this.api.blocks.insert(),i==null||i.remove(),this.api.caret.setToBlock(r,"start")}convertFirstItemToDefaultBlock(){const t=this.currentItem;if(t===null)return;const n=y(t);if(n.length!==0){const l=n[0];this.unshiftItem(l),E(t)}const r=Ne(t),i=this.api.blocks.getCurrentBlockIndex(),a=r===null;this.convertItemToDefaultBlock(i,a)}renderItem(t,n){const r=n??this.renderer.composeDefaultMeta();switch(!0){case this.renderer instanceof v:return this.renderer.renderItem(t,r);case this.renderer instanceof b:return this.renderer.renderItem(t,r);default:return this.renderer.renderItem(t,r)}}appendItems(t,n){t.forEach(r=>{var a;const i=this.renderItem(r.content,r.meta);if(n.appendChild(i),r.items.length){const l=(a=this.renderer)==null?void 0:a.renderWrapper(!1);this.appendItems(r.items,l),i.appendChild(l)}})}}const I={wrapper:`${h}-start-with-field`,input:`${h}-start-with-field__input`,startWithElementWrapperInvalid:`${h}-start-with-field--invalid`};function Jn(e,{value:t,placeholder:n,attributes:r,sanitize:i}){const a=c.make("div",I.wrapper),l=c.make("input",I.input,{placeholder:n,tabIndex:-1,value:t});for(const s in r)l.setAttribute(s,r[s]);return a.appendChild(l),l.addEventListener("input",()=>{i!==void 0&&(l.value=i(l.value));const s=l.checkValidity();!s&&!a.classList.contains(I.startWithElementWrapperInvalid)&&a.classList.add(I.startWithElementWrapperInvalid),s&&a.classList.contains(I.startWithElementWrapperInvalid)&&a.classList.remove(I.startWithElementWrapperInvalid),s&&e(l.value)}),a}const z=new Map([["Numeric","numeric"],["Lower Roman","lower-roman"],["Upper Roman","upper-roman"],["Lower Alpha","lower-alpha"],["Upper Alpha","upper-alpha"]]),ut=new Map([["numeric",ct],["lower-roman",dt],["upper-roman",ft],["lower-alpha",mt],["upper-alpha",pt]]),mr="",hr="";function Qn(e){return e.replace(/\D+/g,"")}function Zn(e){return typeof e.items[0]=="string"}function xn(e){return!("meta"in e)}function er(e){return typeof e.items[0]!="string"&&"text"in e.items[0]&&"checked"in e.items[0]&&typeof e.items[0].text=="string"&&typeof e.items[0].checked=="boolean"}function tr(e){const t=[];return Zn(e)?(e.items.forEach(n=>{t.push({content:n,meta:{},items:[]})}),{style:e.style,meta:{},items:t}):er(e)?(e.items.forEach(n=>{t.push({content:n.text,meta:{checked:n.checked},items:[]})}),{style:"checklist",meta:{},items:t}):xn(e)?{style:e.style,meta:{},items:e.items}:e}class K{static get isReadOnlySupported(){return!0}static get enableLineBreaks(){return!0}static get toolbox(){return[{icon:Be,title:"Unordered List",data:{style:"unordered"}},{icon:We,title:"Ordered List",data:{style:"ordered"}},{icon:_,title:"Checklist",data:{style:"checklist"}}]}static get pasteConfig(){return{tags:["OL","UL","LI"]}}static get conversionConfig(){return{export:t=>K.joinRecursive(t),import:(t,n)=>({meta:{},items:[{content:t,meta:{},items:[]}],style:(n==null?void 0:n.defaultStyle)!==void 0?n.defaultStyle:"unordered"})}}get listStyle(){return this.data.style||this.defaultListStyle}set listStyle(t){var r;this.data.style=t,this.changeTabulatorByStyle();const n=this.list.render();(r=this.listElement)==null||r.replaceWith(n),this.listElement=n}constructor({data:t,config:n,api:r,readOnly:i,block:a}){var s;this.api=r,this.readOnly=i,this.config=n,this.block=a,this.defaultListStyle=((s=this.config)==null?void 0:s.defaultStyle)||"unordered";const l={style:this.defaultListStyle,meta:{},items:[]};this.data=Object.keys(t).length?tr(t):l,this.listStyle==="ordered"&&this.data.meta.counterType===void 0&&(this.data.meta.counterType="numeric"),this.changeTabulatorByStyle()}static joinRecursive(t){return t.items.map(n=>`${n.content} ${K.joinRecursive(n)}`).join("")}render(){return this.listElement=this.list.render(),this.listElement}save(){return this.data=this.list.save(),this.data}merge(t){this.list.merge(t)}renderSettings(){const t=[{label:this.api.i18n.t("Unordered"),icon:Be,closeOnActivate:!0,isActive:this.listStyle=="unordered",onActivate:()=>{this.listStyle="unordered"}},{label:this.api.i18n.t("Ordered"),icon:We,closeOnActivate:!0,isActive:this.listStyle=="ordered",onActivate:()=>{this.listStyle="ordered"}},{label:this.api.i18n.t("Checklist"),icon:_,closeOnActivate:!0,isActive:this.listStyle=="checklist",onActivate:()=>{this.listStyle="checklist"}}];if(this.listStyle==="ordered"){const n=Jn(a=>this.changeStartWith(Number(a)),{value:String(this.data.meta.start??1),placeholder:"",attributes:{required:"true"},sanitize:a=>Qn(a)}),r=[{label:this.api.i18n.t("Start with"),icon:ht,children:{items:[{element:n,type:"html"}]}}],i={label:this.api.i18n.t("Counter type"),icon:ut.get(this.data.meta.counterType),children:{items:[]}};z.forEach((a,l)=>{i.children.items.push({title:this.api.i18n.t(l),icon:ut.get(z.get(l)),isActive:this.data.meta.counterType===z.get(l),closeOnActivate:!0,onActivate:()=>{this.changeCounters(z.get(l))}})}),t.push({type:"separator"},...r,i)}return t}onPaste(t){const{tagName:n}=t.detail.data;switch(n){case"OL":this.listStyle="ordered";break;case"UL":case"LI":this.listStyle="unordered"}this.list.onPaste(t)}pasteHandler(t){return this.list.pasteHandler(t)}changeCounters(t){var n;(n=this.list)==null||n.changeCounters(t),this.data.meta.counterType=t}changeStartWith(t){var n;(n=this.list)==null||n.changeStartWith(t),this.data.meta.start=t}changeTabulatorByStyle(){switch(this.listStyle){case"ordered":this.list=new $e({data:this.data,readOnly:this.readOnly,api:this.api,config:this.config,block:this.block},new v(this.readOnly,this.config));break;case"unordered":this.list=new $e({data:this.data,readOnly:this.readOnly,api:this.api,config:this.config,block:this.block},new b(this.readOnly,this.config));break;case"checklist":this.list=new $e({data:this.data,readOnly:this.readOnly,api:this.api,config:this.config,block:this.block},new f(this.readOnly,this.config));break}}}return K});
diff --git a/httpdocs/themes/vuexy/js/editorjs/warning.js b/httpdocs/themes/vuexy/js/editorjs/warning.js
new file mode 100644
index 00000000..47eeea8c
--- /dev/null
+++ b/httpdocs/themes/vuexy/js/editorjs/warning.js
@@ -0,0 +1,8 @@
+/**
+ * Skipped minification because the original files appears to be already minified.
+ * Original file: /npm/@editorjs/warning@1.4.1/dist/warning.umd.js
+ *
+ * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
+ */
+(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(`.cdx-warning{position:relative}@media all and (min-width: 736px){.cdx-warning{padding-left:36px}}.cdx-warning [contentEditable=true][data-placeholder]:before{position:absolute;content:attr(data-placeholder);color:#707684;font-weight:400;opacity:0}.cdx-warning [contentEditable=true][data-placeholder]:empty:before{opacity:1}.cdx-warning [contentEditable=true][data-placeholder]:empty:focus:before{opacity:0}.cdx-warning:before{content:"";background-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='5' y='5' width='14' height='14' rx='4' stroke='black' stroke-width='2'/%3E%3Cline x1='12' y1='9' x2='12' y2='12' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3Cpath d='M12 15.02V15.01' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");width:24px;height:24px;background-size:24px 24px;position:absolute;margin-top:8px;left:0}@media all and (max-width: 735px){.cdx-warning:before{display:none}}.cdx-warning__message{min-height:85px}.cdx-warning__title{margin-bottom:6px}`)),document.head.appendChild(e)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
+(function(r,n){typeof exports=="object"&&typeof module<"u"?module.exports=n():typeof define=="function"&&define.amd?define(n):(r=typeof globalThis<"u"?globalThis:r||self,r.Warning=n())})(this,function(){"use strict";const r='',n="";class a{static get isReadOnlySupported(){return!0}static get toolbox(){return{icon:r,title:"Warning"}}static get enableLineBreaks(){return!0}static get DEFAULT_TITLE_PLACEHOLDER(){return"Title"}static get DEFAULT_MESSAGE_PLACEHOLDER(){return"Message"}get CSS(){return{baseClass:this.api.styles.block,wrapper:"cdx-warning",title:"cdx-warning__title",input:this.api.styles.input,message:"cdx-warning__message"}}constructor({data:t,config:e,api:s,readOnly:i}){this.api=s,this.readOnly=i,this.titlePlaceholder=(e==null?void 0:e.titlePlaceholder)||a.DEFAULT_TITLE_PLACEHOLDER,this.messagePlaceholder=(e==null?void 0:e.messagePlaceholder)||a.DEFAULT_MESSAGE_PLACEHOLDER,this.data={title:t.title||"",message:t.message||""}}render(){const t=this._make("div",[this.CSS.baseClass,this.CSS.wrapper]),e=this._make("div",[this.CSS.input,this.CSS.title],{contentEditable:!this.readOnly,innerHTML:this.data.title}),s=this._make("div",[this.CSS.input,this.CSS.message],{contentEditable:!this.readOnly,innerHTML:this.data.message});return e.dataset.placeholder=this.titlePlaceholder,s.dataset.placeholder=this.messagePlaceholder,t.appendChild(e),t.appendChild(s),t}save(t){const e=t.querySelector(`.${this.CSS.title}`),s=t.querySelector(`.${this.CSS.message}`);return Object.assign(this.data,{title:(e==null?void 0:e.innerHTML)??"",message:(s==null?void 0:s.innerHTML)??""})}_make(t,e=null,s={}){const i=document.createElement(t);Array.isArray(e)?i.classList.add(...e):e&&i.classList.add(e);for(const l in s)i[l]=s[l];return i}static get sanitize(){return{title:{},message:{}}}}return a});
\ No newline at end of file