Compare commits

...

34 Commits

Author SHA1 Message Date
Meinzzzz
934feff65f
Merge f8d84814e079bdca892c1c2cac75c53baa96f20b into 2e431b11350698b6095037bb51aedb95f3466464 2025-11-28 11:26:22 +02:00
Elian Doran
2e431b1135
chore(deps): update dependency electron to v38.7.2 (#7873)
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Documentation / Build and Deploy Documentation (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
2025-11-28 11:26:12 +02:00
Elian Doran
e2ec27250c
chore(deps): update dependency happy-dom to v20.0.11 (#7874) 2025-11-28 08:24:15 +02:00
Elian Doran
1228eda5ea
chore(deps): update pnpm to v10.24.0 (#7875) 2025-11-28 08:23:01 +02:00
renovate[bot]
435794df73
chore(deps): update pnpm to v10.24.0 2025-11-28 01:16:30 +00:00
renovate[bot]
7e3d0639f7
chore(deps): update dependency happy-dom to v20.0.11 2025-11-28 01:16:18 +00:00
renovate[bot]
86b0005821
chore(deps): update dependency electron to v38.7.2 2025-11-28 01:15:07 +00:00
meinzzzz
f8d84814e0 Fix differential d problems 2025-11-26 23:02:34 +01:00
meinzzzz
c46cf41842 Small improvements 2025-11-26 22:48:57 +01:00
meinzzzz
64ab1c4116 Imrovement for Latex 2025-11-26 22:29:29 +01:00
meinzzzz
a6de1041c7 Fix bug in math rendering where old content was not cleared 2025-11-26 21:59:33 +01:00
meinzzzz
c8d34e65ea Improve max window size 2025-11-26 21:49:09 +01:00
meinzzzz
51db729546 Improve and simplify Mathfield integration 2025-11-25 23:27:06 +01:00
meinzzzz
d2052ad236 Disable mathlive sound effects 2025-11-24 21:51:59 +01:00
meinzzzz
9c4301467f Remove unused icons from ckeditor5-math package 2025-11-24 19:46:04 +01:00
meinzzzz
e7355dc0e4 remove gitignore unneccesary changes 2025-11-24 18:43:52 +01:00
meinzzzz
4110fec94f Removed unnecessary declare keyboard 2025-11-24 18:28:59 +01:00
meinzzzz
d5e601eae9 Simpliyfied resize logic for math input form and improved css 2025-11-24 17:56:18 +01:00
meinzzzz
4f044c4a57 Use icons form CKEditor5 icons, instead of testing icons. 2025-11-23 22:43:07 +01:00
meinzzzz
5821c350e1 Fixing class property initialization order 2025-11-23 17:58:51 +01:00
meinzzzz
edba8188fe Fix dark selection colors in MathLive math-field 2025-11-23 13:44:28 +01:00
meinzzzz
1471a72633 refactor: avoid recursive updates in mathLiveInput by normalizing value before updateing 2025-11-23 13:34:22 +01:00
meinzzzz
56834cb88a Improve MathLive and Raw LaTeX input views to propagate mousedown events 2025-11-23 13:29:26 +01:00
meinzzzz
a0f16f9184 Fix typos in mathform.css 2025-11-23 13:09:56 +01:00
meinzzzz
de80eb4806 Improve mathform.css styling for better visual integration 2025-11-22 22:42:34 +01:00
meinzzzz
48a4b81fbe remove automated screenshot files 2025-11-22 21:40:55 +01:00
meinzzzz
e225794f72 Better window focus handling in MathFormView 2025-11-22 21:35:37 +01:00
meinzzzz
4eef30f8b5 Fix names 2025-11-22 00:20:20 +01:00
meinzzzz
569b09609d Remove mathlive dependency and chunking 2025-11-22 00:01:14 +01:00
meinzzzz
39838c25c2 Fixed chaching problems 2025-11-21 23:50:49 +01:00
meinzzzz
49e90c08a9 Better Names for Math UI Components 2025-11-20 22:45:21 +01:00
meinzzzz
e777b06fb8 Math 2025-11-20 18:53:39 +01:00
meinzzzz
497ec2ac74 Merge branch 'main' of https://github.com/Meinzzzz/Trilium-Mathlive 2025-11-20 18:00:18 +01:00
meinzzzz
c5d282d203 Mathlive 2025-11-20 00:09:10 +01:00
17 changed files with 716 additions and 359 deletions

View File

@ -9,7 +9,7 @@
"keywords": [], "keywords": [],
"author": "Elian Doran <contact@eliandoran.me>", "author": "Elian Doran <contact@eliandoran.me>",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"packageManager": "pnpm@10.23.0", "packageManager": "pnpm@10.24.0",
"devDependencies": { "devDependencies": {
"@redocly/cli": "2.12.0", "@redocly/cli": "2.12.0",
"archiver": "7.0.1", "archiver": "7.0.1",

View File

@ -77,7 +77,7 @@
"@types/reveal.js": "5.2.1", "@types/reveal.js": "5.2.1",
"@types/tabulator-tables": "6.3.0", "@types/tabulator-tables": "6.3.0",
"copy-webpack-plugin": "13.0.1", "copy-webpack-plugin": "13.0.1",
"happy-dom": "20.0.10", "happy-dom": "20.0.11",
"script-loader": "0.7.2", "script-loader": "0.7.2",
"vite-plugin-static-copy": "3.1.4" "vite-plugin-static-copy": "3.1.4"
} }

View File

@ -35,7 +35,7 @@
"@triliumnext/commons": "workspace:*", "@triliumnext/commons": "workspace:*",
"@triliumnext/server": "workspace:*", "@triliumnext/server": "workspace:*",
"copy-webpack-plugin": "13.0.1", "copy-webpack-plugin": "13.0.1",
"electron": "38.7.1", "electron": "38.7.2",
"@electron-forge/cli": "7.10.2", "@electron-forge/cli": "7.10.2",
"@electron-forge/maker-deb": "7.10.2", "@electron-forge/maker-deb": "7.10.2",
"@electron-forge/maker-dmg": "7.10.2", "@electron-forge/maker-dmg": "7.10.2",

View File

@ -12,7 +12,7 @@
"@triliumnext/desktop": "workspace:*", "@triliumnext/desktop": "workspace:*",
"@types/fs-extra": "11.0.4", "@types/fs-extra": "11.0.4",
"copy-webpack-plugin": "13.0.1", "copy-webpack-plugin": "13.0.1",
"electron": "38.7.1", "electron": "38.7.2",
"fs-extra": "11.3.2" "fs-extra": "11.3.2"
}, },
"scripts": { "scripts": {

View File

@ -80,7 +80,7 @@
"debounce": "3.0.0", "debounce": "3.0.0",
"debug": "4.4.3", "debug": "4.4.3",
"ejs": "3.1.10", "ejs": "3.1.10",
"electron": "38.7.1", "electron": "38.7.2",
"electron-debug": "4.1.0", "electron-debug": "4.1.0",
"electron-window-state": "5.0.3", "electron-window-state": "5.0.3",
"escape-html": "1.0.3", "escape-html": "1.0.3",

View File

@ -84,7 +84,7 @@
"url": "https://github.com/TriliumNext/Trilium/issues" "url": "https://github.com/TriliumNext/Trilium/issues"
}, },
"homepage": "https://triliumnotes.org", "homepage": "https://triliumnotes.org",
"packageManager": "pnpm@10.23.0", "packageManager": "pnpm@10.24.0",
"pnpm": { "pnpm": {
"patchedDependencies": { "patchedDependencies": {
"@ckeditor/ckeditor5-mention": "patches/@ckeditor__ckeditor5-mention.patch", "@ckeditor/ckeditor5-mention": "patches/@ckeditor__ckeditor5-mention.patch",

View File

@ -71,6 +71,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@ckeditor/ckeditor5-icons": "47.2.0" "@ckeditor/ckeditor5-icons": "47.2.0",
"mathlive": "0.108.2"
} }
} }

View File

@ -1,6 +1,9 @@
import ckeditor from './../theme/icons/math.svg?raw'; import ckeditor from './../theme/icons/math.svg?raw';
import './augmentation.js'; import './augmentation.js';
import "../theme/mathform.css"; import "../theme/mathform.css";
import 'mathlive';
import 'mathlive/fonts.css';
import 'mathlive/static.css';
export { default as Math } from './math.js'; export { default as Math } from './math.js';
export { default as MathUI } from './mathui.js'; export { default as MathUI } from './mathui.js';

View File

@ -56,7 +56,7 @@ export default class MathUI extends Plugin {
this._balloon.showStack( 'main' ); this._balloon.showStack( 'main' );
requestAnimationFrame(() => { requestAnimationFrame(() => {
this.formView?.mathInputView.fieldView.element?.focus(); this.formView?.mathLiveInputView.focus();
}); });
} }
@ -71,31 +71,38 @@ export default class MathUI extends Plugin {
throw new CKEditorError( 'math-command' ); throw new CKEditorError( 'math-command' );
} }
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const mathConfig = editor.config.get( 'math' )!; const mathConfig = editor.config.get( 'math' )!;
const formView = new MainFormView( const formView = new MainFormView(
editor.locale, editor.locale,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion {
mathConfig.engine!, engine: mathConfig.engine!,
mathConfig.lazyLoad, lazyLoad: mathConfig.lazyLoad,
previewUid: this._previewUid,
previewClassName: mathConfig.previewClassName!,
katexRenderOptions: mathConfig.katexRenderOptions!
},
mathConfig.enablePreview, mathConfig.enablePreview,
this._previewUid, mathConfig.popupClassName!
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
mathConfig.previewClassName!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
mathConfig.popupClassName!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
mathConfig.katexRenderOptions!
); );
formView.mathInputView.bind( 'value' ).to( mathCommand, 'value' ); formView.mathLiveInputView.bind( 'value' ).to( mathCommand, 'value' );
formView.displayButtonView.bind( 'isOn' ).to( mathCommand, 'display' ); formView.displayButtonView.bind( 'isOn' ).to( mathCommand, 'display' );
// Form elements should be read-only when corresponding commands are disabled. // Form elements should be read-only when corresponding commands are disabled.
formView.mathInputView.bind( 'isReadOnly' ).to( mathCommand, 'isEnabled', value => !value ); formView.mathLiveInputView.bind( 'isReadOnly' ).to( mathCommand, 'isEnabled', value => !value );
formView.saveButtonView.bind( 'isEnabled' ).to( mathCommand ); formView.saveButtonView.bind( 'isEnabled' ).to(
formView.displayButtonView.bind( 'isEnabled' ).to( mathCommand ); mathCommand,
'isEnabled',
formView.mathLiveInputView,
'value',
( commandEnabled, equation ) => {
const normalizedEquation = ( equation ?? '' ).trim();
return commandEnabled && normalizedEquation.length > 0;
}
);
formView.displayButtonView.bind( 'isEnabled' ).to( mathCommand, 'isEnabled' );
// Listen to submit button click // Listen to submit button click
this.listenTo( formView, 'submit', () => { this.listenTo( formView, 'submit', () => {
@ -122,18 +129,6 @@ export default class MathUI extends Plugin {
} }
}); });
// Allow the textarea to be resizable
formView.mathInputView.fieldView.once('render', () => {
const textarea = formView.mathInputView.fieldView.element;
if (!textarea) return;
Object.assign(textarea.style, {
resize: 'both',
height: '100px',
width: '400px',
minWidth: '100%',
});
});
return formView; return formView;
} }
@ -162,14 +157,14 @@ export default class MathUI extends Plugin {
} ); } );
if ( this._balloon.visibleView === this.formView ) { if ( this._balloon.visibleView === this.formView ) {
this.formView.mathInputView.fieldView.element?.select(); this.formView.mathLiveInputView.focus();
} }
// Show preview element // Show preview element
const previewEl = document.getElementById( this._previewUid ); const previewEl = document.getElementById( this._previewUid );
if ( previewEl && this.formView.previewEnabled ) { if ( previewEl && this.formView.mathView ) {
// Force refresh preview // Force refresh preview
this.formView.mathView?.updateMath(); this.formView.mathView.updateMath();
} }
this.formView.equation = mathCommand.value ?? ''; this.formView.equation = mathCommand.value ?? '';

View File

@ -1,270 +1,219 @@
import { ButtonView, createLabeledTextarea, FocusCycler, LabelView, LabeledFieldView, submitHandler, SwitchButtonView, View, ViewCollection, type TextareaView, type FocusableView, Locale, FocusTracker, KeystrokeHandler } from 'ckeditor5'; import {
import IconCheck from "@ckeditor/ckeditor5-icons/theme/icons/check.svg?raw"; ButtonView,
import IconCancel from "@ckeditor/ckeditor5-icons/theme/icons/cancel.svg?raw"; FocusCycler,
LabelView,
submitHandler,
SwitchButtonView,
View,
ViewCollection,
type FocusableView,
Locale,
FocusTracker,
KeystrokeHandler
} from 'ckeditor5';
import IconCheck from '@ckeditor/ckeditor5-icons/theme/icons/check.svg?raw';
import IconCancel from '@ckeditor/ckeditor5-icons/theme/icons/cancel.svg?raw';
import { extractDelimiters, hasDelimiters } from '../utils.js'; import { extractDelimiters, hasDelimiters } from '../utils.js';
import MathView from './mathview.js'; import MathView, { type MathViewOptions } from './mathview.js';
import MathLiveInputView from './mathliveinputview.js';
import RawLatexInputView from './rawlatexinputview.js';
import '../../theme/mathform.css'; import '../../theme/mathform.css';
import type { KatexOptions } from '../typings-external.js';
class MathInputView extends LabeledFieldView<TextareaView> {
public value: null | string = null;
public isReadOnly = false;
constructor( locale: Locale ) {
super( locale, createLabeledTextarea );
}
}
export default class MainFormView extends View { export default class MainFormView extends View {
public saveButtonView: ButtonView; public saveButtonView: ButtonView;
public mathInputView: MathInputView;
public displayButtonView: SwitchButtonView;
public cancelButtonView: ButtonView; public cancelButtonView: ButtonView;
public previewEnabled: boolean; public displayButtonView: SwitchButtonView;
public previewLabel?: LabelView;
public mathLiveInputView: MathLiveInputView;
public rawLatexInputView: RawLatexInputView;
public mathView?: MathView; public mathView?: MathView;
public override locale: Locale = new Locale();
public lazyLoad: undefined | ( () => Promise<void> ); public focusTracker = new FocusTracker();
public keystrokes = new KeystrokeHandler();
private _focusables = new ViewCollection<FocusableView>();
private _focusCycler: FocusCycler;
constructor( constructor(
locale: Locale, locale: Locale,
engine: mathViewOptions: MathViewOptions,
| 'mathjax'
| 'katex'
| ( (
equation: string,
element: HTMLElement,
display: boolean,
) => void ),
lazyLoad: undefined | ( () => Promise<void> ),
previewEnabled = false, previewEnabled = false,
previewUid: string, popupClassName: string[] = []
previewClassName: Array<string>,
popupClassName: Array<string>,
katexRenderOptions: KatexOptions
) { ) {
super( locale ); super( locale );
const t = locale.t; const t = locale.t;
// Submit button // --- 1. View Initialization ---
this.saveButtonView = this._createButton( t( 'Save' ), IconCheck, 'ck-button-save', null );
this.mathLiveInputView = new MathLiveInputView( locale );
this.rawLatexInputView = new RawLatexInputView( locale );
this.rawLatexInputView.label = t( 'LaTeX' );
this.saveButtonView = this._createButton( t( 'Save' ), IconCheck, 'ck-button-save' );
this.saveButtonView.type = 'submit'; this.saveButtonView.type = 'submit';
// Equation input this.cancelButtonView = this._createButton( t( 'Cancel' ), IconCancel, 'ck-button-cancel' );
this.mathInputView = this._createMathInput(); this.cancelButtonView.delegate( 'execute' ).to( this, 'cancel' );
// Display button this.displayButtonView = this._createDisplayButton( t );
this.displayButtonView = this._createDisplayButton();
// Cancel button // --- 2. Construct Children & Preview ---
this.cancelButtonView = this._createButton( t( 'Cancel' ), IconCancel, 'ck-button-cancel', 'cancel' );
this.previewEnabled = previewEnabled; const children: View[] = [
this.mathLiveInputView,
this.rawLatexInputView,
this.displayButtonView
];
let children = []; if ( previewEnabled ) {
if ( this.previewEnabled ) { const previewLabel = new LabelView( locale );
// Preview label previewLabel.text = t( 'Equation preview' );
this.previewLabel = new LabelView( locale );
this.previewLabel.text = t( 'Equation preview' );
// Math element // Clean instantiation using the options object
this.mathView = new MathView( engine, lazyLoad, locale, previewUid, previewClassName, katexRenderOptions ); this.mathView = new MathView( locale, mathViewOptions );
// Bind display mode: When button flips, preview updates automatically
this.mathView.bind( 'display' ).to( this.displayButtonView, 'isOn' ); this.mathView.bind( 'display' ).to( this.displayButtonView, 'isOn' );
children = [ children.push( previewLabel, this.mathView );
this.mathInputView,
this.displayButtonView,
this.previewLabel,
this.mathView
];
} else {
children = [
this.mathInputView,
this.displayButtonView
];
} }
// Add UI elements to template // --- 3. Sync Logic ---
this._setupInputSync( previewEnabled );
// --- 4. Template Setup ---
this.setTemplate( { this.setTemplate( {
tag: 'form', tag: 'form',
attributes: { attributes: {
class: [ class: [ 'ck', 'ck-math-form', ...popupClassName ],
'ck',
'ck-math-form',
...popupClassName
],
tabindex: '-1', tabindex: '-1',
spellcheck: 'false' spellcheck: 'false'
}, },
children: [ children: [
{ {
tag: 'div', tag: 'div',
attributes: { attributes: { class: [ 'ck-math-scroll' ] },
class: [ children: [ { tag: 'div', attributes: { class: [ 'ck-math-view' ] }, children } ]
'ck-math-view'
]
},
children
}, },
this.saveButtonView, {
this.cancelButtonView tag: 'div',
attributes: { class: [ 'ck-math-button-row' ] },
children: [ this.saveButtonView, this.cancelButtonView ]
}
] ]
} ); } );
// --- 5. Accessibility ---
this._focusCycler = new FocusCycler( {
focusables: this._focusables,
focusTracker: this.focusTracker,
keystrokeHandler: this.keystrokes,
actions: { focusPrevious: 'shift + tab', focusNext: 'tab' }
} );
} }
public override render(): void { public override render(): void {
super.render(); super.render();
// Prevent default form submit event & trigger custom 'submit' submitHandler( { view: this } );
submitHandler( {
view: this
} );
// Register form elements to focusable elements // Register focusables
const childViews = [ [
this.mathInputView, this.mathLiveInputView,
this.rawLatexInputView,
this.displayButtonView, this.displayButtonView,
this.saveButtonView, this.saveButtonView,
this.cancelButtonView this.cancelButtonView
]; ].forEach( v => {
childViews.forEach( v => {
if ( v.element ) { if ( v.element ) {
this._focusables.add( v ); this._focusables.add( v );
this.focusTracker.add( v.element ); this.focusTracker.add( v.element );
} }
} ); } );
// Listen to keypresses inside form element if ( this.element ) this.keystrokes.listenTo( this.element );
if ( this.element ) { }
this.keystrokes.listenTo( this.element );
} public get equation(): string {
return this.mathLiveInputView.value ?? '';
}
public set equation( equation: string ) {
const norm = equation.trim();
// Direct updates to the "source of truth"
this.mathLiveInputView.value = norm.length ? norm : null;
this.rawLatexInputView.value = norm;
if ( this.mathView ) this.mathView.value = norm;
} }
public focus(): void { public focus(): void {
this._focusCycler.focusFirst(); this._focusCycler.focusFirst();
} }
public get equation(): string { /**
return this.mathInputView.fieldView.element?.value ?? ''; * Sets up split handlers for synchronization.
} */
private _setupInputSync( previewEnabled: boolean ): void {
// Handler 1: MathLive -> Raw LaTeX
this.mathLiveInputView.on( 'change:value', () => {
let eq = ( this.mathLiveInputView.value ?? '' ).trim();
public set equation( equation: string ) { // Delimiter Normalization
if ( this.mathInputView.fieldView.element ) { if ( hasDelimiters( eq ) ) {
this.mathInputView.fieldView.element.value = equation; const params = extractDelimiters( eq );
} eq = params.equation;
if ( this.previewEnabled && this.mathView ) { this.displayButtonView.isOn = params.display;
this.mathView.value = equation;
}
}
public focusTracker: FocusTracker = new FocusTracker(); // UX Fix: If we stripped delimiters, update the source
public keystrokes: KeystrokeHandler = new KeystrokeHandler(); // so the visual editor doesn't show them.
private _focusables = new ViewCollection<FocusableView>(); if ( this.mathLiveInputView.value !== eq ) {
private _focusCycler: FocusCycler = new FocusCycler( { this.mathLiveInputView.value = eq;
focusables: this._focusables,
focusTracker: this.focusTracker,
keystrokeHandler: this.keystrokes,
actions: {
focusPrevious: 'shift + tab',
focusNext: 'tab'
}
} );
private _createMathInput() {
const t = this.locale.t;
// Create equation input
const mathInput = new MathInputView( this.locale );
const fieldView = mathInput.fieldView;
mathInput.infoText = t( 'Insert equation in TeX format.' );
const onInput = () => {
if ( fieldView.element != null ) {
let equationInput = fieldView.element.value.trim();
// If input has delimiters
if ( hasDelimiters( equationInput ) ) {
// Get equation without delimiters
const params = extractDelimiters( equationInput );
// Remove delimiters from input field
fieldView.element.value = params.equation;
equationInput = params.equation;
// update display button and preview
this.displayButtonView.isOn = params.display;
} }
if ( this.previewEnabled && this.mathView ) {
// Update preview view
this.mathView.value = equationInput;
}
this.saveButtonView.isEnabled = !!equationInput;
} }
};
fieldView.on( 'render', onInput ); // Sync to Raw LaTeX
fieldView.on( 'input', onInput ); if ( this.rawLatexInputView.value !== eq ) {
this.rawLatexInputView.value = eq;
}
return mathInput; // Sync to Preview
if ( previewEnabled && this.mathView && this.mathView.value !== eq ) {
this.mathView.value = eq;
}
} );
// Handler 2: Raw LaTeX -> MathLive
this.rawLatexInputView.on( 'change:value', () => {
const eq = ( this.rawLatexInputView.value ?? '' ).trim();
const normalized = eq.length ? eq : null;
// Sync to MathLive
if ( this.mathLiveInputView.value !== normalized ) {
this.mathLiveInputView.value = normalized;
}
// Sync to Preview
if ( previewEnabled && this.mathView && this.mathView.value !== eq ) {
this.mathView.value = eq;
}
} );
} }
private _createButton( private _createButton( label: string, icon: string, className: string ): ButtonView {
label: string, const btn = new ButtonView( this.locale );
icon: string, btn.set( { label, icon, tooltip: true } );
className: string, btn.extendTemplate( { attributes: { class: className } } );
eventName: string | null return btn;
) {
const button = new ButtonView( this.locale );
button.set( {
label,
icon,
tooltip: true
} );
button.extendTemplate( {
attributes: {
class: className
}
} );
if ( eventName ) {
button.delegate( 'execute' ).to( this, eventName );
}
return button;
} }
private _createDisplayButton() { private _createDisplayButton( t: ( str: string ) => string ): SwitchButtonView {
const t = this.locale.t; const btn = new SwitchButtonView( this.locale );
btn.set( { label: t( 'Display mode' ), withText: true } );
btn.extendTemplate( { attributes: { class: 'ck-button-display-toggle' } } );
const switchButton = new SwitchButtonView( this.locale ); btn.on( 'execute', () => {
btn.isOn = !btn.isOn;
switchButton.set( { // mathView updates automatically via bind()
label: t( 'Display mode' ),
withText: true
} ); } );
return btn;
switchButton.extendTemplate( {
attributes: {
class: 'ck-button-display-toggle'
}
} );
switchButton.on( 'execute', () => {
// Toggle state
switchButton.isOn = !switchButton.isOn;
if ( this.previewEnabled && this.mathView ) {
// Update preview view
this.mathView.display = switchButton.isOn;
}
} );
return switchButton;
} }
} }

View File

@ -0,0 +1,116 @@
import { View, type Locale } from 'ckeditor5';
import 'mathlive'; // Import side-effects only (registers the <math-field> tag)
/**
* Interface describing the custom <math-field> element.
*/
interface MathFieldElement extends HTMLElement {
value: string;
readOnly: boolean;
mathVirtualKeyboardPolicy: string;
// Interface includes the shortcuts property
inlineShortcuts: Record<string, string>;
}
/**
* A wrapper for the MathLive <math-field> component.
*/
export default class MathLiveInputView extends View {
/**
* The current LaTeX value.
* @observable
*/
public declare value: string | null;
/**
* Read-only state.
* @observable
*/
public declare isReadOnly: boolean;
/**
* Reference to the DOM element.
* Typed as MathFieldElement | null for proper TS support.
*/
public mathfield: MathFieldElement | null = null;
constructor( locale: Locale ) {
super( locale );
this.set( 'value', null );
this.set( 'isReadOnly', false );
this.setTemplate( {
tag: 'div',
attributes: {
class: [ 'ck', 'ck-mathlive-input' ]
}
} );
}
public override render(): void {
super.render();
// 1. Create element with the specific type
const mathfield = document.createElement( 'math-field' ) as MathFieldElement;
// 2. Configure Options
mathfield.mathVirtualKeyboardPolicy = 'manual';
//Disable differential D
mathfield.addEventListener( 'mount', () => {
mathfield.inlineShortcuts = {
...mathfield.inlineShortcuts, // Safe to read now
dx: 'dx',
dy: 'dy',
dt: 'dt'
};
} );
// Disable sounds safely
const MathfieldConstructor = customElements.get( 'math-field' );
if ( MathfieldConstructor ) {
const proto = MathfieldConstructor as any;
if ( proto.soundsDirectory !== null ) proto.soundsDirectory = null;
if ( proto.plonkSound !== null ) proto.plonkSound = null;
}
// 3. Set Initial State
mathfield.value = this.value ?? '';
mathfield.readOnly = this.isReadOnly;
// 4. Bind Events (DOM -> Observable)
mathfield.addEventListener( 'input', () => {
const val = mathfield.value;
this.value = val.length ? val : null;
} );
// 5. Bind Events (Observable -> DOM)
this.on( 'change:value', ( _evt, _name, nextValue ) => {
if ( mathfield.value !== nextValue ) {
mathfield.value = nextValue ?? '';
}
} );
this.on( 'change:isReadOnly', ( _evt, _name, nextValue ) => {
mathfield.readOnly = nextValue;
} );
// 6. Mount to the wrapper view
this.element?.appendChild( mathfield );
this.mathfield = mathfield;
}
public focus(): void {
this.mathfield?.focus();
}
public override destroy(): void {
if ( this.mathfield ) {
this.mathfield.remove();
this.mathfield = null;
}
super.destroy();
}
}

View File

@ -2,44 +2,44 @@ import { View, type Locale } from 'ckeditor5';
import type { KatexOptions } from '../typings-external.js'; import type { KatexOptions } from '../typings-external.js';
import { renderEquation } from '../utils.js'; import { renderEquation } from '../utils.js';
/**
* Configuration options for the MathView.
*/
export interface MathViewOptions {
engine: 'mathjax' | 'katex' | ( ( equation: string, element: HTMLElement, display: boolean ) => void );
lazyLoad: undefined | ( () => Promise<void> );
previewUid: string;
previewClassName: Array<string>;
katexRenderOptions: KatexOptions;
}
export default class MathView extends View { export default class MathView extends View {
/**
* The LaTeX equation value to render.
* @observable
*/
public declare value: string; public declare value: string;
/**
* Whether to render in display mode (centered) or inline.
* @observable
*/
public declare display: boolean; public declare display: boolean;
public previewUid: string;
public previewClassName: Array<string>;
public katexRenderOptions: KatexOptions;
public engine:
| 'mathjax'
| 'katex'
| ( ( equation: string, element: HTMLElement, display: boolean ) => void );
public lazyLoad: undefined | ( () => Promise<void> );
constructor( /**
engine: * Configuration options passed during initialization.
| 'mathjax' */
| 'katex' private options: MathViewOptions;
| ( (
equation: string, constructor( locale: Locale, options: MathViewOptions ) {
element: HTMLElement,
display: boolean,
) => void ),
lazyLoad: undefined | ( () => Promise<void> ),
locale: Locale,
previewUid: string,
previewClassName: Array<string>,
katexRenderOptions: KatexOptions
) {
super( locale ); super( locale );
this.options = options;
this.engine = engine;
this.lazyLoad = lazyLoad;
this.previewUid = previewUid;
this.katexRenderOptions = katexRenderOptions;
this.previewClassName = previewClassName;
this.set( 'value', '' ); this.set( 'value', '' );
this.set( 'display', false ); this.set( 'display', false );
// Update rendering when state changes.
// Checking isRendered prevents errors during initialization.
this.on( 'change', () => { this.on( 'change', () => {
if ( this.isRendered ) { if ( this.isRendered ) {
this.updateMath(); this.updateMath();
@ -56,16 +56,20 @@ export default class MathView extends View {
public updateMath(): void { public updateMath(): void {
if ( this.element ) { if ( this.element ) {
// This prevents the new render from appending to the old one.
this.element.textContent = '';
void renderEquation( void renderEquation(
this.value, this.value,
this.element, this.element,
this.engine, this.options.engine,
this.lazyLoad, this.options.lazyLoad,
this.display, this.display,
true, true, // isPreview
this.previewUid, this.options.previewUid,
this.previewClassName, this.options.previewClassName,
this.katexRenderOptions this.options.katexRenderOptions
); );
} }
} }

View File

@ -0,0 +1,54 @@
import { LabeledFieldView, createLabeledTextarea, type Locale, type TextareaView } from 'ckeditor5';
/**
* A labeled textarea view for direct LaTeX code editing.
*/
export default class RawLatexInputView extends LabeledFieldView<TextareaView> {
/**
* The current LaTeX value.
* @observable
*/
public declare value: string;
/**
* Whether the input is in read-only mode.
* @observable
*/
public declare isReadOnly: boolean;
constructor( locale: Locale ) {
super( locale, createLabeledTextarea );
this.set( 'value', '' );
this.set( 'isReadOnly', false );
const fieldView = this.fieldView;
// 1. Sync: DOM (Textarea) -> Observable
fieldView.on( 'input', () => {
// We cast strictly to HTMLTextAreaElement to access '.value' safely
const textarea = fieldView.element as HTMLTextAreaElement;
if ( textarea ) {
this.value = textarea.value;
}
} );
// 2. Sync: Observable -> DOM (Textarea)
this.on( 'change:value', () => {
const textarea = fieldView.element as HTMLTextAreaElement;
// Check for difference to avoid cursor jumping
if ( textarea && textarea.value !== this.value ) {
textarea.value = this.value;
}
} );
// 3. Sync: ReadOnly State
this.on( 'change:isReadOnly', ( _evt, _name, nextValue ) => {
fieldView.isReadOnly = nextValue;
} );
}
public override render(): void {
super.render();
}
}

View File

@ -168,13 +168,13 @@ describe( 'MathUI', () => {
command.isEnabled = true; command.isEnabled = true;
expect( formView!.mathInputView.isReadOnly ).to.be.false; expect( formView!.mathLiveInputView.isReadOnly ).to.be.false;
expect( formView!.saveButtonView.isEnabled ).to.be.false; expect( formView!.saveButtonView.isEnabled ).to.be.false;
expect( formView!.cancelButtonView.isEnabled ).to.be.true; expect( formView!.cancelButtonView.isEnabled ).to.be.true;
command.isEnabled = false; command.isEnabled = false;
expect( formView!.mathInputView.isReadOnly ).to.be.true; expect( formView!.mathLiveInputView.isReadOnly ).to.be.true;
expect( formView!.saveButtonView.isEnabled ).to.be.false; expect( formView!.saveButtonView.isEnabled ).to.be.false;
expect( formView!.cancelButtonView.isEnabled ).to.be.true; expect( formView!.cancelButtonView.isEnabled ).to.be.true;
} ); } );
@ -407,22 +407,30 @@ describe( 'MathUI', () => {
setModelData( editor.model, '<paragraph>f[o]o</paragraph>' ); setModelData( editor.model, '<paragraph>f[o]o</paragraph>' );
} ); } );
it( 'should bind mainFormView.mathInputView#value to math command value', () => { it( 'should bind mainFormView.mathLiveInputView#value to math command value', () => {
const command = editor.commands.get( 'math' ); const command = editor.commands.get( 'math' );
expect( formView!.mathInputView.value ).to.null; expect( formView!.mathLiveInputView.value ).to.be.null;
command!.value = 'x^2'; command!.value = 'x^2';
expect( formView!.mathInputView.value ).to.equal( 'x^2' ); expect( formView!.mathLiveInputView.value ).to.equal( 'x^2' );
} ); } );
it( 'should execute math command on mainFormView#submit event', () => { it( 'should execute math command on mainFormView#submit event', () => {
const executeSpy = vi.spyOn( editor, 'execute' ); const executeSpy = vi.spyOn( editor, 'execute' );
formView!.mathInputView.fieldView.element!.value = 'x^2'; formView!.mathLiveInputView.value = 'x^2';
formView!.fire( 'submit' ); formView!.fire( 'submit' );
expect(executeSpy.mock.lastCall?.slice(0, 2)).toMatchObject(['math', 'x^2']); expect( executeSpy.mock.lastCall?.slice( 0, 2 ) ).toMatchObject( [ 'math', 'x^2' ] );
} );
it( 'should sync mathLiveInputView and rawLatexInputView', () => {
formView!.mathLiveInputView.value = 'x^2';
expect( formView!.rawLatexInputView.value ).to.equal( 'x^2' );
formView!.rawLatexInputView.value = '\\frac{1}{2}';
expect( formView!.mathLiveInputView.value ).to.equal( '\\frac{1}{2}' );
} ); } );
it( 'should hide the balloon on mainFormView#cancel if math command does not have a value', () => { it( 'should hide the balloon on mainFormView#cancel if math command does not have a value', () => {

View File

@ -1,35 +1,214 @@
/**
* Math equation editor dialog styles
* Supports MathLive input, raw LaTeX textarea, and equation preview
*/
/* ============================================================================
Main Dialog Container
========================================================================= */
.ck.ck-math-form { .ck.ck-math-form {
display: flex; display: flex;
align-items: flex-start; flex-direction: column;
flex-direction: row; padding: var(--ck-spacing-standard);
flex-wrap: nowrap; box-sizing: border-box;
padding: var(--ck-spacing-standard); max-width: 80vw;
max-height: 80vh;
@media screen and (max-width: 600px) { height: 100%;
flex-wrap: wrap; overflow-x: hidden;
& .ck-math-view {
flex-basis: 100%;
& .ck-labeled-view {
flex-basis: 100%;
}
& .ck-label {
flex-basis: 100%;
}
}
& .ck-button {
flex-basis: 50%;
}
}
} }
.ck-math-tex.ck-placeholder::before { /* Mobile responsiveness */
display: none !important; @media screen and (max-width: 600px) {
.ck.ck-math-form {
flex-wrap: wrap;
}
} }
.ck.ck-toolbar-container { /* ============================================================================
z-index: calc(var(--ck-z-panel) + 2); Content Layout
========================================================================= */
.ck-math-view {
display: flex;
flex-direction: column;
flex: 1 1 auto;
gap: var(--ck-spacing-standard);
min-height: fit-content;
min-width: 0;
width: 100%;
}
/* LaTeX section heading */
.ck-math-view > .ck-labeled-field-view::before {
content: "LaTeX";
display: block;
font-size: 12px;
font-weight: 600;
color: var(--ck-color-text, #333);
margin-bottom: 4px;
padding-left: 2px;
opacity: 0.8;
}
/* Equation preview section heading */
.ck-math-view > math-field::before {
content: "Equation preview";
display: block;
font-size: 12px;
font-weight: 600;
color: var(--ck-color-text, #333);
margin-bottom: 4px;
padding-left: 2px;
opacity: 0.8;
}
/* Add spacing between preview and action buttons */
.ck-math-view > math-field {
margin-bottom: var(--ck-spacing-large, 16px);
}
/* Action buttons row (Save/Cancel) */
.ck-math-button-row {
display: flex;
flex-shrink: 0;
gap: var(--ck-spacing-standard);
margin-top: var(--ck-spacing-standard);
width: fit-content;
max-width: 100%;
flex-wrap: wrap;
}
/* ============================================================================
Shared Styles for Input Fields
========================================================================= */
/* Base styling for both MathLive fields and textareas */
.ck.ck-math-form math-field,
.ck.ck-math-form textarea {
box-sizing: border-box;
padding: var(--ck-spacing-small);
background: var(--ck-color-input-background) !important;
color: var(--ck-color-input-text, inherit);
font-size: var(--ck-font-size-base);
border: none !important;
border-radius: var(--ck-border-radius, 6px);
outline: 3px solid transparent;
outline-offset: 6px;
}
/* MathLive-specific configuration */
.ck.ck-math-form math-field {
display: block !important;
width: 100%;
max-width: 100%;
overflow-x: auto !important;
/* MathLive theme customization */
--selection-background-color: rgba(33, 150, 243, 0.2);
--selection-color: inherit;
--contains-highlight-background-color: rgba(0, 0, 0, 0.05);
}
/* ============================================================================
MathLive Visual Editor (Top Input)
========================================================================= */
.ck.ck-mathlive-input {
display: inline-block;
flex: 0 0 auto;
width: 100%;
max-width: 100%;
min-height: fit-content;
max-height: 80vh;
overflow: auto;
padding-bottom: var(--ck-spacing-small);
resize: none;
}
/* Configure MathLive shadow DOM layout */
.ck.ck-math-form math-field::part(container),
.ck.ck-math-form math-field::part(content),
.ck.ck-math-form math-field::part(field) {
display: flex;
flex-direction: column;
flex: 1 1 auto;
height: 100%;
align-items: flex-start;
justify-content: flex-start;
}
/* Position MathLive UI controls */
.ck.ck-math-form math-field::part(virtual-keyboard-toggle),
.ck.ck-math-form math-field::part(menu-toggle) {
position: absolute;
top: 8px;
}
.ck.ck-math-form math-field::part(virtual-keyboard-toggle) {
right: 40px;
}
.ck.ck-math-form math-field::part(menu-toggle) {
right: 8px;
display: flex !important;
visibility: visible !important;
}
/* ============================================================================
Raw LaTeX Textarea (Middle Input)
========================================================================= */
.ck-math-view .ck-labeled-field-view {
display: flex;
flex-direction: column;
flex: 0 0 auto;
min-width: 100%;
width: 100%;
max-width: 100%;
min-height: 60px;
max-height: 65vh;
resize: both;
overflow: auto;
background: transparent;
}
/* Hide the default label (we use ::before for custom heading) */
.ck-math-view .ck-labeled-field-view .ck-label {
display: none !important;
}
/* Textarea wrapper */
.ck-math-view .ck-labeled-field-view .ck-labeled-field-view__input-wrapper {
display: flex;
flex-direction: column;
flex: 1 1 auto;
width: 100%;
min-height: 100px;
height: auto;
padding: 0;
border: none;
background: transparent;
box-shadow: none;
}
/* Raw LaTeX textarea styling */
.ck-math-view .ck-labeled-field-view textarea {
display: block;
flex: 1 1 auto;
width: 100% !important;
height: 100%;
min-height: 140px;
resize: none !important;
border-radius: 0 !important;
box-shadow: none !important;
transition: none !important;
}
/* Textarea hover and focus states */
.ck-math-view .ck-labeled-field-view textarea:hover,
.ck-math-view .ck-labeled-field-view textarea:focus {
background: var(--ck-color-input-background) !important;
outline: none !important;
box-shadow: none !important;
} }

152
pnpm-lock.yaml generated
View File

@ -90,7 +90,7 @@ importers:
version: 7.0.1(eslint@9.39.1(jiti@2.6.1)) version: 7.0.1(eslint@9.39.1(jiti@2.6.1))
happy-dom: happy-dom:
specifier: ~20.0.0 specifier: ~20.0.0
version: 20.0.10 version: 20.0.11
http-server: http-server:
specifier: 14.1.1 specifier: 14.1.1
version: 14.1.1 version: 14.1.1
@ -129,7 +129,7 @@ importers:
version: 4.5.4(@types/node@24.10.1)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 4.5.4(@types/node@24.10.1)(rollup@4.52.0)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
apps/build-docs: apps/build-docs:
devDependencies: devDependencies:
@ -339,8 +339,8 @@ importers:
specifier: 13.0.1 specifier: 13.0.1
version: 13.0.1(webpack@5.101.3(esbuild@0.27.0)) version: 13.0.1(webpack@5.101.3(esbuild@0.27.0))
happy-dom: happy-dom:
specifier: 20.0.10 specifier: 20.0.11
version: 20.0.10 version: 20.0.11
script-loader: script-loader:
specifier: 0.7.2 specifier: 0.7.2
version: 0.7.2 version: 0.7.2
@ -367,7 +367,7 @@ importers:
dependencies: dependencies:
'@electron/remote': '@electron/remote':
specifier: 2.1.3 specifier: 2.1.3
version: 2.1.3(electron@38.7.1) version: 2.1.3(electron@38.7.2)
better-sqlite3: better-sqlite3:
specifier: 12.4.6 specifier: 12.4.6
version: 12.4.6 version: 12.4.6
@ -424,8 +424,8 @@ importers:
specifier: 13.0.1 specifier: 13.0.1
version: 13.0.1(webpack@5.101.3(esbuild@0.27.0)) version: 13.0.1(webpack@5.101.3(esbuild@0.27.0))
electron: electron:
specifier: 38.7.1 specifier: 38.7.2
version: 38.7.1 version: 38.7.2
prebuild-install: prebuild-install:
specifier: 7.1.3 specifier: 7.1.3
version: 7.1.3 version: 7.1.3
@ -480,8 +480,8 @@ importers:
specifier: 13.0.1 specifier: 13.0.1
version: 13.0.1(webpack@5.101.3(esbuild@0.27.0)) version: 13.0.1(webpack@5.101.3(esbuild@0.27.0))
electron: electron:
specifier: 38.7.1 specifier: 38.7.2
version: 38.7.1 version: 38.7.2
fs-extra: fs-extra:
specifier: 11.3.2 specifier: 11.3.2
version: 11.3.2 version: 11.3.2
@ -506,7 +506,7 @@ importers:
version: 7.1.1 version: 7.1.1
'@electron/remote': '@electron/remote':
specifier: 2.1.3 specifier: 2.1.3
version: 2.1.3(electron@38.7.1) version: 2.1.3(electron@38.7.2)
'@preact/preset-vite': '@preact/preset-vite':
specifier: 2.10.2 specifier: 2.10.2
version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.10.2(@babel/core@7.28.0)(preact@10.27.2)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
@ -649,8 +649,8 @@ importers:
specifier: 3.1.10 specifier: 3.1.10
version: 3.1.10 version: 3.1.10
electron: electron:
specifier: 38.7.1 specifier: 38.7.2
version: 38.7.1 version: 38.7.2
electron-debug: electron-debug:
specifier: 4.1.0 specifier: 4.1.0
version: 4.1.0 version: 4.1.0
@ -840,7 +840,7 @@ importers:
version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
vitest: vitest:
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
packages/ckeditor5: packages/ckeditor5:
dependencies: dependencies:
@ -931,7 +931,7 @@ importers:
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio: webdriverio:
specifier: 9.20.1 specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@ -991,7 +991,7 @@ importers:
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio: webdriverio:
specifier: 9.20.1 specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@ -1051,7 +1051,7 @@ importers:
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio: webdriverio:
specifier: 9.20.1 specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@ -1061,6 +1061,9 @@ importers:
'@ckeditor/ckeditor5-icons': '@ckeditor/ckeditor5-icons':
specifier: 47.2.0 specifier: 47.2.0
version: 47.2.0 version: 47.2.0
mathlive:
specifier: 0.108.2
version: 0.108.2
devDependencies: devDependencies:
'@ckeditor/ckeditor5-dev-build-tools': '@ckeditor/ckeditor5-dev-build-tools':
specifier: 43.1.0 specifier: 43.1.0
@ -1118,7 +1121,7 @@ importers:
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio: webdriverio:
specifier: 9.20.1 specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@ -1185,7 +1188,7 @@ importers:
version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) version: 2.0.0(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
vitest: vitest:
specifier: 4.0.14 specifier: 4.0.14
version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) version: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio: webdriverio:
specifier: 9.20.1 specifier: 9.20.1
version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) version: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@ -2123,6 +2126,10 @@ packages:
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
engines: {node: '>=0.1.90'} engines: {node: '>=0.1.90'}
'@cortex-js/compute-engine@0.30.2':
resolution: {integrity: sha512-Zx+iisk9WWdbxjm8EYsneIBszvjfUs7BHNwf1jBtSINIgfWGpHrTTq9vW0J59iGCFt6bOFxbmWyxNMRSmksHMA==}
engines: {node: '>=21.7.3', npm: '>=10.5.0'}
'@cspotcode/source-map-support@0.8.1': '@cspotcode/source-map-support@0.8.1':
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -2336,11 +2343,11 @@ packages:
engines: {node: '>=14.14'} engines: {node: '>=14.14'}
hasBin: true hasBin: true
'@emnapi/core@1.7.0': '@emnapi/core@1.7.1':
resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==}
'@emnapi/runtime@1.7.0': '@emnapi/runtime@1.7.1':
resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==} resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==}
'@emnapi/wasi-threads@1.1.0': '@emnapi/wasi-threads@1.1.0':
resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==}
@ -5448,6 +5455,9 @@ packages:
'@types/node@20.19.24': '@types/node@20.19.24':
resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==} resolution: {integrity: sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==}
'@types/node@20.19.25':
resolution: {integrity: sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==}
'@types/node@22.15.21': '@types/node@22.15.21':
resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==} resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==}
@ -5463,6 +5473,9 @@ packages:
'@types/node@22.18.8': '@types/node@22.18.8':
resolution: {integrity: sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==} resolution: {integrity: sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==}
'@types/node@22.19.1':
resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==}
'@types/node@24.10.1': '@types/node@24.10.1':
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
@ -6879,6 +6892,10 @@ packages:
compare-versions@6.1.1: compare-versions@6.1.1:
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
complex-esm@2.1.1-esm1:
resolution: {integrity: sha512-IShBEWHILB9s7MnfyevqNGxV0A1cfcSnewL/4uPFiSxkcQL4Mm3FxJ0pXMtCXuWLjYz3lRRyk6OfkeDZcjD6nw==}
engines: {node: '>=16.14.2', npm: '>=8.5.0'}
component-emitter@1.3.1: component-emitter@1.3.1:
resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
@ -7242,6 +7259,9 @@ packages:
csstype@3.1.3: csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
custom-event@1.0.1: custom-event@1.0.1:
resolution: {integrity: sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==} resolution: {integrity: sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==}
@ -7827,8 +7847,8 @@ packages:
resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
electron@38.7.1: electron@38.7.2:
resolution: {integrity: sha512-mdFVpL80nZvIvajtl1Xz+2Q/a9tFGVnPO0YW/N+MqQUyZG8D9r3wrWoaEVBXTc1jI+Vkg77Eqqwh5FLiaYRI+A==} resolution: {integrity: sha512-BcjR0IHqp3uv4ytVQwW2/9zAWo17Rjwrydn6RS+g+vqhpcPTzmBHDCHKaEcqheSl/7zzKPgFZdvT21BoSfrxRQ==}
engines: {node: '>= 12.20.55'} engines: {node: '>= 12.20.55'}
hasBin: true hasBin: true
@ -8807,8 +8827,8 @@ packages:
engines: {node: '>=0.4.7'} engines: {node: '>=0.4.7'}
hasBin: true hasBin: true
happy-dom@20.0.10: happy-dom@20.0.11:
resolution: {integrity: sha512-6umCCHcjQrhP5oXhrHQQvLB0bwb1UzHAHdsXy+FjtKoYjUhmNZsQL8NivwM1vDvNEChJabVrUYxUnp/ZdYmy2g==} resolution: {integrity: sha512-QsCdAUHAmiDeKeaNojb1OHOPF7NjcWPBR7obdu3NwH2a/oyQaLg5d0aaCy/9My6CdPChYF07dvz5chaXBGaD4g==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
has-bigints@1.1.0: has-bigints@1.1.0:
@ -10192,6 +10212,9 @@ packages:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
mathlive@0.108.2:
resolution: {integrity: sha512-GIZkfprGTxrbHckOvwo92ZmOOxdD018BHDzlrEwYUU+pzR5KabhqI1s43lxe/vqXdF5RLiQKgDcuk5jxEjhkYg==}
mathml-tag-names@2.1.3: mathml-tag-names@2.1.3:
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
@ -15623,6 +15646,8 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0 '@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-upload': 47.2.0 '@ckeditor/ckeditor5-upload': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-ai@47.2.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)': '@ckeditor/ckeditor5-ai@47.2.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)':
dependencies: dependencies:
@ -15769,6 +15794,8 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0 '@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)': '@ckeditor/ckeditor5-code-block@47.2.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)':
dependencies: dependencies:
@ -15833,8 +15860,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
'@ckeditor/ckeditor5-watchdog': 47.2.0 '@ckeditor/ckeditor5-watchdog': 47.2.0
es-toolkit: 1.39.5 es-toolkit: 1.39.5
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)': '@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)':
dependencies: dependencies:
@ -16029,6 +16054,8 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
es-toolkit: 1.39.5 es-toolkit: 1.39.5
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-editor-multi-root@47.2.0': '@ckeditor/ckeditor5-editor-multi-root@47.2.0':
dependencies: dependencies:
@ -16051,6 +16078,8 @@ snapshots:
'@ckeditor/ckeditor5-table': 47.2.0 '@ckeditor/ckeditor5-table': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) ckeditor5: 47.2.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41)
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-emoji@47.2.0': '@ckeditor/ckeditor5-emoji@47.2.0':
dependencies: dependencies:
@ -16076,8 +16105,6 @@ snapshots:
'@ckeditor/ckeditor5-core': 47.2.0 '@ckeditor/ckeditor5-core': 47.2.0
'@ckeditor/ckeditor5-engine': 47.2.0 '@ckeditor/ckeditor5-engine': 47.2.0
'@ckeditor/ckeditor5-utils': 47.2.0 '@ckeditor/ckeditor5-utils': 47.2.0
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-essentials@47.2.0': '@ckeditor/ckeditor5-essentials@47.2.0':
dependencies: dependencies:
@ -16941,6 +16968,11 @@ snapshots:
'@colors/colors@1.5.0': {} '@colors/colors@1.5.0': {}
'@cortex-js/compute-engine@0.30.2':
dependencies:
complex-esm: 2.1.1-esm1
decimal.js: 10.6.0
'@cspotcode/source-map-support@0.8.1': '@cspotcode/source-map-support@0.8.1':
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.9 '@jridgewell/trace-mapping': 0.3.9
@ -17381,9 +17413,9 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@electron/remote@2.1.3(electron@38.7.1)': '@electron/remote@2.1.3(electron@38.7.2)':
dependencies: dependencies:
electron: 38.7.1 electron: 38.7.2
'@electron/universal@2.0.2': '@electron/universal@2.0.2':
dependencies: dependencies:
@ -17407,13 +17439,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@emnapi/core@1.7.0': '@emnapi/core@1.7.1':
dependencies: dependencies:
'@emnapi/wasi-threads': 1.1.0 '@emnapi/wasi-threads': 1.1.0
tslib: 2.8.1 tslib: 2.8.1
optional: true optional: true
'@emnapi/runtime@1.7.0': '@emnapi/runtime@1.7.1':
dependencies: dependencies:
tslib: 2.8.1 tslib: 2.8.1
optional: true optional: true
@ -18122,7 +18154,7 @@ snapshots:
'@inquirer/figures': 1.0.13 '@inquirer/figures': 1.0.13
'@inquirer/type': 2.0.0 '@inquirer/type': 2.0.0
'@types/mute-stream': 0.0.4 '@types/mute-stream': 0.0.4
'@types/node': 22.18.13 '@types/node': 22.19.1
'@types/wrap-ansi': 3.0.0 '@types/wrap-ansi': 3.0.0
ansi-escapes: 4.3.2 ansi-escapes: 4.3.2
cli-width: 4.1.0 cli-width: 4.1.0
@ -18700,8 +18732,8 @@ snapshots:
'@napi-rs/wasm-runtime@1.0.7': '@napi-rs/wasm-runtime@1.0.7':
dependencies: dependencies:
'@emnapi/core': 1.7.0 '@emnapi/core': 1.7.1
'@emnapi/runtime': 1.7.0 '@emnapi/runtime': 1.7.1
'@tybys/wasm-util': 0.10.1 '@tybys/wasm-util': 0.10.1
optional: true optional: true
@ -20706,7 +20738,7 @@ snapshots:
'@types/mute-stream@0.0.4': '@types/mute-stream@0.0.4':
dependencies: dependencies:
'@types/node': 24.10.1 '@types/node': 22.19.1
'@types/node-forge@1.3.14': '@types/node-forge@1.3.14':
dependencies: dependencies:
@ -20718,6 +20750,10 @@ snapshots:
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
'@types/node@20.19.25':
dependencies:
undici-types: 6.21.0
'@types/node@22.15.21': '@types/node@22.15.21':
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
@ -20738,6 +20774,10 @@ snapshots:
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
'@types/node@22.19.1':
dependencies:
undici-types: 6.21.0
'@types/node@24.10.1': '@types/node@24.10.1':
dependencies: dependencies:
undici-types: 7.16.0 undici-types: 7.16.0
@ -20761,7 +20801,7 @@ snapshots:
'@types/react@19.1.7': '@types/react@19.1.7':
dependencies: dependencies:
csstype: 3.1.3 csstype: 3.2.3
optional: true optional: true
'@types/readdir-glob@1.1.5': '@types/readdir-glob@1.1.5':
@ -20887,7 +20927,7 @@ snapshots:
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
dependencies: dependencies:
'@types/node': 24.10.1 '@types/node': 22.18.13
optional: true optional: true
'@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': '@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)':
@ -21117,7 +21157,7 @@ snapshots:
'@vitest/browser-webdriverio@4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))': '@vitest/browser-webdriverio@4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))':
dependencies: dependencies:
'@vitest/browser': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14) '@vitest/browser': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
webdriverio: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) webdriverio: 9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
@ -21134,7 +21174,7 @@ snapshots:
pngjs: 7.0.0 pngjs: 7.0.0
sirv: 3.0.2 sirv: 3.0.2
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
@ -21153,7 +21193,7 @@ snapshots:
magicast: 0.5.1 magicast: 0.5.1
obug: 2.1.1 obug: 2.1.1
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -21170,7 +21210,7 @@ snapshots:
obug: 2.1.1 obug: 2.1.1
std-env: 3.10.0 std-env: 3.10.0
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
optionalDependencies: optionalDependencies:
'@vitest/browser': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14) '@vitest/browser': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)
transitivePeerDependencies: transitivePeerDependencies:
@ -21220,7 +21260,7 @@ snapshots:
sirv: 3.0.2 sirv: 3.0.2
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vitest: 4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
'@vitest/utils@4.0.14': '@vitest/utils@4.0.14':
dependencies: dependencies:
@ -22577,6 +22617,8 @@ snapshots:
compare-versions@6.1.1: {} compare-versions@6.1.1: {}
complex-esm@2.1.1-esm1: {}
component-emitter@1.3.1: {} component-emitter@1.3.1: {}
compress-commons@6.0.2: compress-commons@6.0.2:
@ -23086,6 +23128,9 @@ snapshots:
csstype@3.1.3: {} csstype@3.1.3: {}
csstype@3.2.3:
optional: true
custom-event@1.0.1: {} custom-event@1.0.1: {}
cytoscape-cose-bilkent@4.1.0(cytoscape@3.31.2): cytoscape-cose-bilkent@4.1.0(cytoscape@3.31.2):
@ -23360,8 +23405,7 @@ snapshots:
decimal.js@10.5.0: {} decimal.js@10.5.0: {}
decimal.js@10.6.0: decimal.js@10.6.0: {}
optional: true
decko@1.2.0: {} decko@1.2.0: {}
@ -23747,7 +23791,7 @@ snapshots:
- supports-color - supports-color
optional: true optional: true
electron@38.7.1: electron@38.7.2:
dependencies: dependencies:
'@electron/get': 2.0.3 '@electron/get': 2.0.3
'@types/node': 22.18.13 '@types/node': 22.18.13
@ -25186,9 +25230,9 @@ snapshots:
optionalDependencies: optionalDependencies:
uglify-js: 3.19.3 uglify-js: 3.19.3
happy-dom@20.0.10: happy-dom@20.0.11:
dependencies: dependencies:
'@types/node': 20.19.24 '@types/node': 20.19.25
'@types/whatwg-mimetype': 3.0.2 '@types/whatwg-mimetype': 3.0.2
whatwg-mimetype: 3.0.0 whatwg-mimetype: 3.0.0
@ -26780,6 +26824,10 @@ snapshots:
math-intrinsics@1.1.0: {} math-intrinsics@1.1.0: {}
mathlive@0.108.2:
dependencies:
'@cortex-js/compute-engine': 0.30.2
mathml-tag-names@2.1.3: {} mathml-tag-names@2.1.3: {}
mdast-util-find-and-replace@3.0.2: mdast-util-find-and-replace@3.0.2:
@ -31767,7 +31815,7 @@ snapshots:
tsx: 4.20.6 tsx: 4.20.6
yaml: 2.8.1 yaml: 2.8.1
vitest@4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.10)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): vitest@4.0.14(@opentelemetry/api@1.9.0)(@types/node@24.10.1)(@vitest/browser-webdriverio@4.0.14)(@vitest/ui@4.0.14)(happy-dom@20.0.11)(jiti@2.6.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1):
dependencies: dependencies:
'@vitest/expect': 4.0.14 '@vitest/expect': 4.0.14
'@vitest/mocker': 4.0.14(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitest/mocker': 4.0.14(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))
@ -31794,7 +31842,7 @@ snapshots:
'@types/node': 24.10.1 '@types/node': 24.10.1
'@vitest/browser-webdriverio': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)) '@vitest/browser-webdriverio': 4.0.14(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.10.1)(typescript@5.9.3))(utf-8-validate@6.0.5)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(vitest@4.0.14)(webdriverio@9.20.1(bufferutil@4.0.9)(utf-8-validate@6.0.5))
'@vitest/ui': 4.0.14(vitest@4.0.14) '@vitest/ui': 4.0.14(vitest@4.0.14)
happy-dom: 20.0.10 happy-dom: 20.0.11
jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)
transitivePeerDependencies: transitivePeerDependencies:
- jiti - jiti