From c6d9b26643ec896b49f3d5639805a5c5492dd73f Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 16 Dec 2025 15:57:30 -0300 Subject: [PATCH 001/125] feat: add function for mapping doc paragraphs by id --- .../src/extensions/diffing/computeDiff.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 packages/super-editor/src/extensions/diffing/computeDiff.js diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js new file mode 100644 index 0000000000..3cccc3af85 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/computeDiff.js @@ -0,0 +1,18 @@ +import { Node } from 'prosemirror-model'; +import { v4 as uuidv4 } from 'uuid'; + +/** + * Collects paragraphs from a ProseMirror document and returns them by paragraph ID. + * @param {Node} pmDoc - ProseMirror document to scan. + * @returns {Map} Map keyed by paraId containing paragraph nodes and positions. + */ +export function extractParagraphs(pmDoc) { + const paragraphMap = new Map(); + pmDoc.descendants((node, pos) => { + if (node.type.name === 'paragraph') { + paragraphMap.set(node.attrs?.paraId ?? uuidv4(), { node, pos }); + return false; // Do not descend further + } + }); + return paragraphMap; +} From 57beb160b5f47a87923f45ab69df367dfd9cdcbc Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 16 Dec 2025 15:58:04 -0300 Subject: [PATCH 002/125] feat: add function for flattening paragraph text but keep track of positions --- .../src/extensions/diffing/computeDiff.js | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js index 3cccc3af85..4394204d9a 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.js @@ -16,3 +16,56 @@ export function extractParagraphs(pmDoc) { }); return paragraphMap; } + +/** + * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. + * @param {Node} paragraph - Paragraph node to flatten. + * @param {number} [paragraphPos=0] - Position of the paragraph in the document. + * @returns {{text: string, resolvePosition: (index: number) => number|null}} Concatenated text and position resolver. + */ +export function getTextContent(paragraph, paragraphPos = 0) { + let text = ''; + const segments = []; + + paragraph.nodesBetween( + 0, + paragraph.content.size, + (node, pos) => { + let nodeText = ''; + + if (node.isText) { + nodeText = node.text; + } else if (node.isLeaf && node.type.spec.leafText) { + nodeText = node.type.spec.leafText(node); + } + + if (!nodeText) { + return; + } + + const start = text.length; + const end = start + nodeText.length; + + segments.push({ start, end, pos }); + text += nodeText; + }, + 0, + ); + + const resolvePosition = (index) => { + if (index < 0 || index > text.length) { + return null; + } + + for (const segment of segments) { + if (index >= segment.start && index < segment.end) { + return paragraphPos + 1 + segment.pos + (index - segment.start); + } + } + + // If index points to the end of the string, return the paragraph end + return paragraphPos + 1 + paragraph.content.size; + }; + + return { text, resolvePosition }; +} From e6968be2ec1bab3ea2b027ab0fd0024961ceb6e1 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 16 Dec 2025 16:00:49 -0300 Subject: [PATCH 003/125] feat: add function for calculating text diffs using LCS --- .../src/extensions/diffing/computeDiff.js | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js index 4394204d9a..b9cc70d443 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.js @@ -69,3 +69,85 @@ export function getTextContent(paragraph, paragraphPos = 0) { return { text, resolvePosition }; } + +/** + * Computes text-level additions and deletions between two strings using LCS, mapping back to document positions. + * @param {string} oldText - Source text. + * @param {string} newText - Target text. + * @param {(index: number) => number|null} positionResolver - Maps string indices to document positions. + * @returns {Array} List of addition/deletion ranges with document positions and text content. + */ +export function getLCSdiff(oldText, newText, positionResolver) { + const oldLen = oldText.length; + const newLen = newText.length; + + // Build LCS length table + const lcs = Array.from({ length: oldLen + 1 }, () => Array(newLen + 1).fill(0)); + for (let i = oldLen - 1; i >= 0; i -= 1) { + for (let j = newLen - 1; j >= 0; j -= 1) { + if (oldText[i] === newText[j]) { + lcs[i][j] = lcs[i + 1][j + 1] + 1; + } else { + lcs[i][j] = Math.max(lcs[i + 1][j], lcs[i][j + 1]); + } + } + } + + // Reconstruct the LCS path to figure out unmatched segments + const matches = []; + for (let i = 0, j = 0; i < oldLen && j < newLen; ) { + if (oldText[i] === newText[j]) { + matches.push({ oldIdx: i, newIdx: j }); + i += 1; + j += 1; + } else if (lcs[i + 1][j] >= lcs[i][j + 1]) { + i += 1; + } else { + j += 1; + } + } + + const diffs = []; + let prevOld = 0; + let prevNew = 0; + + for (const { oldIdx, newIdx } of matches) { + if (oldIdx > prevOld) { + diffs.push({ + type: 'deletion', + startIdx: positionResolver(prevOld), + endIdx: positionResolver(oldIdx), + text: oldText.slice(prevOld, oldIdx), + }); + } + if (newIdx > prevNew) { + diffs.push({ + type: 'addition', + startIdx: positionResolver(prevOld), + endIdx: positionResolver(prevOld), + text: newText.slice(prevNew, newIdx), + }); + } + prevOld = oldIdx + 1; + prevNew = newIdx + 1; + } + + if (prevOld < oldLen) { + diffs.push({ + type: 'deletion', + startIdx: positionResolver(prevOld), + endIdx: positionResolver(oldLen - 1), + text: oldText.slice(prevOld), + }); + } + if (prevNew < newLen) { + diffs.push({ + type: 'addition', + startIdx: positionResolver(prevOld), + endIdx: positionResolver(prevOld), + text: newText.slice(prevNew), + }); + } + + return diffs; +} From 467ce85d8ebd7a02415fc058683720abc2cf2f3d Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 16 Dec 2025 16:01:34 -0300 Subject: [PATCH 004/125] feat: add function for calculating paragraph-level diffing --- .../src/extensions/diffing/computeDiff.js | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js index b9cc70d443..9c81559441 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.js @@ -1,6 +1,60 @@ import { Node } from 'prosemirror-model'; import { v4 as uuidv4 } from 'uuid'; +/** + * Computes paragraph-level diffs between two ProseMirror documents, returning inserts, deletes and text modifications. + * @param {Node} oldPmDoc - The previous ProseMirror document. + * @param {Node} newPmDoc - The updated ProseMirror document. + * @returns {Array} List of diff objects describing added, deleted or modified paragraphs. + */ +export function computeDiff(oldPmDoc, newPmDoc) { + const diffs = []; + + // 1. Extract all paragraphs from old document and create a map using their IDs + const oldParagraphsMap = extractParagraphs(oldPmDoc); + + // 2. Extract all paragraphs from new document and create a map using their IDs + const newParagraphsMap = extractParagraphs(newPmDoc); + + // 3. Compare paragraphs in old and new documents + let insertPos = 0; + newParagraphsMap.forEach((newPara, paraId) => { + const oldPara = oldParagraphsMap.get(paraId); + if (!oldPara) { + diffs.push({ + type: 'added', + paraId, + node: newPara.node, + text: newPara.node.textContent, + pos: insertPos, + }); + return; + } else if (oldPara.node.textContent !== newPara.node.textContent) { + const oldTextContent = getTextContent(oldPara.node, oldPara.pos); + const newTextContent = getTextContent(newPara.node, newPara.pos); + const textDiffs = getLCSdiff(oldPara.node.textContent, newPara.node.textContent, oldTextContent.resolvePosition); + diffs.push({ + type: 'modified', + paraId, + oldText: oldTextContent.text, + newText: newTextContent.text, + pos: oldPara.pos, + textDiffs, + }); + } + insertPos = oldPara.pos + oldPara.node.nodeSize; + }); + + // 4. Identify deleted paragraphs + oldParagraphsMap.forEach((oldPara, paraId) => { + if (!newParagraphsMap.has(paraId)) { + diffs.push({ type: 'deleted', paraId, node: oldPara.node, pos: oldPara.pos }); + } + }); + + return diffs; +} + /** * Collects paragraphs from a ProseMirror document and returns them by paragraph ID. * @param {Node} pmDoc - ProseMirror document to scan. From 44bedd43803a3478eaa16b59b8819137ad1a56fd Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 17 Dec 2025 17:34:24 -0300 Subject: [PATCH 005/125] feat: add diffing extension --- .../src/extensions/diffing/diffing.js | 18 ++++++++++++++++++ .../src/extensions/diffing/index.js | 1 + packages/super-editor/src/extensions/index.js | 2 ++ 3 files changed, 21 insertions(+) create mode 100644 packages/super-editor/src/extensions/diffing/diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/index.js diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js new file mode 100644 index 0000000000..1ebfdc3b0e --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -0,0 +1,18 @@ +// @ts-nocheck +import { Extension } from '@core/Extension.js'; +import { computeDiff } from './computeDiff.js'; + +export const Diffing = Extension.create({ + name: 'documentDiffing', + + addCommands() { + return { + compareDocuments: + (updatedDocument) => + ({ state }) => { + const diffs = computeDiff(state.doc, updatedDocument); + return diffs; + }, + }; + }, +}); diff --git a/packages/super-editor/src/extensions/diffing/index.js b/packages/super-editor/src/extensions/diffing/index.js new file mode 100644 index 0000000000..0a3aee23b8 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/index.js @@ -0,0 +1 @@ +export { Diffing } from './diffing.js'; diff --git a/packages/super-editor/src/extensions/index.js b/packages/super-editor/src/extensions/index.js index a501692377..a7fac28bf0 100644 --- a/packages/super-editor/src/extensions/index.js +++ b/packages/super-editor/src/extensions/index.js @@ -88,6 +88,7 @@ import { PermEnd, PermEndBlock } from './perm-end/index.js'; // Helpers import { trackChangesHelpers } from './track-changes/index.js'; +import { Diffing } from './diffing/index.js'; const getRichTextExtensions = () => { return [ @@ -284,6 +285,7 @@ export { trackChangesHelpers, getStarterExtensions, getRichTextExtensions, + Diffing, AiMark, AiAnimationMark, AiLoaderNode, From 96d2e3bd31aa76221b984f3d664f4cc7e6f174d2 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 17 Dec 2025 17:34:41 -0300 Subject: [PATCH 006/125] test: add diffing tests --- .../extensions/diffing/computeDiff.test.js | 225 ++++++++++++++++++ .../src/tests/data/diff_after.docx | Bin 0 -> 16585 bytes .../src/tests/data/diff_before.docx | Bin 0 -> 14583 bytes .../export/export-helpers/export-helpers.js | 2 +- 4 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 packages/super-editor/src/extensions/diffing/computeDiff.test.js create mode 100644 packages/super-editor/src/tests/data/diff_after.docx create mode 100644 packages/super-editor/src/tests/data/diff_before.docx diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js new file mode 100644 index 0000000000..6bdf169fa9 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -0,0 +1,225 @@ +import { describe, it, expect } from 'vitest'; +import { getTextContent, computeDiff, extractParagraphs, getLCSdiff } from './computeDiff'; + +import { Editor } from '@core/Editor.js'; +import { getStarterExtensions } from '@extensions/index.js'; +import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers.js'; + +export const getDocument = async (name) => { + const buffer = await getTestDataAsBuffer(name); + const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); + + const editor = new Editor({ + isHeadless: true, + extensions: getStarterExtensions(), + documentId: 'test-doc', + content: docx, + mode: 'docx', + media, + mediaFiles, + fonts, + annotations: true, + }); + + return editor.state.doc; +}; + +describe('Diff', () => { + it('Compares two documents and identifies added, deleted, and modified paragraphs', async () => { + const docBefore = await getDocument('diff_before.docx'); + const docAfter = await getDocument('diff_after.docx'); + + const diffs = computeDiff(docBefore, docAfter); + console.log(JSON.stringify(diffs, null, 2)); + }); +}); + +describe('extractParagraphs', () => { + it('collects all paragraph nodes keyed by their paraId', () => { + const firstParagraph = { + type: { name: 'paragraph' }, + attrs: { paraId: 'para-1' }, + textContent: 'First paragraph', + }; + const nonParagraph = { + type: { name: 'heading' }, + attrs: { paraId: 'heading-1' }, + }; + const secondParagraph = { + type: { name: 'paragraph' }, + attrs: { paraId: 'para-2' }, + textContent: 'Second paragraph', + }; + const pmDoc = { + descendants: (callback) => { + callback(firstParagraph, 0); + callback(nonParagraph, 5); + callback(secondParagraph, 10); + }, + }; + + const paragraphs = extractParagraphs(pmDoc); + + expect(paragraphs.size).toBe(2); + expect(paragraphs.get('para-1')).toEqual({ node: firstParagraph, pos: 0 }); + expect(paragraphs.get('para-2')).toEqual({ node: secondParagraph, pos: 10 }); + }); + + it('generates unique IDs when paragraph nodes are missing paraId', () => { + const firstParagraph = { + type: { name: 'paragraph' }, + attrs: {}, + textContent: 'Anonymous first', + }; + const secondParagraph = { + type: { name: 'paragraph' }, + attrs: undefined, + textContent: 'Anonymous second', + }; + const pmDoc = { + descendants: (callback) => { + callback(firstParagraph, 2); + callback(secondParagraph, 8); + }, + }; + + const paragraphs = extractParagraphs(pmDoc); + const entries = [...paragraphs.entries()]; + const firstEntry = entries.find(([, value]) => value.node === firstParagraph); + const secondEntry = entries.find(([, value]) => value.node === secondParagraph); + + expect(paragraphs.size).toBe(2); + expect(firstEntry?.[0]).toBeTruthy(); + expect(secondEntry?.[0]).toBeTruthy(); + expect(firstEntry?.[0]).not.toBe(secondEntry?.[0]); + expect(firstEntry?.[1].pos).toBe(2); + expect(secondEntry?.[1].pos).toBe(8); + }); +}); + +describe('getTextContent', () => { + it('Handles basic text nodes', () => { + const mockParagraph = { + content: { + size: 5, + }, + nodesBetween: (from, to, callback) => { + callback({ isText: true, text: 'Hello' }, 0); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('Hello'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(4)).toBe(5); + }); + + it('Handles leaf nodes with leafText', () => { + const mockParagraph = { + content: { + size: 4, + }, + nodesBetween: (from, to, callback) => { + callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 0); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('Leaf'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(3)).toBe(4); + }); + + it('Handles mixed content', () => { + const mockParagraph = { + content: { + size: 9, + }, + nodesBetween: (from, to, callback) => { + callback({ isText: true, text: 'Hello' }, 0); + callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 5); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('HelloLeaf'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(5)).toBe(6); + expect(result.resolvePosition(9)).toBe(10); + }); + + it('Handles empty content', () => { + const mockParagraph = { + content: { + size: 0, + }, + nodesBetween: () => {}, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe(''); + expect(result.resolvePosition(0)).toBe(1); + }); + + it('Handles nested nodes', () => { + const mockParagraph = { + content: { + size: 6, + }, + nodesBetween: (from, to, callback) => { + callback({ isText: true, text: 'Nested' }, 0); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('Nested'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(6)).toBe(7); + }); +}); + +describe('getLCSdiff', () => { + it('returns an empty diff list when both strings are identical', () => { + const resolver = () => 0; + + const diffs = getLCSdiff('unchanged', 'unchanged', resolver); + + expect(diffs).toEqual([]); + }); + + it('detects text insertions and maps them to resolver positions', () => { + const resolver = (index) => index + 10; + + const diffs = getLCSdiff('abc', 'abXc', resolver); + + expect(diffs).toEqual([ + { + type: 'addition', + startIdx: 12, + endIdx: 12, + text: 'X', + }, + ]); + }); + + it('detects deletions and additions in the same diff sequence', () => { + const resolver = (index) => index + 5; + + const diffs = getLCSdiff('abcd', 'abXYd', resolver); + + expect(diffs).toEqual([ + { + type: 'deletion', + startIdx: 7, + endIdx: 8, + text: 'c', + }, + { + type: 'addition', + startIdx: 7, + endIdx: 7, + text: 'XY', + }, + ]); + }); +}); diff --git a/packages/super-editor/src/tests/data/diff_after.docx b/packages/super-editor/src/tests/data/diff_after.docx new file mode 100644 index 0000000000000000000000000000000000000000..b04b965837ddff5c026353bd4fb9c1f11706156b GIT binary patch literal 16585 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 EFHo!ljQ{`u literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_before.docx b/packages/super-editor/src/tests/data/diff_before.docx new file mode 100644 index 0000000000000000000000000000000000000000..8cae247f962363005ecacefbc8b179626fb58ec9 GIT binary patch literal 14583 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/export/export-helpers/export-helpers.js b/packages/super-editor/src/tests/export/export-helpers/export-helpers.js index a2cdc35a5d..c6c83cfa5f 100644 --- a/packages/super-editor/src/tests/export/export-helpers/export-helpers.js +++ b/packages/super-editor/src/tests/export/export-helpers/export-helpers.js @@ -37,7 +37,7 @@ export const getTextFromNode = (node) => { * @param {string} name The name of the file in the test data folder * @returns {Promise} The test data as abuffer */ -const getTestDataAsBuffer = async (name) => { +export const getTestDataAsBuffer = async (name) => { try { const basePath = join(__dirname, '../../data', name); return await readFile(basePath); From 9f60c30ec6ac2f95af905dfcf2efd90bf491f335 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 18 Dec 2025 16:28:47 -0300 Subject: [PATCH 007/125] refactor: switch LCS algorith to Myers for performance --- .../src/extensions/diffing/computeDiff.js | 216 ++++++++++++++---- .../extensions/diffing/computeDiff.test.js | 10 +- 2 files changed, 171 insertions(+), 55 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js index 9c81559441..606010d29b 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.js @@ -32,7 +32,7 @@ export function computeDiff(oldPmDoc, newPmDoc) { } else if (oldPara.node.textContent !== newPara.node.textContent) { const oldTextContent = getTextContent(oldPara.node, oldPara.pos); const newTextContent = getTextContent(newPara.node, newPara.pos); - const textDiffs = getLCSdiff(oldPara.node.textContent, newPara.node.textContent, oldTextContent.resolvePosition); + const textDiffs = getTextDiff(oldPara.node.textContent, newPara.node.textContent, oldTextContent.resolvePosition); diffs.push({ type: 'modified', paraId, @@ -125,83 +125,199 @@ export function getTextContent(paragraph, paragraphPos = 0) { } /** - * Computes text-level additions and deletions between two strings using LCS, mapping back to document positions. + * Computes text-level additions and deletions between two strings using Myers diff algorithm, mapping back to document positions. * @param {string} oldText - Source text. * @param {string} newText - Target text. * @param {(index: number) => number|null} positionResolver - Maps string indices to document positions. * @returns {Array} List of addition/deletion ranges with document positions and text content. */ -export function getLCSdiff(oldText, newText, positionResolver) { +export function getTextDiff(oldText, newText, positionResolver) { const oldLen = oldText.length; const newLen = newText.length; - // Build LCS length table - const lcs = Array.from({ length: oldLen + 1 }, () => Array(newLen + 1).fill(0)); - for (let i = oldLen - 1; i >= 0; i -= 1) { - for (let j = newLen - 1; j >= 0; j -= 1) { - if (oldText[i] === newText[j]) { - lcs[i][j] = lcs[i + 1][j + 1] + 1; + if (oldLen === 0 && newLen === 0) { + return []; + } + + // Myers diff bookkeeping: +2 padding keeps diagonal lookups in bounds. + const max = oldLen + newLen; + const size = 2 * max + 3; + const offset = max + 1; + const v = new Array(size).fill(-1); + v[offset + 1] = 0; + + const trace = []; + let foundPath = false; + + for (let d = 0; d <= max && !foundPath; d += 1) { + for (let k = -d; k <= d; k += 2) { + const index = offset + k; + let x; + + if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { + x = v[index + 1]; } else { - lcs[i][j] = Math.max(lcs[i + 1][j], lcs[i][j + 1]); + x = v[index - 1] + 1; + } + + let y = x - k; + while (x < oldLen && y < newLen && oldText[x] === newText[y]) { + x += 1; + y += 1; + } + + v[index] = x; + + if (x >= oldLen && y >= newLen) { + foundPath = true; + break; } } + trace.push(v.slice()); } - // Reconstruct the LCS path to figure out unmatched segments - const matches = []; - for (let i = 0, j = 0; i < oldLen && j < newLen; ) { - if (oldText[i] === newText[j]) { - matches.push({ oldIdx: i, newIdx: j }); - i += 1; - j += 1; - } else if (lcs[i + 1][j] >= lcs[i][j + 1]) { - i += 1; + const operations = backtrackMyers(trace, oldLen, newLen, offset); + return buildDiffFromOperations(operations, oldText, newText, positionResolver); +} + +/** + * Reconstructs the shortest edit script by walking the previously recorded V vectors. + * + * @param {Array} trace - Snapshot of diagonal furthest-reaching points per edit distance. + * @param {number} oldLen - Length of the original string. + * @param {number} newLen - Length of the target string. + * @param {number} offset - Offset applied to diagonal indexes to keep array lookups positive. + * @returns {Array<'equal'|'delete'|'insert'>} Concrete step-by-step operations. + */ +function backtrackMyers(trace, oldLen, newLen, offset) { + const operations = []; + let x = oldLen; + let y = newLen; + + for (let d = trace.length - 1; d > 0; d -= 1) { + const v = trace[d - 1]; + const k = x - y; + const index = offset + k; + + let prevK; + if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { + prevK = k + 1; + } else { + prevK = k - 1; + } + + const prevIndex = offset + prevK; + const prevX = v[prevIndex]; + const prevY = prevX - prevK; + + while (x > prevX && y > prevY) { + x -= 1; + y -= 1; + operations.push('equal'); + } + + if (x === prevX) { + y -= 1; + operations.push('insert'); } else { - j += 1; + x -= 1; + operations.push('delete'); } } + while (x > 0 && y > 0) { + x -= 1; + y -= 1; + operations.push('equal'); + } + + while (x > 0) { + x -= 1; + operations.push('delete'); + } + + while (y > 0) { + y -= 1; + operations.push('insert'); + } + + return operations.reverse(); +} + +/** + * Groups edit operations into contiguous additions/deletions and maps them to document positions. + * + * @param {Array<'equal'|'delete'|'insert'>} operations - Raw operation list produced by the backtracked Myers path. + * @param {string} oldText - Source text. + * @param {string} newText - Target text. + * @param {(index: number) => number|null} positionResolver - Maps string indexes to ProseMirror positions. + * @returns {Array} Final diff payload matching the existing API surface. + */ +function buildDiffFromOperations(operations, oldText, newText, positionResolver) { const diffs = []; - let prevOld = 0; - let prevNew = 0; + let run = null; + let oldIdx = 0; + let newIdx = 0; + let insertionAnchor = 0; + + const flushRun = () => { + if (!run || run.text.length === 0) { + run = null; + return; + } - for (const { oldIdx, newIdx } of matches) { - if (oldIdx > prevOld) { + if (run.type === 'delete') { + const startIdx = positionResolver(run.startOldIdx); + const endIdx = positionResolver(run.endOldIdx); diffs.push({ type: 'deletion', - startIdx: positionResolver(prevOld), - endIdx: positionResolver(oldIdx), - text: oldText.slice(prevOld, oldIdx), + startIdx, + endIdx, + text: run.text, }); - } - if (newIdx > prevNew) { + } else if (run.type === 'insert') { + const startIdx = positionResolver(run.referenceOldIdx); + const endIdx = positionResolver(run.referenceOldIdx); diffs.push({ type: 'addition', - startIdx: positionResolver(prevOld), - endIdx: positionResolver(prevOld), - text: newText.slice(prevNew, newIdx), + startIdx, + endIdx, + text: run.text, }); } - prevOld = oldIdx + 1; - prevNew = newIdx + 1; - } - if (prevOld < oldLen) { - diffs.push({ - type: 'deletion', - startIdx: positionResolver(prevOld), - endIdx: positionResolver(oldLen - 1), - text: oldText.slice(prevOld), - }); - } - if (prevNew < newLen) { - diffs.push({ - type: 'addition', - startIdx: positionResolver(prevOld), - endIdx: positionResolver(prevOld), - text: newText.slice(prevNew), - }); + run = null; + }; + + for (const op of operations) { + if (op === 'equal') { + flushRun(); + oldIdx += 1; + newIdx += 1; + insertionAnchor = oldIdx; + continue; + } + + if (!run || run.type !== op) { + flushRun(); + if (op === 'delete') { + run = { type: 'delete', startOldIdx: oldIdx, endOldIdx: oldIdx, text: '' }; + } else if (op === 'insert') { + run = { type: 'insert', referenceOldIdx: insertionAnchor, text: '' }; + } + } + + if (op === 'delete') { + run.text += oldText[oldIdx]; + oldIdx += 1; + run.endOldIdx = oldIdx; + } else if (op === 'insert') { + run.text += newText[newIdx]; + newIdx += 1; + } } + flushRun(); + return diffs; } diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index 6bdf169fa9..a6da92a0be 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { getTextContent, computeDiff, extractParagraphs, getLCSdiff } from './computeDiff'; +import { getTextContent, computeDiff, extractParagraphs, getTextDiff } from './computeDiff'; import { Editor } from '@core/Editor.js'; import { getStarterExtensions } from '@extensions/index.js'; @@ -178,11 +178,11 @@ describe('getTextContent', () => { }); }); -describe('getLCSdiff', () => { +describe('getTextDiff', () => { it('returns an empty diff list when both strings are identical', () => { const resolver = () => 0; - const diffs = getLCSdiff('unchanged', 'unchanged', resolver); + const diffs = getTextDiff('unchanged', 'unchanged', resolver); expect(diffs).toEqual([]); }); @@ -190,7 +190,7 @@ describe('getLCSdiff', () => { it('detects text insertions and maps them to resolver positions', () => { const resolver = (index) => index + 10; - const diffs = getLCSdiff('abc', 'abXc', resolver); + const diffs = getTextDiff('abc', 'abXc', resolver); expect(diffs).toEqual([ { @@ -205,7 +205,7 @@ describe('getLCSdiff', () => { it('detects deletions and additions in the same diff sequence', () => { const resolver = (index) => index + 5; - const diffs = getLCSdiff('abcd', 'abXYd', resolver); + const diffs = getTextDiff('abcd', 'abXYd', resolver); expect(diffs).toEqual([ { From 710f38014a7c6d95f27f6486369b52fa8b7054a3 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 18 Dec 2025 18:13:00 -0300 Subject: [PATCH 008/125] refactor: code structure --- .../diffing/algorithm/myers-diff.js | 118 +++++++ .../diffing/algorithm/paragraph-diffing.js | 277 +++++++++++++++ .../algorithm/paragraph-diffing.test.js | 52 +++ .../diffing/algorithm/text-diffing.js | 102 ++++++ .../diffing/algorithm/text-diffing.test.js | 50 +++ .../src/extensions/diffing/computeDiff.js | 318 +----------------- .../extensions/diffing/computeDiff.test.js | 282 ++++++---------- .../src/extensions/diffing/utils.js | 69 ++++ .../src/extensions/diffing/utils.test.js | 141 ++++++++ .../src/tests/data/diff_after.docx | Bin 16585 -> 14739 bytes .../src/tests/data/diff_after2.docx | Bin 0 -> 13481 bytes .../src/tests/data/diff_before.docx | Bin 14583 -> 14281 bytes .../src/tests/data/diff_before2.docx | Bin 0 -> 13404 bytes 13 files changed, 911 insertions(+), 498 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/myers-diff.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js create mode 100644 packages/super-editor/src/extensions/diffing/utils.js create mode 100644 packages/super-editor/src/extensions/diffing/utils.test.js create mode 100644 packages/super-editor/src/tests/data/diff_after2.docx create mode 100644 packages/super-editor/src/tests/data/diff_before2.docx diff --git a/packages/super-editor/src/extensions/diffing/algorithm/myers-diff.js b/packages/super-editor/src/extensions/diffing/algorithm/myers-diff.js new file mode 100644 index 0000000000..6704d93a56 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/myers-diff.js @@ -0,0 +1,118 @@ +/** + * Computes a Myers diff operation list for arbitrary sequences. + * @param {Array|String} oldSeq + * @param {Array|String} newSeq + * @param {(a: any, b: any) => boolean} isEqual + * @returns {Array<'equal'|'insert'|'delete'>} + */ +export function myersDiff(oldSeq, newSeq, isEqual) { + const oldLen = oldSeq.length; + const newLen = newSeq.length; + + if (oldLen === 0 && newLen === 0) { + return []; + } + + // Myers diff bookkeeping: +2 padding keeps diagonal lookups in bounds. + const max = oldLen + newLen; + const size = 2 * max + 3; + const offset = max + 1; + const v = new Array(size).fill(-1); + v[offset + 1] = 0; + + const trace = []; + let foundPath = false; + + for (let d = 0; d <= max && !foundPath; d += 1) { + for (let k = -d; k <= d; k += 2) { + const index = offset + k; + let x; + + if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { + x = v[index + 1]; + } else { + x = v[index - 1] + 1; + } + + let y = x - k; + while (x < oldLen && y < newLen && isEqual(oldSeq[x], newSeq[y])) { + x += 1; + y += 1; + } + + v[index] = x; + + if (x >= oldLen && y >= newLen) { + foundPath = true; + break; + } + } + trace.push(v.slice()); + } + + return backtrackMyers(trace, oldLen, newLen, offset); +} + +/** + * Reconstructs the shortest edit script by walking the previously recorded V vectors. + * + * @param {Array} trace - Snapshot of diagonal furthest-reaching points per edit distance. + * @param {number} oldLen - Length of the original string. + * @param {number} newLen - Length of the target string. + * @param {number} offset - Offset applied to diagonal indexes to keep array lookups positive. + * @returns {Array<'equal'|'delete'|'insert'>} Concrete step-by-step operations. + */ +function backtrackMyers(trace, oldLen, newLen, offset) { + const operations = []; + let x = oldLen; + let y = newLen; + + for (let d = trace.length - 1; d > 0; d -= 1) { + const v = trace[d - 1]; + const k = x - y; + const index = offset + k; + + let prevK; + if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { + prevK = k + 1; + } else { + prevK = k - 1; + } + + const prevIndex = offset + prevK; + const prevX = v[prevIndex]; + const prevY = prevX - prevK; + + while (x > prevX && y > prevY) { + x -= 1; + y -= 1; + operations.push('equal'); + } + + if (x === prevX) { + y -= 1; + operations.push('insert'); + } else { + x -= 1; + operations.push('delete'); + } + } + + while (x > 0 && y > 0) { + x -= 1; + y -= 1; + operations.push('equal'); + } + + while (x > 0) { + x -= 1; + operations.push('delete'); + } + + while (y > 0) { + y -= 1; + operations.push('insert'); + } + + return operations.reverse(); +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js new file mode 100644 index 0000000000..7b3fb60113 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -0,0 +1,277 @@ +import { myersDiff } from './myers-diff.js'; +import { getTextDiff } from './text-diffing.js'; + +// Heuristics that prevent unrelated paragraphs from being paired as modifications. +const SIMILARITY_THRESHOLD = 0.65; +const MIN_LENGTH_FOR_SIMILARITY = 4; + +/** + * A paragraph addition diff emitted when new content is inserted. + * @typedef {Object} AddedParagraphDiff + * @property {'added'} type + * @property {Node} node reference to the ProseMirror node for consumers needing schema details + * @property {string} text textual contents of the inserted paragraph + * @property {number} pos document position where the paragraph was inserted + */ + +/** + * A paragraph deletion diff emitted when content is removed. + * @typedef {Object} DeletedParagraphDiff + * @property {'deleted'} type + * @property {Node} node reference to the original ProseMirror node + * @property {string} oldText text that was removed + * @property {number} pos starting document position of the original paragraph + */ + +/** + * A paragraph modification diff that carries inline text-level changes. + * @typedef {Object} ModifiedParagraphDiff + * @property {'modified'} type + * @property {string} oldText text before the edit + * @property {string} newText text after the edit + * @property {number} pos original document position for anchoring UI + * @property {Array} textDiffs granular inline diff data returned by `getTextDiff` + */ + +/** + * Combined type representing every diff payload produced by `diffParagraphs`. + * @typedef {AddedParagraphDiff|DeletedParagraphDiff|ModifiedParagraphDiff} ParagraphDiff + */ + +/** + * Runs a paragraph-level diff using Myers algorithm to align paragraphs that move, get edited, or are added/removed. + * The extra bookkeeping around the raw diff ensures that downstream consumers can map operations back to paragraph + * positions. + * @param {Array} oldParagraphs + * @param {Array} newParagraphs + * @returns {Array} + */ +export function diffParagraphs(oldParagraphs, newParagraphs) { + // Run Myers diff on the paragraph level to get a base set of operations. + const rawOperations = myersDiff(oldParagraphs, newParagraphs, paragraphComparator); + const operations = reorderParagraphOperations(rawOperations); + + // Build a step-by-step operation list with paragraph indices for easier processing. + let oldIdx = 0; + let newIdx = 0; + const steps = []; + for (const op of operations) { + if (op === 'equal') { + steps.push({ type: 'equal', oldIdx, newIdx }); + oldIdx += 1; + newIdx += 1; + } else if (op === 'delete') { + steps.push({ type: 'delete', oldIdx }); + oldIdx += 1; + } else if (op === 'insert') { + steps.push({ type: 'insert', newIdx }); + newIdx += 1; + } + } + + // Process the operation steps into a normalized diff output. + const diffs = []; + for (let i = 0; i < steps.length; i += 1) { + const step = steps[i]; + + switch (step.type) { + case 'equal': + const oldPara = oldParagraphs[step.oldIdx]; + const newPara = newParagraphs[step.newIdx]; + if (oldPara.text !== newPara.text) { + // Text changed within the same paragraph + const diff = buildModifiedParagraphDiff(oldPara, newPara); + if (diff.textDiffs.length > 0) { + diffs.push(diff); + } + } + break; + + case 'delete': + const nextStep = steps[i + 1]; + + // Check if the next step is an insertion that can be paired as a modification. + if (nextStep?.type === 'insert') { + const oldPara = oldParagraphs[step.oldIdx]; + const newPara = newParagraphs[nextStep.newIdx]; + if (canTreatAsModification(oldPara, newPara)) { + const diff = buildModifiedParagraphDiff(oldPara, newPara); + if (diff.textDiffs.length > 0) { + diffs.push(diff); + } + i += 1; // Skip the next insert step as it's paired + } else { + // The paragraph that was deleted is significantly different from any nearby insertions; treat as a deletion. + diffs.push(buildDeletedParagraphDiff(oldParagraphs[step.oldIdx])); + } + } else { + // No matching insertion; treat as a deletion. + diffs.push(buildDeletedParagraphDiff(oldParagraphs[step.oldIdx])); + } + break; + + case 'insert': + diffs.push(buildAddedParagraphDiff(newParagraphs[step.newIdx])); + break; + } + } + + return diffs; +} + +/** + * Compares two paragraphs for identity based on paraId or text content so the diff can prioritize logical matches. + * This prevents the algorithm from treating the same paragraph as a deletion+insertion when the paraId or text proves + * they refer to the same logical node, which in turn keeps visual diffs stable. + * @param {{node: Node, text: string}} oldParagraph + * @param {{node: Node, text: string}} newParagraph + * @returns {boolean} + */ +function paragraphComparator(oldParagraph, newParagraph) { + const oldId = oldParagraph?.node?.attrs?.paraId; + const newId = newParagraph?.node?.attrs?.paraId; + if (oldId && newId && oldId === newId) { + return true; + } + return oldParagraph?.text === newParagraph?.text; +} + +/** + * Builds a normalized payload describing a paragraph addition, ensuring all consumers receive the same metadata shape. + * @param {{node: Node, pos: number, text: string}} paragraph + * @returns {AddedParagraphDiff} + */ +function buildAddedParagraphDiff(paragraph) { + return { + type: 'added', + node: paragraph.node, + text: paragraph.text, + pos: paragraph.pos, + }; +} + +/** + * Builds a normalized payload describing a paragraph deletion so diff consumers can show removals with all context. + * @param {{node: Node, pos: number}} paragraph + * @returns {DeletedParagraphDiff} + */ +function buildDeletedParagraphDiff(paragraph) { + return { + type: 'deleted', + node: paragraph.node, + oldText: paragraph.text, + pos: paragraph.pos, + }; +} + +/** + * Builds the payload for a paragraph modification, including text-level diffs, so renderers can highlight edits inline. + * @param {{node: Node, pos: number, text: string, resolvePosition: Function}} oldParagraph + * @param {{node: Node, pos: number, text: string, resolvePosition: Function}} newParagraph + * @returns {ModifiedParagraphDiff} + */ +function buildModifiedParagraphDiff(oldParagraph, newParagraph) { + const textDiffs = getTextDiff( + oldParagraph.text, + newParagraph.text, + oldParagraph.resolvePosition, + newParagraph.resolvePosition, + ); + + return { + type: 'modified', + oldText: oldParagraph.text, + newText: newParagraph.text, + pos: oldParagraph.pos, + textDiffs, + }; +} + +/** + * Decides whether a delete/insert pair should be reinterpreted as a modification to minimize noisy diff output. + * This heuristic limits the number of false-positive additions/deletions, which keeps reviewers focused on real edits. + * @param {{node: Node, text: string}} oldParagraph + * @param {{node: Node, text: string}} newParagraph + * @returns {boolean} + */ +function canTreatAsModification(oldParagraph, newParagraph) { + if (paragraphComparator(oldParagraph, newParagraph)) { + return true; + } + + const oldText = oldParagraph?.text ?? ''; + const newText = newParagraph?.text ?? ''; + const maxLength = Math.max(oldText.length, newText.length); + if (maxLength < MIN_LENGTH_FOR_SIMILARITY) { + return false; + } + + const similarity = getTextSimilarityScore(oldText, newText); + + return similarity >= SIMILARITY_THRESHOLD; +} + +/** + * Scores the similarity between two text strings so the diff can decide if they represent the same conceptual paragraph. + * @param {string} oldText + * @param {string} newText + * @returns {number} + */ +function getTextSimilarityScore(oldText, newText) { + if (!oldText && !newText) { + return 1; + } + + const operations = myersDiff(oldText, newText, (a, b) => a === b); + const edits = operations.filter((op) => op !== 'equal').length; + const maxLength = Math.max(oldText.length, newText.length) || 1; + return 1 - edits / maxLength; // Proportion of unchanged characters +} + +/** + * Normalizes Myers diff operations for paragraph comparisons so consecutive replacements are easier to classify. + * Myers tends to emit all deletes before inserts when a paragraph is replaced, even if it's a one-for-one swap, and + * that pattern would otherwise hide opportunities to treat those operations as modifications. Reordering the list here + * ensures higher-level diff logic stays simple while avoiding side effects for other consumers of the same operations. + * @param {Array<'equal'|'delete'|'insert'>} operations + * @returns {Array<'equal'|'delete'|'insert'>} + */ +function reorderParagraphOperations(operations) { + const normalized = []; + + for (let i = 0; i < operations.length; i += 1) { + const op = operations[i]; + if (op !== 'delete') { + normalized.push(op); + continue; + } + + let deleteCount = 0; + while (i < operations.length && operations[i] === 'delete') { + deleteCount += 1; + i += 1; + } + + let insertCount = 0; + let insertCursor = i; + while (insertCursor < operations.length && operations[insertCursor] === 'insert') { + insertCount += 1; + insertCursor += 1; + } + + const pairCount = Math.min(deleteCount, insertCount); + for (let k = 0; k < pairCount; k += 1) { + normalized.push('delete', 'insert'); + } + for (let k = pairCount; k < deleteCount; k += 1) { + normalized.push('delete'); + } + for (let k = pairCount; k < insertCount; k += 1) { + normalized.push('insert'); + } + + i = insertCursor - 1; + } + + return normalized; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js new file mode 100644 index 0000000000..6c3edce933 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -0,0 +1,52 @@ +import { describe, it, expect } from 'vitest'; +import { diffParagraphs } from './paragraph-diffing.js'; + +const createParagraph = (text, attrs = {}) => ({ + node: { attrs }, + pos: attrs.pos ?? 0, + text, + resolvePosition: (index) => index, +}); + +describe('diffParagraphs', () => { + it('treats similar paragraphs without IDs as modifications', () => { + const oldParagraphs = [createParagraph('Hello world from ProseMirror.')]; + const newParagraphs = [createParagraph('Hello brave new world from ProseMirror.')]; + + const diffs = diffParagraphs(oldParagraphs, newParagraphs); + + expect(diffs).toHaveLength(1); + expect(diffs[0].type).toBe('modified'); + expect(diffs[0].textDiffs.length).toBeGreaterThan(0); + }); + + it('keeps unrelated paragraphs as deletion + addition', () => { + const oldParagraphs = [createParagraph('Alpha paragraph with some text.')]; + const newParagraphs = [createParagraph('Zephyr quickly jinxed the new passage.')]; + + const diffs = diffParagraphs(oldParagraphs, newParagraphs); + + expect(diffs).toHaveLength(2); + expect(diffs[0].type).toBe('deleted'); + expect(diffs[1].type).toBe('added'); + }); + + it('detects modifications even when Myers emits grouped deletes and inserts', () => { + const oldParagraphs = [ + createParagraph('Original introduction paragraph that needs tweaks.'), + createParagraph('Paragraph that will be removed.'), + ]; + const newParagraphs = [ + createParagraph('Original introduction paragraph that now has tweaks.'), + createParagraph('Completely different replacement paragraph.'), + ]; + + const diffs = diffParagraphs(oldParagraphs, newParagraphs); + + expect(diffs).toHaveLength(3); + expect(diffs[0].type).toBe('modified'); + expect(diffs[0].textDiffs.length).toBeGreaterThan(0); + expect(diffs[1].type).toBe('deleted'); + expect(diffs[2].type).toBe('added'); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js new file mode 100644 index 0000000000..c3f426affa --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js @@ -0,0 +1,102 @@ +import { myersDiff } from './myers-diff.js'; + +/** + * Computes text-level additions and deletions between two strings using Myers diff algorithm, mapping back to document positions. + * @param {string} oldText - Source text. + * @param {string} newText - Target text. + * @param {(index: number) => number|null} oldPositionResolver - Maps string indexes to the original document. + * @param {(index: number) => number|null} [newPositionResolver=oldPositionResolver] - Maps string indexes to the updated document. + * @returns {Array} List of addition/deletion ranges with document positions and text content. + */ +export function getTextDiff(oldText, newText, oldPositionResolver, newPositionResolver = oldPositionResolver) { + const oldLen = oldText.length; + const newLen = newText.length; + + if (oldLen === 0 && newLen === 0) { + return []; + } + + const operations = myersDiff(oldText, newText, (a, b) => a === b); + return buildDiffFromOperations(operations, oldText, newText, oldPositionResolver, newPositionResolver); +} + +/** + * Groups edit operations into contiguous additions/deletions and maps them to document positions. + * + * @param {Array<'equal'|'delete'|'insert'>} operations - Raw operation list produced by the backtracked Myers path. + * @param {string} oldText - Source text. + * @param {string} newText - Target text. + * @param {(index: number) => number|null} oldPositionResolver - Maps string indexes to the previous document. + * @param {(index: number) => number|null} newPositionResolver - Maps string indexes to the updated document. + * @returns {Array} Final diff payload matching the existing API surface. + */ +function buildDiffFromOperations(operations, oldText, newText, oldPositionResolver, newPositionResolver) { + const diffs = []; + let change = null; + let oldIdx = 0; + let newIdx = 0; + const resolveOld = oldPositionResolver ?? (() => null); + const resolveNew = newPositionResolver ?? resolveOld; + + /** Flushes the current change block into the diffs list. */ + const flushChange = () => { + if (!change || change.text.length === 0) { + change = null; + return; + } + + if (change.type === 'delete') { + const startIdx = resolveOld(change.startOldIdx); + const endIdx = resolveOld(change.endOldIdx); + diffs.push({ + type: 'deletion', + startIdx, + endIdx, + text: change.text, + }); + } else if (change.type === 'insert') { + const startIdx = resolveNew(change.startNewIdx); + const endIdx = resolveNew(change.endNewIdx); + diffs.push({ + type: 'addition', + startIdx, + endIdx, + text: change.text, + }); + } + + change = null; + }; + + for (const op of operations) { + if (op === 'equal') { + flushChange(); + oldIdx += 1; + newIdx += 1; + continue; + } + + if (!change || change.type !== op) { + flushChange(); + if (op === 'delete') { + change = { type: 'delete', startOldIdx: oldIdx, endOldIdx: oldIdx, text: '' }; + } else if (op === 'insert') { + change = { type: 'insert', startNewIdx: newIdx, endNewIdx: newIdx, text: '' }; + } + } + + if (op === 'delete') { + change.text += oldText[oldIdx]; + oldIdx += 1; + change.endOldIdx = oldIdx; + } else if (op === 'insert') { + change.text += newText[newIdx]; + newIdx += 1; + change.endNewIdx = newIdx; + } + } + + flushChange(); + + return diffs; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js new file mode 100644 index 0000000000..40e5d794a4 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js @@ -0,0 +1,50 @@ +import { describe, it, expect } from 'vitest'; +import { getTextDiff } from './text-diffing'; + +describe('getTextDiff', () => { + it('returns an empty diff list when both strings are identical', () => { + const resolver = () => 0; + + const diffs = getTextDiff('unchanged', 'unchanged', resolver); + + expect(diffs).toEqual([]); + }); + + it('detects text insertions and maps them to resolver positions', () => { + const oldResolver = (index) => index + 10; + const newResolver = (index) => index + 100; + + const diffs = getTextDiff('abc', 'abXc', oldResolver, newResolver); + + expect(diffs).toEqual([ + { + type: 'addition', + startIdx: 102, + endIdx: 103, + text: 'X', + }, + ]); + }); + + it('detects deletions and additions in the same diff sequence', () => { + const oldResolver = (index) => index + 5; + const newResolver = (index) => index + 20; + + const diffs = getTextDiff('abcd', 'abXYd', oldResolver, newResolver); + + expect(diffs).toEqual([ + { + type: 'deletion', + startIdx: 7, + endIdx: 8, + text: 'c', + }, + { + type: 'addition', + startIdx: 22, + endIdx: 24, + text: 'XY', + }, + ]); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js index 606010d29b..04c2fbc62f 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.js @@ -1,5 +1,5 @@ -import { Node } from 'prosemirror-model'; -import { v4 as uuidv4 } from 'uuid'; +import { extractParagraphs } from './utils.js'; +import { diffParagraphs } from './algorithm/paragraph-diffing.js'; /** * Computes paragraph-level diffs between two ProseMirror documents, returning inserts, deletes and text modifications. @@ -8,316 +8,8 @@ import { v4 as uuidv4 } from 'uuid'; * @returns {Array} List of diff objects describing added, deleted or modified paragraphs. */ export function computeDiff(oldPmDoc, newPmDoc) { - const diffs = []; + const oldParagraphs = extractParagraphs(oldPmDoc); + const newParagraphs = extractParagraphs(newPmDoc); - // 1. Extract all paragraphs from old document and create a map using their IDs - const oldParagraphsMap = extractParagraphs(oldPmDoc); - - // 2. Extract all paragraphs from new document and create a map using their IDs - const newParagraphsMap = extractParagraphs(newPmDoc); - - // 3. Compare paragraphs in old and new documents - let insertPos = 0; - newParagraphsMap.forEach((newPara, paraId) => { - const oldPara = oldParagraphsMap.get(paraId); - if (!oldPara) { - diffs.push({ - type: 'added', - paraId, - node: newPara.node, - text: newPara.node.textContent, - pos: insertPos, - }); - return; - } else if (oldPara.node.textContent !== newPara.node.textContent) { - const oldTextContent = getTextContent(oldPara.node, oldPara.pos); - const newTextContent = getTextContent(newPara.node, newPara.pos); - const textDiffs = getTextDiff(oldPara.node.textContent, newPara.node.textContent, oldTextContent.resolvePosition); - diffs.push({ - type: 'modified', - paraId, - oldText: oldTextContent.text, - newText: newTextContent.text, - pos: oldPara.pos, - textDiffs, - }); - } - insertPos = oldPara.pos + oldPara.node.nodeSize; - }); - - // 4. Identify deleted paragraphs - oldParagraphsMap.forEach((oldPara, paraId) => { - if (!newParagraphsMap.has(paraId)) { - diffs.push({ type: 'deleted', paraId, node: oldPara.node, pos: oldPara.pos }); - } - }); - - return diffs; -} - -/** - * Collects paragraphs from a ProseMirror document and returns them by paragraph ID. - * @param {Node} pmDoc - ProseMirror document to scan. - * @returns {Map} Map keyed by paraId containing paragraph nodes and positions. - */ -export function extractParagraphs(pmDoc) { - const paragraphMap = new Map(); - pmDoc.descendants((node, pos) => { - if (node.type.name === 'paragraph') { - paragraphMap.set(node.attrs?.paraId ?? uuidv4(), { node, pos }); - return false; // Do not descend further - } - }); - return paragraphMap; -} - -/** - * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. - * @param {Node} paragraph - Paragraph node to flatten. - * @param {number} [paragraphPos=0] - Position of the paragraph in the document. - * @returns {{text: string, resolvePosition: (index: number) => number|null}} Concatenated text and position resolver. - */ -export function getTextContent(paragraph, paragraphPos = 0) { - let text = ''; - const segments = []; - - paragraph.nodesBetween( - 0, - paragraph.content.size, - (node, pos) => { - let nodeText = ''; - - if (node.isText) { - nodeText = node.text; - } else if (node.isLeaf && node.type.spec.leafText) { - nodeText = node.type.spec.leafText(node); - } - - if (!nodeText) { - return; - } - - const start = text.length; - const end = start + nodeText.length; - - segments.push({ start, end, pos }); - text += nodeText; - }, - 0, - ); - - const resolvePosition = (index) => { - if (index < 0 || index > text.length) { - return null; - } - - for (const segment of segments) { - if (index >= segment.start && index < segment.end) { - return paragraphPos + 1 + segment.pos + (index - segment.start); - } - } - - // If index points to the end of the string, return the paragraph end - return paragraphPos + 1 + paragraph.content.size; - }; - - return { text, resolvePosition }; -} - -/** - * Computes text-level additions and deletions between two strings using Myers diff algorithm, mapping back to document positions. - * @param {string} oldText - Source text. - * @param {string} newText - Target text. - * @param {(index: number) => number|null} positionResolver - Maps string indices to document positions. - * @returns {Array} List of addition/deletion ranges with document positions and text content. - */ -export function getTextDiff(oldText, newText, positionResolver) { - const oldLen = oldText.length; - const newLen = newText.length; - - if (oldLen === 0 && newLen === 0) { - return []; - } - - // Myers diff bookkeeping: +2 padding keeps diagonal lookups in bounds. - const max = oldLen + newLen; - const size = 2 * max + 3; - const offset = max + 1; - const v = new Array(size).fill(-1); - v[offset + 1] = 0; - - const trace = []; - let foundPath = false; - - for (let d = 0; d <= max && !foundPath; d += 1) { - for (let k = -d; k <= d; k += 2) { - const index = offset + k; - let x; - - if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { - x = v[index + 1]; - } else { - x = v[index - 1] + 1; - } - - let y = x - k; - while (x < oldLen && y < newLen && oldText[x] === newText[y]) { - x += 1; - y += 1; - } - - v[index] = x; - - if (x >= oldLen && y >= newLen) { - foundPath = true; - break; - } - } - trace.push(v.slice()); - } - - const operations = backtrackMyers(trace, oldLen, newLen, offset); - return buildDiffFromOperations(operations, oldText, newText, positionResolver); -} - -/** - * Reconstructs the shortest edit script by walking the previously recorded V vectors. - * - * @param {Array} trace - Snapshot of diagonal furthest-reaching points per edit distance. - * @param {number} oldLen - Length of the original string. - * @param {number} newLen - Length of the target string. - * @param {number} offset - Offset applied to diagonal indexes to keep array lookups positive. - * @returns {Array<'equal'|'delete'|'insert'>} Concrete step-by-step operations. - */ -function backtrackMyers(trace, oldLen, newLen, offset) { - const operations = []; - let x = oldLen; - let y = newLen; - - for (let d = trace.length - 1; d > 0; d -= 1) { - const v = trace[d - 1]; - const k = x - y; - const index = offset + k; - - let prevK; - if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { - prevK = k + 1; - } else { - prevK = k - 1; - } - - const prevIndex = offset + prevK; - const prevX = v[prevIndex]; - const prevY = prevX - prevK; - - while (x > prevX && y > prevY) { - x -= 1; - y -= 1; - operations.push('equal'); - } - - if (x === prevX) { - y -= 1; - operations.push('insert'); - } else { - x -= 1; - operations.push('delete'); - } - } - - while (x > 0 && y > 0) { - x -= 1; - y -= 1; - operations.push('equal'); - } - - while (x > 0) { - x -= 1; - operations.push('delete'); - } - - while (y > 0) { - y -= 1; - operations.push('insert'); - } - - return operations.reverse(); -} - -/** - * Groups edit operations into contiguous additions/deletions and maps them to document positions. - * - * @param {Array<'equal'|'delete'|'insert'>} operations - Raw operation list produced by the backtracked Myers path. - * @param {string} oldText - Source text. - * @param {string} newText - Target text. - * @param {(index: number) => number|null} positionResolver - Maps string indexes to ProseMirror positions. - * @returns {Array} Final diff payload matching the existing API surface. - */ -function buildDiffFromOperations(operations, oldText, newText, positionResolver) { - const diffs = []; - let run = null; - let oldIdx = 0; - let newIdx = 0; - let insertionAnchor = 0; - - const flushRun = () => { - if (!run || run.text.length === 0) { - run = null; - return; - } - - if (run.type === 'delete') { - const startIdx = positionResolver(run.startOldIdx); - const endIdx = positionResolver(run.endOldIdx); - diffs.push({ - type: 'deletion', - startIdx, - endIdx, - text: run.text, - }); - } else if (run.type === 'insert') { - const startIdx = positionResolver(run.referenceOldIdx); - const endIdx = positionResolver(run.referenceOldIdx); - diffs.push({ - type: 'addition', - startIdx, - endIdx, - text: run.text, - }); - } - - run = null; - }; - - for (const op of operations) { - if (op === 'equal') { - flushRun(); - oldIdx += 1; - newIdx += 1; - insertionAnchor = oldIdx; - continue; - } - - if (!run || run.type !== op) { - flushRun(); - if (op === 'delete') { - run = { type: 'delete', startOldIdx: oldIdx, endOldIdx: oldIdx, text: '' }; - } else if (op === 'insert') { - run = { type: 'insert', referenceOldIdx: insertionAnchor, text: '' }; - } - } - - if (op === 'delete') { - run.text += oldText[oldIdx]; - oldIdx += 1; - run.endOldIdx = oldIdx; - } else if (op === 'insert') { - run.text += newText[newIdx]; - newIdx += 1; - } - } - - flushRun(); - - return diffs; + return diffParagraphs(oldParagraphs, newParagraphs); } diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index a6da92a0be..fcd1772f7b 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -1,11 +1,11 @@ import { describe, it, expect } from 'vitest'; -import { getTextContent, computeDiff, extractParagraphs, getTextDiff } from './computeDiff'; +import { computeDiff } from './computeDiff'; import { Editor } from '@core/Editor.js'; import { getStarterExtensions } from '@extensions/index.js'; import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers.js'; -export const getDocument = async (name) => { +const getDocument = async (name) => { const buffer = await getTestDataAsBuffer(name); const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); @@ -30,196 +30,108 @@ describe('Diff', () => { const docAfter = await getDocument('diff_after.docx'); const diffs = computeDiff(docBefore, docAfter); - console.log(JSON.stringify(diffs, null, 2)); - }); -}); - -describe('extractParagraphs', () => { - it('collects all paragraph nodes keyed by their paraId', () => { - const firstParagraph = { - type: { name: 'paragraph' }, - attrs: { paraId: 'para-1' }, - textContent: 'First paragraph', - }; - const nonParagraph = { - type: { name: 'heading' }, - attrs: { paraId: 'heading-1' }, - }; - const secondParagraph = { - type: { name: 'paragraph' }, - attrs: { paraId: 'para-2' }, - textContent: 'Second paragraph', - }; - const pmDoc = { - descendants: (callback) => { - callback(firstParagraph, 0); - callback(nonParagraph, 5); - callback(secondParagraph, 10); - }, - }; - - const paragraphs = extractParagraphs(pmDoc); - - expect(paragraphs.size).toBe(2); - expect(paragraphs.get('para-1')).toEqual({ node: firstParagraph, pos: 0 }); - expect(paragraphs.get('para-2')).toEqual({ node: secondParagraph, pos: 10 }); - }); - - it('generates unique IDs when paragraph nodes are missing paraId', () => { - const firstParagraph = { - type: { name: 'paragraph' }, - attrs: {}, - textContent: 'Anonymous first', - }; - const secondParagraph = { - type: { name: 'paragraph' }, - attrs: undefined, - textContent: 'Anonymous second', - }; - const pmDoc = { - descendants: (callback) => { - callback(firstParagraph, 2); - callback(secondParagraph, 8); - }, - }; - - const paragraphs = extractParagraphs(pmDoc); - const entries = [...paragraphs.entries()]; - const firstEntry = entries.find(([, value]) => value.node === firstParagraph); - const secondEntry = entries.find(([, value]) => value.node === secondParagraph); - - expect(paragraphs.size).toBe(2); - expect(firstEntry?.[0]).toBeTruthy(); - expect(secondEntry?.[0]).toBeTruthy(); - expect(firstEntry?.[0]).not.toBe(secondEntry?.[0]); - expect(firstEntry?.[1].pos).toBe(2); - expect(secondEntry?.[1].pos).toBe(8); - }); -}); - -describe('getTextContent', () => { - it('Handles basic text nodes', () => { - const mockParagraph = { - content: { - size: 5, - }, - nodesBetween: (from, to, callback) => { - callback({ isText: true, text: 'Hello' }, 0); - }, - }; - - const result = getTextContent(mockParagraph); - expect(result.text).toBe('Hello'); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(4)).toBe(5); - }); - - it('Handles leaf nodes with leafText', () => { - const mockParagraph = { - content: { - size: 4, - }, - nodesBetween: (from, to, callback) => { - callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 0); - }, - }; - - const result = getTextContent(mockParagraph); - expect(result.text).toBe('Leaf'); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(3)).toBe(4); + const getDiff = (type, predicate) => diffs.find((diff) => diff.type === type && predicate(diff)); + + expect(diffs).toHaveLength(15); + expect(diffs.filter((diff) => diff.type === 'modified')).toHaveLength(5); + expect(diffs.filter((diff) => diff.type === 'added')).toHaveLength(5); + expect(diffs.filter((diff) => diff.type === 'deleted')).toHaveLength(5); + + // Modified paragraph with multiple text diffs + let diff = getDiff( + 'modified', + (diff) => diff.oldText === 'Curabitur facilisis ligula suscipit enim pretium, sed porttitor augue consequat.', + ); + expect(diff?.newText).toBe( + 'Curabitur facilisis ligula suscipit enim pretium et nunc ligula, porttitor augue consequat maximus.', + ); + expect(diff?.textDiffs).toHaveLength(6); + + // Deleted paragraph + diff = getDiff( + 'deleted', + (diff) => diff.oldText === 'Vestibulum gravida eros sed nulla malesuada, vel eleifend sapien bibendum.', + ); + expect(diff).toBeDefined(); + + // Added paragraph + diff = getDiff( + 'added', + (diff) => + diff.text === 'Lorem tempor velit eget lorem posuere, id luctus dolor ultricies, to track supplier risks.', + ); + expect(diff).toBeDefined(); + + // Another modified paragraph + diff = getDiff( + 'modified', + (diff) => diff.oldText === 'Quisque posuere risus a ligula cursus vulputate et vitae ipsum.', + ); + expect(diff?.newText).toBe( + 'Quisque dapibus risus convallis ligula cursus vulputate, ornare dictum ipsum et vehicula nisl.', + ); + + // Simple modified paragraph + diff = getDiff('modified', (diff) => diff.oldText === 'OK' && diff.newText === 'No'); + expect(diff).toBeDefined(); + + // Added, trimmed, merged, removed, and moved paragraphs + diff = getDiff('added', (diff) => diff.text === 'Sed et nibh in nulla blandit maximus et dapibus.'); + expect(diff).toBeDefined(); + + const trimmedParagraph = getDiff( + 'modified', + (diff) => + diff.oldText === + 'Sed et nibh in nulla blandit maximus et dapibus. Etiam egestas diam luctus sit amet gravida purus.' && + diff.newText === 'Etiam egestas diam luctus sit amet gravida purus.', + ); + expect(trimmedParagraph).toBeDefined(); + + const mergedParagraph = getDiff( + 'added', + (diff) => + diff.text === + 'Praesent dapibus lacus vitae tellus laoreet, eget facilisis mi facilisis, donec mollis lacus sed nisl posuere, nec feugiat massa fringilla.', + ); + expect(mergedParagraph).toBeDefined(); + + const removedParagraph = getDiff( + 'modified', + (diff) => + diff.oldText === 'Praesent dapibus lacus vitae tellus laoreet, eget facilisis mi facilisis.' && + diff.newText === '', + ); + expect(removedParagraph).toBeDefined(); + + const movedParagraph = getDiff( + 'added', + (diff) => diff.text === 'Aenean hendrerit elit vitae sem fermentum, vel sagittis erat gravida.', + ); + expect(movedParagraph).toBeDefined(); }); - it('Handles mixed content', () => { - const mockParagraph = { - content: { - size: 9, - }, - nodesBetween: (from, to, callback) => { - callback({ isText: true, text: 'Hello' }, 0); - callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 5); - }, - }; - - const result = getTextContent(mockParagraph); - expect(result.text).toBe('HelloLeaf'); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(5)).toBe(6); - expect(result.resolvePosition(9)).toBe(10); - }); - - it('Handles empty content', () => { - const mockParagraph = { - content: { - size: 0, - }, - nodesBetween: () => {}, - }; - - const result = getTextContent(mockParagraph); - expect(result.text).toBe(''); - expect(result.resolvePosition(0)).toBe(1); - }); - - it('Handles nested nodes', () => { - const mockParagraph = { - content: { - size: 6, - }, - nodesBetween: (from, to, callback) => { - callback({ isText: true, text: 'Nested' }, 0); - }, - }; - - const result = getTextContent(mockParagraph); - expect(result.text).toBe('Nested'); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(6)).toBe(7); - }); -}); + it('Compare two documents with simple changes', async () => { + const docBefore = await getDocument('diff_before2.docx'); + const docAfter = await getDocument('diff_after2.docx'); -describe('getTextDiff', () => { - it('returns an empty diff list when both strings are identical', () => { - const resolver = () => 0; + const diffs = computeDiff(docBefore, docAfter); + expect(diffs).toHaveLength(4); - const diffs = getTextDiff('unchanged', 'unchanged', resolver); + let diff = diffs.find((diff) => diff.type === 'modified' && diff.oldText === 'Here’s some text.'); - expect(diffs).toEqual([]); - }); + expect(diff.newText).toBe('Here’s some NEW text.'); + expect(diff.textDiffs).toHaveLength(1); + expect(diff.textDiffs[0].text).toBe('NEW '); - it('detects text insertions and maps them to resolver positions', () => { - const resolver = (index) => index + 10; + diff = diffs.find((diff) => diff.type === 'deleted' && diff.oldText === 'I deleted this sentence.'); + expect(diff).toBeDefined(); - const diffs = getTextDiff('abc', 'abXc', resolver); - - expect(diffs).toEqual([ - { - type: 'addition', - startIdx: 12, - endIdx: 12, - text: 'X', - }, - ]); - }); + diff = diffs.find((diff) => diff.type === 'added' && diff.text === 'I added this sentence.'); + expect(diff).toBeDefined(); - it('detects deletions and additions in the same diff sequence', () => { - const resolver = (index) => index + 5; - - const diffs = getTextDiff('abcd', 'abXYd', resolver); - - expect(diffs).toEqual([ - { - type: 'deletion', - startIdx: 7, - endIdx: 8, - text: 'c', - }, - { - type: 'addition', - startIdx: 7, - endIdx: 7, - text: 'XY', - }, - ]); + diff = diffs.find((diff) => diff.type === 'modified' && diff.oldText === 'We are not done yet.'); + expect(diff.newText).toBe('We are done now.'); + expect(diff.textDiffs).toHaveLength(3); }); }); diff --git a/packages/super-editor/src/extensions/diffing/utils.js b/packages/super-editor/src/extensions/diffing/utils.js new file mode 100644 index 0000000000..3b4cc56abf --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/utils.js @@ -0,0 +1,69 @@ +/** + * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. + * @param {Node} paragraph - Paragraph node to flatten. + * @param {number} [paragraphPos=0] - Position of the paragraph in the document. + * @returns {{text: string, resolvePosition: (index: number) => number|null}} Concatenated text and position resolver. + */ +export function getTextContent(paragraph, paragraphPos = 0) { + let text = ''; + const segments = []; + + paragraph.nodesBetween( + 0, + paragraph.content.size, + (node, pos) => { + let nodeText = ''; + + if (node.isText) { + nodeText = node.text; + } else if (node.isLeaf && node.type.spec.leafText) { + nodeText = node.type.spec.leafText(node); + } + + if (!nodeText) { + return; + } + + const start = text.length; + const end = start + nodeText.length; + + segments.push({ start, end, pos }); + text += nodeText; + }, + 0, + ); + + const resolvePosition = (index) => { + if (index < 0 || index > text.length) { + return null; + } + + for (const segment of segments) { + if (index >= segment.start && index < segment.end) { + return paragraphPos + 1 + segment.pos + (index - segment.start); + } + } + + // If index points to the end of the string, return the paragraph end + return paragraphPos + 1 + paragraph.content.size; + }; + + return { text, resolvePosition }; +} + +/** + * Collects paragraphs from a ProseMirror document and returns them by paragraph ID. + * @param {Node} pmDoc - ProseMirror document to scan. + * @returns {Array<{node: Node, pos: number, text: string, resolvePosition: Function}>} Ordered list of paragraph descriptors. + */ +export function extractParagraphs(pmDoc) { + const paragraphs = []; + pmDoc.descendants((node, pos) => { + if (node.type.name === 'paragraph') { + const { text, resolvePosition } = getTextContent(node, pos); + paragraphs.push({ node, pos, text, resolvePosition }); + return false; // Do not descend further + } + }); + return paragraphs; +} diff --git a/packages/super-editor/src/extensions/diffing/utils.test.js b/packages/super-editor/src/extensions/diffing/utils.test.js new file mode 100644 index 0000000000..1c3dd9ddbc --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/utils.test.js @@ -0,0 +1,141 @@ +import { extractParagraphs, getTextContent } from './utils'; + +/** + * Creates a lightweight mock paragraph node for tests. + * @param {string} text + * @param {Record} [attrs={}] + * @returns {object} + */ +const createParagraphNode = (text, attrs = {}) => ({ + type: { name: 'paragraph' }, + attrs, + textContent: text, + content: { size: text.length }, + nodesBetween: (from, to, callback) => { + callback({ isText: true, text }, 0); + }, +}); + +describe('extractParagraphs', () => { + it('collects paragraph nodes in document order', () => { + const firstParagraph = createParagraphNode('First paragraph', { paraId: 'para-1' }); + const nonParagraph = { + type: { name: 'heading' }, + attrs: { paraId: 'heading-1' }, + }; + const secondParagraph = createParagraphNode('Second paragraph', { paraId: 'para-2' }); + const pmDoc = { + descendants: (callback) => { + callback(firstParagraph, 0); + callback(nonParagraph, 5); + callback(secondParagraph, 10); + }, + }; + + const paragraphs = extractParagraphs(pmDoc); + + expect(paragraphs).toHaveLength(2); + expect(paragraphs[0]).toMatchObject({ node: firstParagraph, pos: 0, text: 'First paragraph' }); + expect(paragraphs[1]).toMatchObject({ node: secondParagraph, pos: 10, text: 'Second paragraph' }); + }); + + it('includes position resolvers for paragraphs with missing IDs', () => { + const firstParagraph = createParagraphNode('Anonymous first'); + const secondParagraph = createParagraphNode('Anonymous second'); + const pmDoc = { + descendants: (callback) => { + callback(firstParagraph, 2); + callback(secondParagraph, 8); + }, + }; + + const paragraphs = extractParagraphs(pmDoc); + + expect(paragraphs).toHaveLength(2); + expect(paragraphs[0].pos).toBe(2); + expect(paragraphs[1].pos).toBe(8); + expect(paragraphs[0].resolvePosition(0)).toBe(3); + expect(paragraphs[1].resolvePosition(4)).toBe(13); + }); +}); + +describe('getTextContent', () => { + it('Handles basic text nodes', () => { + const mockParagraph = { + content: { + size: 5, + }, + nodesBetween: (from, to, callback) => { + callback({ isText: true, text: 'Hello' }, 0); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('Hello'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(4)).toBe(5); + }); + + it('Handles leaf nodes with leafText', () => { + const mockParagraph = { + content: { + size: 4, + }, + nodesBetween: (from, to, callback) => { + callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 0); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('Leaf'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(3)).toBe(4); + }); + + it('Handles mixed content', () => { + const mockParagraph = { + content: { + size: 9, + }, + nodesBetween: (from, to, callback) => { + callback({ isText: true, text: 'Hello' }, 0); + callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 5); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('HelloLeaf'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(5)).toBe(6); + expect(result.resolvePosition(9)).toBe(10); + }); + + it('Handles empty content', () => { + const mockParagraph = { + content: { + size: 0, + }, + nodesBetween: () => {}, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe(''); + expect(result.resolvePosition(0)).toBe(1); + }); + + it('Handles nested nodes', () => { + const mockParagraph = { + content: { + size: 6, + }, + nodesBetween: (from, to, callback) => { + callback({ isText: true, text: 'Nested' }, 0); + }, + }; + + const result = getTextContent(mockParagraph); + expect(result.text).toBe('Nested'); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(6)).toBe(7); + }); +}); diff --git a/packages/super-editor/src/tests/data/diff_after.docx b/packages/super-editor/src/tests/data/diff_after.docx index b04b965837ddff5c026353bd4fb9c1f11706156b..75c363abb674c799b6f9918998e7e8b8e6511019 100644 GIT binary patch delta 9019 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 diff --git a/packages/super-editor/src/tests/data/diff_after2.docx b/packages/super-editor/src/tests/data/diff_after2.docx new file mode 100644 index 0000000000000000000000000000000000000000..7f0426d99675989c6ddccd2e43a8f979b364bf9d GIT binary patch literal 13481 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_before.docx b/packages/super-editor/src/tests/data/diff_before.docx index 8cae247f962363005ecacefbc8b179626fb58ec9..3fec392b96bcf45d41d125552d1a7163cc13608f 100644 GIT binary patch delta 8427 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 HkM4f~pI(n! diff --git a/packages/super-editor/src/tests/data/diff_before2.docx b/packages/super-editor/src/tests/data/diff_before2.docx new file mode 100644 index 0000000000000000000000000000000000000000..6db7a2b993e99b9560ffc6c2234baa77d0ff69ea GIT binary patch literal 13404 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 Date: Fri, 19 Dec 2025 17:31:52 -0300 Subject: [PATCH 009/125] feat: compute text similarity using Levenshtein distance --- .../diffing/algorithm/paragraph-diffing.js | 6 +-- .../diffing/algorithm/similarity.js | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/similarity.js diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index 7b3fb60113..3e05cc6145 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -1,5 +1,6 @@ import { myersDiff } from './myers-diff.js'; import { getTextDiff } from './text-diffing.js'; +import { levenshteinDistance } from './similarity.js'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. const SIMILARITY_THRESHOLD = 0.65; @@ -222,10 +223,9 @@ function getTextSimilarityScore(oldText, newText) { return 1; } - const operations = myersDiff(oldText, newText, (a, b) => a === b); - const edits = operations.filter((op) => op !== 'equal').length; + const distance = levenshteinDistance(oldText, newText); const maxLength = Math.max(oldText.length, newText.length) || 1; - return 1 - edits / maxLength; // Proportion of unchanged characters + return 1 - distance / maxLength; } /** diff --git a/packages/super-editor/src/extensions/diffing/algorithm/similarity.js b/packages/super-editor/src/extensions/diffing/algorithm/similarity.js new file mode 100644 index 0000000000..d0118aabda --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/similarity.js @@ -0,0 +1,42 @@ +/** + * Computes the Levenshtein edit distance between two strings. + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function levenshteinDistance(a, b) { + const lenA = a.length; + const lenB = b.length; + + if (lenA === 0) { + return lenB; + } + if (lenB === 0) { + return lenA; + } + + let previous = new Array(lenB + 1); + let current = new Array(lenB + 1); + + for (let j = 0; j <= lenB; j += 1) { + previous[j] = j; + } + + for (let i = 1; i <= lenA; i += 1) { + current[0] = i; + const charA = a[i - 1]; + + for (let j = 1; j <= lenB; j += 1) { + const charB = b[j - 1]; + const cost = charA === charB ? 0 : 1; + const deletion = previous[j] + 1; + const insertion = current[j - 1] + 1; + const substitution = previous[j - 1] + cost; + current[j] = Math.min(deletion, insertion, substitution); + } + + [previous, current] = [current, previous]; + } + + return previous[lenB]; +} From 9583614ef255cd429d9dde0d1c3379b57a576753 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 22 Dec 2025 14:23:49 -0300 Subject: [PATCH 010/125] feat: identify contiguous text changes as single operation --- .../diffing/algorithm/text-diffing.js | 44 ++++++++++++++++++- .../diffing/algorithm/text-diffing.test.js | 33 +++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js index c3f426affa..43781c0fa1 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js @@ -17,7 +17,8 @@ export function getTextDiff(oldText, newText, oldPositionResolver, newPositionRe } const operations = myersDiff(oldText, newText, (a, b) => a === b); - return buildDiffFromOperations(operations, oldText, newText, oldPositionResolver, newPositionResolver); + const normalizedOperations = reorderTextOperations(operations); + return buildDiffFromOperations(normalizedOperations, oldText, newText, oldPositionResolver, newPositionResolver); } /** @@ -100,3 +101,44 @@ function buildDiffFromOperations(operations, oldText, newText, oldPositionResolv return diffs; } + +/** + * Normalizes the Myers operation list so contiguous edit regions are represented by single delete/insert runs. + * Myers may emit interleaved delete/insert steps for a single contiguous region, which would otherwise show up as + * multiple discrete diff entries even though the user edited one continuous block. + * @param {Array<'equal'|'delete'|'insert'>} operations + * @returns {Array<'equal'|'delete'|'insert'>} + */ +function reorderTextOperations(operations) { + const normalized = []; + + for (let i = 0; i < operations.length; i += 1) { + const op = operations[i]; + if (op === 'equal') { + normalized.push(op); + continue; + } + + let deleteCount = 0; + let insertCount = 0; + while (i < operations.length && operations[i] !== 'equal') { + if (operations[i] === 'delete') { + deleteCount += 1; + } else if (operations[i] === 'insert') { + insertCount += 1; + } + i += 1; + } + + for (let k = 0; k < deleteCount; k += 1) { + normalized.push('delete'); + } + for (let k = 0; k < insertCount; k += 1) { + normalized.push('insert'); + } + + i -= 1; // account for the for-loop increment since we advanced i while counting + } + + return normalized; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js index 40e5d794a4..c3b6e84c4a 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js @@ -1,5 +1,12 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; +vi.mock('./myers-diff.js', async () => { + const actual = await vi.importActual('./myers-diff.js'); + return { + myersDiff: vi.fn(actual.myersDiff), + }; +}); import { getTextDiff } from './text-diffing'; +import { myersDiff } from './myers-diff.js'; describe('getTextDiff', () => { it('returns an empty diff list when both strings are identical', () => { @@ -47,4 +54,28 @@ describe('getTextDiff', () => { }, ]); }); + + it('merges interleaved delete/insert steps within a contiguous change', () => { + const oldResolver = (index) => index + 1; + const newResolver = (index) => index + 50; + const customOperations = ['delete', 'insert', 'delete', 'insert']; + myersDiff.mockImplementationOnce(() => customOperations); + + const diffs = getTextDiff('ab', 'XY', oldResolver, newResolver); + + expect(diffs).toEqual([ + { + type: 'deletion', + startIdx: 1, + endIdx: 3, + text: 'ab', + }, + { + type: 'addition', + startIdx: 50, + endIdx: 52, + text: 'XY', + }, + ]); + }); }); From 8cd8e58fd3441ee223340ab0d6c803aca4d4a8f1 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 23 Dec 2025 11:49:46 -0300 Subject: [PATCH 011/125] feat: implement logic for diffing paragraph attributes --- .../diffing/algorithm/attributes-diffing.js | 132 ++++++++++++++++++ .../algorithm/attributes-diffing.test.js | 125 +++++++++++++++++ .../diffing/algorithm/paragraph-diffing.js | 20 ++- .../extensions/diffing/computeDiff.test.js | 56 +++++++- 4 files changed, 325 insertions(+), 8 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js new file mode 100644 index 0000000000..776fce854a --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js @@ -0,0 +1,132 @@ +/** + * @typedef {Object} AttributesDiff + * @property {Record} added + * @property {Record} deleted + * @property {Record} modified + */ + +/** + * Computes the attribute level diff between two arbitrary objects. + * Produces a map of dotted paths to added, deleted and modified values. + * @param {Record} objectA + * @param {Record} objectB + * @returns {AttributesDiff|null} + */ +const IGNORED_ATTRIBUTE_KEYS = new Set(['sdBlockId']); + +export function getAttributesDiff(objectA = {}, objectB = {}) { + const diff = { + added: {}, + deleted: {}, + modified: {}, + }; + + diffObjects(objectA ?? {}, objectB ?? {}, '', diff); + const hasChanges = + Object.keys(diff.added).length > 0 || Object.keys(diff.deleted).length > 0 || Object.keys(diff.modified).length > 0; + + return hasChanges ? diff : null; +} + +/** + * Recursively compares two objects and fills the diff buckets. + * @param {Record} objectA + * @param {Record} objectB + * @param {string} basePath + * @param {AttributesDiff} diff + */ +function diffObjects(objectA, objectB, basePath, diff) { + const keys = new Set([...Object.keys(objectA || {}), ...Object.keys(objectB || {})]); + + for (const key of keys) { + if (IGNORED_ATTRIBUTE_KEYS.has(key)) { + continue; + } + + const path = joinPath(basePath, key); + const hasA = Object.prototype.hasOwnProperty.call(objectA, key); + const hasB = Object.prototype.hasOwnProperty.call(objectB, key); + + if (hasA && !hasB) { + recordDeletedValue(objectA[key], path, diff); + continue; + } + + if (!hasA && hasB) { + recordAddedValue(objectB[key], path, diff); + continue; + } + + const valueA = objectA[key]; + const valueB = objectB[key]; + + if (isPlainObject(valueA) && isPlainObject(valueB)) { + diffObjects(valueA, valueB, path, diff); + continue; + } + + if (valueA !== valueB) { + diff.modified[path] = { + from: valueA, + to: valueB, + }; + } + } +} + +/** + * Records a nested value as an addition, flattening objects into dotted paths. + * @param {any} value + * @param {string} path + * @param {{added: Record}} diff + */ +function recordAddedValue(value, path, diff) { + if (isPlainObject(value)) { + for (const [childKey, childValue] of Object.entries(value)) { + if (IGNORED_ATTRIBUTE_KEYS.has(childKey)) { + continue; + } + recordAddedValue(childValue, joinPath(path, childKey), diff); + } + return; + } + diff.added[path] = value; +} + +/** + * Records a nested value as a deletion, flattening objects into dotted paths. + * @param {any} value + * @param {string} path + * @param {{deleted: Record}} diff + */ +function recordDeletedValue(value, path, diff) { + if (isPlainObject(value)) { + for (const [childKey, childValue] of Object.entries(value)) { + if (IGNORED_ATTRIBUTE_KEYS.has(childKey)) { + continue; + } + recordDeletedValue(childValue, joinPath(path, childKey), diff); + } + return; + } + diff.deleted[path] = value; +} + +/** + * Builds dotted attribute paths. + * @param {string} base + * @param {string} key + * @returns {string} + */ +function joinPath(base, key) { + return base ? `${base}.${key}` : key; +} + +/** + * Determines if a value is a plain object (no arrays or nulls). + * @param {any} value + * @returns {value is Record} + */ +function isPlainObject(value) { + return Boolean(value) && typeof value === 'object' && !Array.isArray(value); +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js new file mode 100644 index 0000000000..0b9316c837 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js @@ -0,0 +1,125 @@ +import { describe, it, expect } from 'vitest'; +import { getAttributesDiff } from './attributes-diffing.js'; + +describe('getAttributesDiff', () => { + it('detects nested additions, deletions, and modifications', () => { + const objectA = { + id: 1, + name: 'Alice', + age: 30, + config: { + theme: 'dark', + notifications: true, + additional: { + layout: 'grid', + itemsPerPage: 10, + }, + }, + }; + + const objectB = { + id: 1, + name: 'Alice Smith', + config: { + theme: 'light', + additional: { + layout: 'list', + itemsPerPage: 10, + showSidebar: true, + }, + }, + isActive: true, + }; + + const diff = getAttributesDiff(objectA, objectB); + + expect(diff).toEqual({ + added: { + isActive: true, + 'config.additional.showSidebar': true, + }, + deleted: { + age: 30, + 'config.notifications': true, + }, + modified: { + name: { from: 'Alice', to: 'Alice Smith' }, + 'config.theme': { from: 'dark', to: 'light' }, + 'config.additional.layout': { from: 'grid', to: 'list' }, + }, + }); + }); + + it('returns empty diff when objects are identical', () => { + const objectA = { + name: 'Same', + config: { + theme: 'dark', + }, + }; + + const diff = getAttributesDiff(objectA, { ...objectA }); + + expect(diff).toBeNull(); + }); + + it('handles whole-object additions, removals, and non-object replacements', () => { + const objectA = { + profile: { + preferences: { + email: true, + }, + }, + options: { + advanced: { + mode: 'auto', + }, + }, + }; + + const objectB = { + profile: {}, + options: { + advanced: 'manual', + }, + flags: ['a'], + }; + + const diff = getAttributesDiff(objectA, objectB); + + expect(diff.added).toEqual({ + flags: ['a'], + }); + expect(diff.deleted).toEqual({ + 'profile.preferences.email': true, + }); + expect(diff.modified).toEqual({ + 'options.advanced': { from: { mode: 'auto' }, to: 'manual' }, + }); + }); + + it('ignores keys defined in the ignored attribute list', () => { + const objectA = { + sdBlockId: '123', + nested: { + sdBlockId: '456', + value: 1, + }, + }; + + const objectB = { + nested: { + sdBlockId: '789', + value: 2, + }, + }; + + const diff = getAttributesDiff(objectA, objectB); + + expect(diff.added).toEqual({}); + expect(diff.deleted).toEqual({}); + expect(diff.modified).toEqual({ + 'nested.value': { from: 1, to: 2 }, + }); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index 3e05cc6145..f093b33a88 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -1,5 +1,6 @@ import { myersDiff } from './myers-diff.js'; import { getTextDiff } from './text-diffing.js'; +import { getAttributesDiff } from './attributes-diffing.js'; import { levenshteinDistance } from './similarity.js'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. @@ -32,6 +33,7 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; * @property {string} newText text after the edit * @property {number} pos original document position for anchoring UI * @property {Array} textDiffs granular inline diff data returned by `getTextDiff` + * @property {import('./attributes-diffing.js').AttributesDiff|null} attrsDiff attribute-level changes between the old and new paragraph nodes */ /** @@ -79,10 +81,13 @@ export function diffParagraphs(oldParagraphs, newParagraphs) { case 'equal': const oldPara = oldParagraphs[step.oldIdx]; const newPara = newParagraphs[step.newIdx]; - if (oldPara.text !== newPara.text) { - // Text changed within the same paragraph + if ( + oldPara.text !== newPara.text || + JSON.stringify(oldPara.node.attrs) !== JSON.stringify(newPara.node.attrs) + ) { + // Text or attributes changed within the same paragraph const diff = buildModifiedParagraphDiff(oldPara, newPara); - if (diff.textDiffs.length > 0) { + if (diff) { diffs.push(diff); } } @@ -97,7 +102,7 @@ export function diffParagraphs(oldParagraphs, newParagraphs) { const newPara = newParagraphs[nextStep.newIdx]; if (canTreatAsModification(oldPara, newPara)) { const diff = buildModifiedParagraphDiff(oldPara, newPara); - if (diff.textDiffs.length > 0) { + if (diff) { diffs.push(diff); } i += 1; // Skip the next insert step as it's paired @@ -179,12 +184,19 @@ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { newParagraph.resolvePosition, ); + const attrsDiff = getAttributesDiff(oldParagraph.node.attrs, newParagraph.node.attrs); + + if (textDiffs.length === 0 && !attrsDiff) { + return null; + } + return { type: 'modified', oldText: oldParagraph.text, newText: newParagraph.text, pos: oldParagraph.pos, textDiffs, + attrsDiff, }; } diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index fcd1772f7b..e1e707658d 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -5,6 +5,9 @@ import { Editor } from '@core/Editor.js'; import { getStarterExtensions } from '@extensions/index.js'; import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers.js'; +import { ChangeSet } from 'prosemirror-changeset'; +import { Transform } from 'prosemirror-transform'; + const getDocument = async (name) => { const buffer = await getTestDataAsBuffer(name); const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); @@ -32,10 +35,19 @@ describe('Diff', () => { const diffs = computeDiff(docBefore, docAfter); const getDiff = (type, predicate) => diffs.find((diff) => diff.type === type && predicate(diff)); - expect(diffs).toHaveLength(15); - expect(diffs.filter((diff) => diff.type === 'modified')).toHaveLength(5); - expect(diffs.filter((diff) => diff.type === 'added')).toHaveLength(5); - expect(diffs.filter((diff) => diff.type === 'deleted')).toHaveLength(5); + const modifiedDiffs = diffs.filter((diff) => diff.type === 'modified'); + const addedDiffs = diffs.filter((diff) => diff.type === 'added'); + const deletedDiffs = diffs.filter((diff) => diff.type === 'deleted'); + const attrOnlyDiffs = modifiedDiffs.filter((diff) => diff.textDiffs.length === 0); + + expect(diffs).toHaveLength(19); + expect(modifiedDiffs).toHaveLength(9); + expect(addedDiffs).toHaveLength(5); + expect(deletedDiffs).toHaveLength(5); + expect(attrOnlyDiffs).toHaveLength(4); + attrOnlyDiffs.forEach((diff) => { + expect(diff.attrsDiff).not.toBeNull(); + }); // Modified paragraph with multiple text diffs let diff = getDiff( @@ -109,6 +121,12 @@ describe('Diff', () => { (diff) => diff.text === 'Aenean hendrerit elit vitae sem fermentum, vel sagittis erat gravida.', ); expect(movedParagraph).toBeDefined(); + + // Attribute-only paragraph change + const namParagraph = attrOnlyDiffs.find( + (diff) => diff.oldText === 'Nam ultricies velit vitae purus eleifend pellentesque.', + ); + expect(namParagraph?.attrsDiff?.modified).toBeDefined(); }); it('Compare two documents with simple changes', async () => { @@ -123,6 +141,7 @@ describe('Diff', () => { expect(diff.newText).toBe('Here’s some NEW text.'); expect(diff.textDiffs).toHaveLength(1); expect(diff.textDiffs[0].text).toBe('NEW '); + expect(diff.attrsDiff?.modified?.textId).toBeDefined(); diff = diffs.find((diff) => diff.type === 'deleted' && diff.oldText === 'I deleted this sentence.'); expect(diff).toBeDefined(); @@ -133,5 +152,34 @@ describe('Diff', () => { diff = diffs.find((diff) => diff.type === 'modified' && diff.oldText === 'We are not done yet.'); expect(diff.newText).toBe('We are done now.'); expect(diff.textDiffs).toHaveLength(3); + expect(diff.attrsDiff?.modified?.textId).toBeDefined(); }); + + // it.only('Test prosemirror-changeset', async () => { + // const docA = await getDocument('diff_before.docx'); + // const docB = await getDocument('diff_after.docx'); + // + // // Produce StepMaps that turn A into B + // const tr = new Transform(docA) + // tr.replaceWith(0, docA.content.size, docB.content) + // + // // Diff them: metadata tags each span with the author + // const encoder = { + // encodeCharacter: (char, marks) => (JSON.stringify({type: "char", char, marks})), + // encodeNodeStart: node => (JSON.stringify({type: "open", name: node.type.name, attrs: node.attrs})), + // encodeNodeEnd: node => (JSON.stringify({type: "close", name: node.type.name})), + // compareTokens: (a, b) => JSON.stringify(a) === JSON.stringify(b) + // } + // const originalChangeSet = ChangeSet + // .create(docA, (a, b) => a === b ? a : null, encoder); + // + // debugger; + // const changeSet = originalChangeSet + // .addSteps(docB, tr.mapping.maps) + // + // // Inspect the replacements + // for (const change of changeSet.changes) { + // console.log(JSON.stringify(change, null, 2)); + // } + // }); }); From 738bdc98f78aebdc77be2dd457192ebb16542b12 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 23 Dec 2025 13:58:04 -0300 Subject: [PATCH 012/125] refactor: extract generic sequence diffing helper --- .../diffing/algorithm/sequence-diffing.js | 117 ++++++++++++++++++ .../algorithm/sequence-diffing.test.js | 73 +++++++++++ 2 files changed, 190 insertions(+) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js new file mode 100644 index 0000000000..523599086e --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js @@ -0,0 +1,117 @@ +import { myersDiff } from './myers-diff.js'; + +/** + * @typedef {Object} SequenceDiffOptions + * @property {(a: any, b: any) => boolean} [comparator] equality test passed to Myers diff + * @property {(item: any, index: number) => any} buildAdded maps newly inserted entries + * @property {(item: any, index: number) => any} buildDeleted maps removed entries + * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => any|null} buildModified maps paired entries + * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [shouldProcessEqual] decides if equal-aligned entries should emit a modification + * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [canTreatAsModification] determines if delete/insert pairs are modifications + * @property {(operations: Array<'equal'|'delete'|'insert'>) => Array<'equal'|'delete'|'insert'>} [reorderOperations] optional hook to normalize raw Myers operations + */ + +/** + * Generic sequence diff helper built on top of Myers algorithm. + * Allows callers to provide custom comparators and payload builders that determine how + * additions, deletions, and modifications should be reported. + * @param {Array} oldSeq + * @param {Array} newSeq + * @param {SequenceDiffOptions} options + * @returns {Array} + */ +export function diffSequences(oldSeq, newSeq, options) { + if (!options) { + throw new Error('diffSequences requires an options object.'); + } + + const comparator = options.comparator ?? ((a, b) => a === b); + const reorder = options.reorderOperations ?? ((ops) => ops); + const canTreatAsModification = options.canTreatAsModification; + const shouldProcessEqual = options.shouldProcessEqual; + + if (typeof options.buildAdded !== 'function') { + throw new Error('diffSequences requires a buildAdded option.'); + } + if (typeof options.buildDeleted !== 'function') { + throw new Error('diffSequences requires a buildDeleted option.'); + } + if (typeof options.buildModified !== 'function') { + throw new Error('diffSequences requires a buildModified option.'); + } + + const operations = reorder(myersDiff(oldSeq, newSeq, comparator)); + const steps = buildOperationSteps(operations); + + const diffs = []; + for (let i = 0; i < steps.length; i += 1) { + const step = steps[i]; + + if (step.type === 'equal') { + if (!shouldProcessEqual) { + continue; + } + const oldItem = oldSeq[step.oldIdx]; + const newItem = newSeq[step.newIdx]; + if (!shouldProcessEqual(oldItem, newItem, step.oldIdx, step.newIdx)) { + continue; + } + const diff = options.buildModified(oldItem, newItem, step.oldIdx, step.newIdx); + if (diff) { + diffs.push(diff); + } + continue; + } + + if (step.type === 'delete') { + const nextStep = steps[i + 1]; + if ( + nextStep?.type === 'insert' && + typeof canTreatAsModification === 'function' && + canTreatAsModification(oldSeq[step.oldIdx], newSeq[nextStep.newIdx], step.oldIdx, nextStep.newIdx) + ) { + const diff = options.buildModified(oldSeq[step.oldIdx], newSeq[nextStep.newIdx], step.oldIdx, nextStep.newIdx); + if (diff) { + diffs.push(diff); + } + i += 1; + } else { + diffs.push(options.buildDeleted(oldSeq[step.oldIdx], step.oldIdx)); + } + continue; + } + + if (step.type === 'insert') { + diffs.push(options.buildAdded(newSeq[step.newIdx], step.newIdx)); + } + } + + return diffs; +} + +/** + * Translates the raw Myers operations into indexed steps so higher-level logic can reason about positions. + * @param {Array<'equal'|'delete'|'insert'>} operations + * @returns {Array} + */ +function buildOperationSteps(operations) { + let oldIdx = 0; + let newIdx = 0; + const steps = []; + + for (const op of operations) { + if (op === 'equal') { + steps.push({ type: 'equal', oldIdx, newIdx }); + oldIdx += 1; + newIdx += 1; + } else if (op === 'delete') { + steps.push({ type: 'delete', oldIdx }); + oldIdx += 1; + } else if (op === 'insert') { + steps.push({ type: 'insert', newIdx }); + newIdx += 1; + } + } + + return steps; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js new file mode 100644 index 0000000000..1d7071ff1e --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js @@ -0,0 +1,73 @@ +import { describe, it, expect } from 'vitest'; +import { diffSequences } from './sequence-diffing.js'; + +const buildAdded = (item) => ({ type: 'added', id: item.id }); +const buildDeleted = (item) => ({ type: 'deleted', id: item.id }); +const buildModified = (oldItem, newItem) => ({ + type: 'modified', + id: oldItem.id ?? newItem.id, + from: oldItem.value, + to: newItem.value, +}); + +describe('diffSequences', () => { + it('detects modifications for equal-aligned items when requested', () => { + const oldSeq = [ + { id: 'a', value: 'Hello' }, + { id: 'b', value: 'World' }, + ]; + const newSeq = [ + { id: 'a', value: 'Hello' }, + { id: 'b', value: 'World!!!' }, + ]; + + const diffs = diffSequences(oldSeq, newSeq, { + comparator: (a, b) => a.id === b.id, + shouldProcessEqual: (oldItem, newItem) => oldItem.value !== newItem.value, + buildAdded, + buildDeleted, + buildModified, + }); + + expect(diffs).toEqual([{ type: 'modified', id: 'b', from: 'World', to: 'World!!!' }]); + }); + + it('pairs delete/insert operations into modifications when allowed', () => { + const oldSeq = [ + { id: 'a', value: 'Alpha' }, + { id: 'b', value: 'Beta' }, + ]; + const newSeq = [ + { id: 'a', value: 'Alpha' }, + { id: 'c', value: 'Beta v2' }, + ]; + + const diffs = diffSequences(oldSeq, newSeq, { + comparator: (a, b) => a.id === b.id, + canTreatAsModification: (oldItem, newItem) => oldItem.value[0] === newItem.value[0], + shouldProcessEqual: () => false, + buildAdded, + buildDeleted, + buildModified, + }); + + expect(diffs).toEqual([{ type: 'modified', id: 'b', from: 'Beta', to: 'Beta v2' }]); + }); + + it('emits additions and deletions when items cannot be paired', () => { + const oldSeq = [{ id: 'a', value: 'Foo' }]; + const newSeq = [{ id: 'b', value: 'Bar' }]; + + const diffs = diffSequences(oldSeq, newSeq, { + comparator: (a, b) => a.id === b.id, + buildAdded, + buildDeleted, + buildModified, + }); + + expect(diffs).toEqual([ + { type: 'deleted', id: 'a' }, + { type: 'added', id: 'b' }, + ]); + }); +}); From 5b1efa2f17fea1de91331c29790c26aeb83ea88a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 23 Dec 2025 14:08:51 -0300 Subject: [PATCH 013/125] refactor: modify paragraph diffing to reuse generic helper --- .../diffing/algorithm/paragraph-diffing.js | 85 +++---------------- 1 file changed, 12 insertions(+), 73 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index f093b33a88..6ae7a889c3 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -1,6 +1,7 @@ import { myersDiff } from './myers-diff.js'; import { getTextDiff } from './text-diffing.js'; import { getAttributesDiff } from './attributes-diffing.js'; +import { diffSequences } from './sequence-diffing.js'; import { levenshteinDistance } from './similarity.js'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. @@ -50,79 +51,17 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; * @returns {Array} */ export function diffParagraphs(oldParagraphs, newParagraphs) { - // Run Myers diff on the paragraph level to get a base set of operations. - const rawOperations = myersDiff(oldParagraphs, newParagraphs, paragraphComparator); - const operations = reorderParagraphOperations(rawOperations); - - // Build a step-by-step operation list with paragraph indices for easier processing. - let oldIdx = 0; - let newIdx = 0; - const steps = []; - for (const op of operations) { - if (op === 'equal') { - steps.push({ type: 'equal', oldIdx, newIdx }); - oldIdx += 1; - newIdx += 1; - } else if (op === 'delete') { - steps.push({ type: 'delete', oldIdx }); - oldIdx += 1; - } else if (op === 'insert') { - steps.push({ type: 'insert', newIdx }); - newIdx += 1; - } - } - - // Process the operation steps into a normalized diff output. - const diffs = []; - for (let i = 0; i < steps.length; i += 1) { - const step = steps[i]; - - switch (step.type) { - case 'equal': - const oldPara = oldParagraphs[step.oldIdx]; - const newPara = newParagraphs[step.newIdx]; - if ( - oldPara.text !== newPara.text || - JSON.stringify(oldPara.node.attrs) !== JSON.stringify(newPara.node.attrs) - ) { - // Text or attributes changed within the same paragraph - const diff = buildModifiedParagraphDiff(oldPara, newPara); - if (diff) { - diffs.push(diff); - } - } - break; - - case 'delete': - const nextStep = steps[i + 1]; - - // Check if the next step is an insertion that can be paired as a modification. - if (nextStep?.type === 'insert') { - const oldPara = oldParagraphs[step.oldIdx]; - const newPara = newParagraphs[nextStep.newIdx]; - if (canTreatAsModification(oldPara, newPara)) { - const diff = buildModifiedParagraphDiff(oldPara, newPara); - if (diff) { - diffs.push(diff); - } - i += 1; // Skip the next insert step as it's paired - } else { - // The paragraph that was deleted is significantly different from any nearby insertions; treat as a deletion. - diffs.push(buildDeletedParagraphDiff(oldParagraphs[step.oldIdx])); - } - } else { - // No matching insertion; treat as a deletion. - diffs.push(buildDeletedParagraphDiff(oldParagraphs[step.oldIdx])); - } - break; - - case 'insert': - diffs.push(buildAddedParagraphDiff(newParagraphs[step.newIdx])); - break; - } - } - - return diffs; + return diffSequences(oldParagraphs, newParagraphs, { + comparator: paragraphComparator, + reorderOperations: reorderParagraphOperations, + shouldProcessEqual: (oldParagraph, newParagraph) => + oldParagraph.text !== newParagraph.text || + JSON.stringify(oldParagraph.node.attrs) !== JSON.stringify(newParagraph.node.attrs), + canTreatAsModification, + buildAdded: (paragraph) => buildAddedParagraphDiff(paragraph), + buildDeleted: (paragraph) => buildDeletedParagraphDiff(paragraph), + buildModified: (oldParagraph, newParagraph) => buildModifiedParagraphDiff(oldParagraph, newParagraph), + }); } /** From 8b11027e1211db0caa5d87d5136f20cbd97dc61c Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 23 Dec 2025 17:19:14 -0300 Subject: [PATCH 014/125] refactor: extract operation reordering function This function can then be reused when diffing paragraphs and runs. It helps identifying modifications instead of delete/insert pairs --- .../diffing/algorithm/paragraph-diffing.js | 42 +---------------- .../diffing/algorithm/sequence-diffing.js | 47 ++++++++++++++++++- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index 6ae7a889c3..3ff1e4400d 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -1,7 +1,7 @@ import { myersDiff } from './myers-diff.js'; import { getTextDiff } from './text-diffing.js'; import { getAttributesDiff } from './attributes-diffing.js'; -import { diffSequences } from './sequence-diffing.js'; +import { diffSequences, reorderDiffOperations } from './sequence-diffing.js'; import { levenshteinDistance } from './similarity.js'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. @@ -187,42 +187,4 @@ function getTextSimilarityScore(oldText, newText) { * @param {Array<'equal'|'delete'|'insert'>} operations * @returns {Array<'equal'|'delete'|'insert'>} */ -function reorderParagraphOperations(operations) { - const normalized = []; - - for (let i = 0; i < operations.length; i += 1) { - const op = operations[i]; - if (op !== 'delete') { - normalized.push(op); - continue; - } - - let deleteCount = 0; - while (i < operations.length && operations[i] === 'delete') { - deleteCount += 1; - i += 1; - } - - let insertCount = 0; - let insertCursor = i; - while (insertCursor < operations.length && operations[insertCursor] === 'insert') { - insertCount += 1; - insertCursor += 1; - } - - const pairCount = Math.min(deleteCount, insertCount); - for (let k = 0; k < pairCount; k += 1) { - normalized.push('delete', 'insert'); - } - for (let k = pairCount; k < deleteCount; k += 1) { - normalized.push('delete'); - } - for (let k = pairCount; k < insertCount; k += 1) { - normalized.push('insert'); - } - - i = insertCursor - 1; - } - - return normalized; -} +const reorderParagraphOperations = reorderDiffOperations; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js index 523599086e..a8d7a9c9d6 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js @@ -5,7 +5,7 @@ import { myersDiff } from './myers-diff.js'; * @property {(a: any, b: any) => boolean} [comparator] equality test passed to Myers diff * @property {(item: any, index: number) => any} buildAdded maps newly inserted entries * @property {(item: any, index: number) => any} buildDeleted maps removed entries - * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => any|null} buildModified maps paired entries + * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => any|null} buildModified maps paired entries. If it returns null/undefined, it means no modification should be recorded. * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [shouldProcessEqual] decides if equal-aligned entries should emit a modification * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [canTreatAsModification] determines if delete/insert pairs are modifications * @property {(operations: Array<'equal'|'delete'|'insert'>) => Array<'equal'|'delete'|'insert'>} [reorderOperations] optional hook to normalize raw Myers operations @@ -115,3 +115,48 @@ function buildOperationSteps(operations) { return steps; } + +/** + * Normalizes interleaved delete/insert operations so consumers can treat replacements as paired steps. + * @param {Array<'equal'|'delete'|'insert'>} operations + * @returns {Array<'equal'|'delete'|'insert'>} + */ +export function reorderDiffOperations(operations) { + const normalized = []; + + for (let i = 0; i < operations.length; i += 1) { + const op = operations[i]; + if (op !== 'delete') { + normalized.push(op); + continue; + } + + let deleteCount = 0; + while (i < operations.length && operations[i] === 'delete') { + deleteCount += 1; + i += 1; + } + + let insertCount = 0; + let insertCursor = i; + while (insertCursor < operations.length && operations[insertCursor] === 'insert') { + insertCount += 1; + insertCursor += 1; + } + + const pairCount = Math.min(deleteCount, insertCount); + for (let k = 0; k < pairCount; k += 1) { + normalized.push('delete', 'insert'); + } + for (let k = pairCount; k < deleteCount; k += 1) { + normalized.push('delete'); + } + for (let k = pairCount; k < insertCount; k += 1) { + normalized.push('insert'); + } + + i = insertCursor - 1; + } + + return normalized; +} From 6760d6eaebad1428fc356f02c1d42d14d6f63e44 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 23 Dec 2025 17:20:42 -0300 Subject: [PATCH 015/125] fix: standardize positions for text diffing Always maps starting/ending positions to the old document instead of the new one. --- .../diffing/algorithm/text-diffing.js | 38 ++++++------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js index 43781c0fa1..85d8947339 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js @@ -46,26 +46,15 @@ function buildDiffFromOperations(operations, oldText, newText, oldPositionResolv return; } - if (change.type === 'delete') { - const startIdx = resolveOld(change.startOldIdx); - const endIdx = resolveOld(change.endOldIdx); - diffs.push({ - type: 'deletion', - startIdx, - endIdx, - text: change.text, - }); - } else if (change.type === 'insert') { - const startIdx = resolveNew(change.startNewIdx); - const endIdx = resolveNew(change.endNewIdx); - diffs.push({ - type: 'addition', - startIdx, - endIdx, - text: change.text, - }); - } - + const startPos = resolveOld(change.startIdx); + const endPos = resolveOld(change.endIdx); + + diffs.push({ + type: change.type, + startPos, + endPos, + text: change.text, + }); change = null; }; @@ -79,21 +68,16 @@ function buildDiffFromOperations(operations, oldText, newText, oldPositionResolv if (!change || change.type !== op) { flushChange(); - if (op === 'delete') { - change = { type: 'delete', startOldIdx: oldIdx, endOldIdx: oldIdx, text: '' }; - } else if (op === 'insert') { - change = { type: 'insert', startNewIdx: newIdx, endNewIdx: newIdx, text: '' }; - } + change = { type: op, startIdx: oldIdx, endIdx: oldIdx, text: '' }; } if (op === 'delete') { change.text += oldText[oldIdx]; + change.endIdx += 1; oldIdx += 1; - change.endOldIdx = oldIdx; } else if (op === 'insert') { change.text += newText[newIdx]; newIdx += 1; - change.endNewIdx = newIdx; } } From 9c4f97569be8421ded9fd400c2a907d784ed8ab4 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 26 Dec 2025 11:48:25 -0300 Subject: [PATCH 016/125] refactor: change text diffing logic to account for formatting --- .../diffing/algorithm/paragraph-diffing.js | 31 +-- .../algorithm/paragraph-diffing.test.js | 23 +- .../diffing/algorithm/sequence-diffing.js | 16 +- .../algorithm/sequence-diffing.test.js | 4 +- .../diffing/algorithm/text-diffing.js | 203 +++++++++--------- .../diffing/algorithm/text-diffing.test.js | 84 +++++--- .../extensions/diffing/computeDiff.test.js | 53 ++--- .../src/extensions/diffing/utils.js | 22 +- .../src/extensions/diffing/utils.test.js | 125 +++++------ .../src/tests/data/diff_after3.docx | Bin 0 -> 13380 bytes .../src/tests/data/diff_after4.docx | Bin 0 -> 13345 bytes .../src/tests/data/diff_before3.docx | Bin 0 -> 13370 bytes .../src/tests/data/diff_before4.docx | Bin 0 -> 13370 bytes 13 files changed, 287 insertions(+), 274 deletions(-) create mode 100644 packages/super-editor/src/tests/data/diff_after3.docx create mode 100644 packages/super-editor/src/tests/data/diff_after4.docx create mode 100644 packages/super-editor/src/tests/data/diff_before3.docx create mode 100644 packages/super-editor/src/tests/data/diff_before4.docx diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index 3ff1e4400d..feeafecd40 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -53,9 +53,9 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; export function diffParagraphs(oldParagraphs, newParagraphs) { return diffSequences(oldParagraphs, newParagraphs, { comparator: paragraphComparator, - reorderOperations: reorderParagraphOperations, - shouldProcessEqual: (oldParagraph, newParagraph) => - oldParagraph.text !== newParagraph.text || + reorderOperations: reorderDiffOperations, + shouldProcessEqualAsModification: (oldParagraph, newParagraph) => + JSON.stringify(oldParagraph.text) !== JSON.stringify(newParagraph.text) || JSON.stringify(oldParagraph.node.attrs) !== JSON.stringify(newParagraph.node.attrs), canTreatAsModification, buildAdded: (paragraph) => buildAddedParagraphDiff(paragraph), @@ -78,7 +78,7 @@ function paragraphComparator(oldParagraph, newParagraph) { if (oldId && newId && oldId === newId) { return true; } - return oldParagraph?.text === newParagraph?.text; + return oldParagraph?.fullText === newParagraph?.fullText; } /** @@ -90,7 +90,7 @@ function buildAddedParagraphDiff(paragraph) { return { type: 'added', node: paragraph.node, - text: paragraph.text, + text: paragraph.fullText, pos: paragraph.pos, }; } @@ -104,7 +104,7 @@ function buildDeletedParagraphDiff(paragraph) { return { type: 'deleted', node: paragraph.node, - oldText: paragraph.text, + oldText: paragraph.fullText, pos: paragraph.pos, }; } @@ -124,15 +124,14 @@ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { ); const attrsDiff = getAttributesDiff(oldParagraph.node.attrs, newParagraph.node.attrs); - if (textDiffs.length === 0 && !attrsDiff) { return null; } return { type: 'modified', - oldText: oldParagraph.text, - newText: newParagraph.text, + oldText: oldParagraph.fullText, + newText: newParagraph.fullText, pos: oldParagraph.pos, textDiffs, attrsDiff, @@ -151,8 +150,8 @@ function canTreatAsModification(oldParagraph, newParagraph) { return true; } - const oldText = oldParagraph?.text ?? ''; - const newText = newParagraph?.text ?? ''; + const oldText = oldParagraph.fullText; + const newText = newParagraph.fullText; const maxLength = Math.max(oldText.length, newText.length); if (maxLength < MIN_LENGTH_FOR_SIMILARITY) { return false; @@ -178,13 +177,3 @@ function getTextSimilarityScore(oldText, newText) { const maxLength = Math.max(oldText.length, newText.length) || 1; return 1 - distance / maxLength; } - -/** - * Normalizes Myers diff operations for paragraph comparisons so consecutive replacements are easier to classify. - * Myers tends to emit all deletes before inserts when a paragraph is replaced, even if it's a one-for-one swap, and - * that pattern would otherwise hide opportunities to treat those operations as modifications. Reordering the list here - * ensures higher-level diff logic stays simple while avoiding side effects for other consumers of the same operations. - * @param {Array<'equal'|'delete'|'insert'>} operations - * @returns {Array<'equal'|'delete'|'insert'>} - */ -const reorderParagraphOperations = reorderDiffOperations; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index 6c3edce933..f81180663a 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -1,12 +1,23 @@ import { describe, it, expect } from 'vitest'; import { diffParagraphs } from './paragraph-diffing.js'; -const createParagraph = (text, attrs = {}) => ({ - node: { attrs }, - pos: attrs.pos ?? 0, - text, - resolvePosition: (index) => index, -}); +const buildTextRuns = (text, runAttrs = {}) => + text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs) })); + +const createParagraph = (text, attrs = {}, options = {}) => { + const { pos = 0, textAttrs = {} } = options; + const textRuns = buildTextRuns(text, textAttrs); + + return { + node: { attrs }, + pos, + text: textRuns, + resolvePosition: (index) => pos + 1 + index, + get fullText() { + return textRuns.map((c) => c.char).join(''); + }, + }; +}; describe('diffParagraphs', () => { it('treats similar paragraphs without IDs as modifications', () => { diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js index a8d7a9c9d6..68af0d854a 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js @@ -6,7 +6,7 @@ import { myersDiff } from './myers-diff.js'; * @property {(item: any, index: number) => any} buildAdded maps newly inserted entries * @property {(item: any, index: number) => any} buildDeleted maps removed entries * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => any|null} buildModified maps paired entries. If it returns null/undefined, it means no modification should be recorded. - * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [shouldProcessEqual] decides if equal-aligned entries should emit a modification + * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [shouldProcessEqualAsModification] decides if equal-aligned entries should emit a modification * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [canTreatAsModification] determines if delete/insert pairs are modifications * @property {(operations: Array<'equal'|'delete'|'insert'>) => Array<'equal'|'delete'|'insert'>} [reorderOperations] optional hook to normalize raw Myers operations */ @@ -28,7 +28,7 @@ export function diffSequences(oldSeq, newSeq, options) { const comparator = options.comparator ?? ((a, b) => a === b); const reorder = options.reorderOperations ?? ((ops) => ops); const canTreatAsModification = options.canTreatAsModification; - const shouldProcessEqual = options.shouldProcessEqual; + const shouldProcessEqualAsModification = options.shouldProcessEqualAsModification; if (typeof options.buildAdded !== 'function') { throw new Error('diffSequences requires a buildAdded option.'); @@ -48,12 +48,12 @@ export function diffSequences(oldSeq, newSeq, options) { const step = steps[i]; if (step.type === 'equal') { - if (!shouldProcessEqual) { + if (!shouldProcessEqualAsModification) { continue; } const oldItem = oldSeq[step.oldIdx]; const newItem = newSeq[step.newIdx]; - if (!shouldProcessEqual(oldItem, newItem, step.oldIdx, step.newIdx)) { + if (!shouldProcessEqualAsModification(oldItem, newItem, step.oldIdx, step.newIdx)) { continue; } const diff = options.buildModified(oldItem, newItem, step.oldIdx, step.newIdx); @@ -76,13 +76,13 @@ export function diffSequences(oldSeq, newSeq, options) { } i += 1; } else { - diffs.push(options.buildDeleted(oldSeq[step.oldIdx], step.oldIdx)); + diffs.push(options.buildDeleted(oldSeq[step.oldIdx], step.oldIdx, step.newIdx)); } continue; } if (step.type === 'insert') { - diffs.push(options.buildAdded(newSeq[step.newIdx], step.newIdx)); + diffs.push(options.buildAdded(newSeq[step.newIdx], step.oldIdx, step.newIdx)); } } @@ -105,10 +105,10 @@ function buildOperationSteps(operations) { oldIdx += 1; newIdx += 1; } else if (op === 'delete') { - steps.push({ type: 'delete', oldIdx }); + steps.push({ type: 'delete', oldIdx, newIdx }); oldIdx += 1; } else if (op === 'insert') { - steps.push({ type: 'insert', newIdx }); + steps.push({ type: 'insert', oldIdx, newIdx }); newIdx += 1; } } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js index 1d7071ff1e..4f771cd123 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js @@ -23,7 +23,7 @@ describe('diffSequences', () => { const diffs = diffSequences(oldSeq, newSeq, { comparator: (a, b) => a.id === b.id, - shouldProcessEqual: (oldItem, newItem) => oldItem.value !== newItem.value, + shouldProcessEqualAsModification: (oldItem, newItem) => oldItem.value !== newItem.value, buildAdded, buildDeleted, buildModified, @@ -45,7 +45,7 @@ describe('diffSequences', () => { const diffs = diffSequences(oldSeq, newSeq, { comparator: (a, b) => a.id === b.id, canTreatAsModification: (oldItem, newItem) => oldItem.value[0] === newItem.value[0], - shouldProcessEqual: () => false, + shouldProcessEqualAsModification: () => false, buildAdded, buildDeleted, buildModified, diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js index 85d8947339..b6bff482b7 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js @@ -1,128 +1,119 @@ import { myersDiff } from './myers-diff.js'; +import { getAttributesDiff } from './attributes-diffing.js'; +import { diffSequences } from './sequence-diffing.js'; /** * Computes text-level additions and deletions between two strings using Myers diff algorithm, mapping back to document positions. - * @param {string} oldText - Source text. - * @param {string} newText - Target text. + * @param {{char: string, runAttrs: Record}[]} oldText - Source text. + * @param {{char: string, runAttrs: Record}[]} newText - Target text. * @param {(index: number) => number|null} oldPositionResolver - Maps string indexes to the original document. * @param {(index: number) => number|null} [newPositionResolver=oldPositionResolver] - Maps string indexes to the updated document. * @returns {Array} List of addition/deletion ranges with document positions and text content. */ export function getTextDiff(oldText, newText, oldPositionResolver, newPositionResolver = oldPositionResolver) { - const oldLen = oldText.length; - const newLen = newText.length; - - if (oldLen === 0 && newLen === 0) { - return []; - } - - const operations = myersDiff(oldText, newText, (a, b) => a === b); - const normalizedOperations = reorderTextOperations(operations); - return buildDiffFromOperations(normalizedOperations, oldText, newText, oldPositionResolver, newPositionResolver); + const buildCharDiff = (type, char, oldIdx) => ({ + type, + idx: oldIdx, + text: char.char, + runAttrs: char.runAttrs, + }); + let diffs = diffSequences(oldText, newText, { + comparator: (a, b) => a.char === b.char, + shouldProcessEqualAsModification: (oldChar, newChar) => oldChar.runAttrs !== newChar.runAttrs, + canTreatAsModification: (oldChar, newChar) => false, + buildAdded: (char, oldIdx, newIdx) => buildCharDiff('added', char, oldIdx), + buildDeleted: (char, oldIdx, newIdx) => buildCharDiff('deleted', char, oldIdx), + buildModified: (oldChar, newChar, oldIdx, newIdx) => ({ + type: 'modified', + idx: oldIdx, + newText: newChar.char, + oldText: oldChar.char, + oldAttrs: oldChar.runAttrs, + newAttrs: newChar.runAttrs, + }), + }); + + const groupedDiffs = groupDiffs(diffs, oldPositionResolver, newPositionResolver); + return groupedDiffs; } -/** - * Groups edit operations into contiguous additions/deletions and maps them to document positions. - * - * @param {Array<'equal'|'delete'|'insert'>} operations - Raw operation list produced by the backtracked Myers path. - * @param {string} oldText - Source text. - * @param {string} newText - Target text. - * @param {(index: number) => number|null} oldPositionResolver - Maps string indexes to the previous document. - * @param {(index: number) => number|null} newPositionResolver - Maps string indexes to the updated document. - * @returns {Array} Final diff payload matching the existing API surface. - */ -function buildDiffFromOperations(operations, oldText, newText, oldPositionResolver, newPositionResolver) { - const diffs = []; - let change = null; - let oldIdx = 0; - let newIdx = 0; - const resolveOld = oldPositionResolver ?? (() => null); - const resolveNew = newPositionResolver ?? resolveOld; +function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { + const grouped = []; + let currentGroup = null; - /** Flushes the current change block into the diffs list. */ - const flushChange = () => { - if (!change || change.text.length === 0) { - change = null; - return; + const compareDiffs = (group, diff) => { + if (group.type !== diff.type) { + return false; } - - const startPos = resolveOld(change.startIdx); - const endPos = resolveOld(change.endIdx); - - diffs.push({ - type: change.type, - startPos, - endPos, - text: change.text, - }); - change = null; - }; - - for (const op of operations) { - if (op === 'equal') { - flushChange(); - oldIdx += 1; - newIdx += 1; - continue; - } - - if (!change || change.type !== op) { - flushChange(); - change = { type: op, startIdx: oldIdx, endIdx: oldIdx, text: '' }; + if (group.type === 'modified') { + return group.oldAttrs === diff.oldAttrs && group.newAttrs === diff.newAttrs; } + return group.runAttrs === diff.runAttrs; + }; - if (op === 'delete') { - change.text += oldText[oldIdx]; - change.endIdx += 1; - oldIdx += 1; - } else if (op === 'insert') { - change.text += newText[newIdx]; - newIdx += 1; - } - } - - flushChange(); - - return diffs; -} - -/** - * Normalizes the Myers operation list so contiguous edit regions are represented by single delete/insert runs. - * Myers may emit interleaved delete/insert steps for a single contiguous region, which would otherwise show up as - * multiple discrete diff entries even though the user edited one continuous block. - * @param {Array<'equal'|'delete'|'insert'>} operations - * @returns {Array<'equal'|'delete'|'insert'>} - */ -function reorderTextOperations(operations) { - const normalized = []; - - for (let i = 0; i < operations.length; i += 1) { - const op = operations[i]; - if (op === 'equal') { - normalized.push(op); - continue; + const comparePositions = (group, diff) => { + if (group.type === 'added') { + return group.startPos === oldPositionResolver(diff.idx); + } else { + return group.endPos + 1 === oldPositionResolver(diff.idx); } + }; - let deleteCount = 0; - let insertCount = 0; - while (i < operations.length && operations[i] !== 'equal') { - if (operations[i] === 'delete') { - deleteCount += 1; - } else if (operations[i] === 'insert') { - insertCount += 1; + for (const diff of diffs) { + if (currentGroup == null) { + currentGroup = { + type: diff.type, + startPos: oldPositionResolver(diff.idx), + endPos: oldPositionResolver(diff.idx), + }; + if (diff.type === 'modified') { + currentGroup.newText = diff.newText; + currentGroup.oldText = diff.oldText; + currentGroup.oldAttrs = diff.oldAttrs; + currentGroup.newAttrs = diff.newAttrs; + } else { + currentGroup.text = diff.text; + currentGroup.runAttrs = diff.runAttrs; + } + } else if (!compareDiffs(currentGroup, diff) || !comparePositions(currentGroup, diff)) { + grouped.push(currentGroup); + currentGroup = { + type: diff.type, + startPos: oldPositionResolver(diff.idx), + endPos: oldPositionResolver(diff.idx), + }; + if (diff.type === 'modified') { + currentGroup.newText = diff.newText; + currentGroup.oldText = diff.oldText; + currentGroup.oldAttrs = diff.oldAttrs; + currentGroup.newAttrs = diff.newAttrs; + } else { + currentGroup.text = diff.text; + currentGroup.runAttrs = diff.runAttrs; + } + } else { + currentGroup.endPos = oldPositionResolver(diff.idx); + if (diff.type === 'modified') { + currentGroup.newText += diff.newText; + currentGroup.oldText += diff.oldText; + } else { + currentGroup.text += diff.text; } - i += 1; - } - - for (let k = 0; k < deleteCount; k += 1) { - normalized.push('delete'); - } - for (let k = 0; k < insertCount; k += 1) { - normalized.push('insert'); } - - i -= 1; // account for the for-loop increment since we advanced i while counting } - return normalized; + if (currentGroup != null) grouped.push(currentGroup); + return grouped.map((group) => { + let ret = { ...group }; + if (group.type === 'modified') { + ret.oldAttrs = JSON.parse(group.oldAttrs); + ret.newAttrs = JSON.parse(group.newAttrs); + ret.runAttrsDiff = getAttributesDiff(ret.oldAttrs, ret.newAttrs); + delete ret.oldAttrs; + delete ret.newAttrs; + } else { + ret.runAttrs = JSON.parse(group.runAttrs); + } + return ret; + }); } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js index c3b6e84c4a..9f3005a2a7 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js @@ -5,14 +5,15 @@ vi.mock('./myers-diff.js', async () => { myersDiff: vi.fn(actual.myersDiff), }; }); -import { getTextDiff } from './text-diffing'; -import { myersDiff } from './myers-diff.js'; +import { getTextDiff } from './text-diffing.js'; + +const buildTextRuns = (text, runAttrs = {}) => + text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs) })); describe('getTextDiff', () => { it('returns an empty diff list when both strings are identical', () => { - const resolver = () => 0; - - const diffs = getTextDiff('unchanged', 'unchanged', resolver); + const resolver = (index) => index; + const diffs = getTextDiff(buildTextRuns('unchanged'), buildTextRuns('unchanged'), resolver); expect(diffs).toEqual([]); }); @@ -21,14 +22,15 @@ describe('getTextDiff', () => { const oldResolver = (index) => index + 10; const newResolver = (index) => index + 100; - const diffs = getTextDiff('abc', 'abXc', oldResolver, newResolver); + const diffs = getTextDiff(buildTextRuns('abc'), buildTextRuns('abXc'), oldResolver, newResolver); expect(diffs).toEqual([ { - type: 'addition', - startIdx: 102, - endIdx: 103, + type: 'added', + startPos: 12, + endPos: 12, text: 'X', + runAttrs: {}, }, ]); }); @@ -37,44 +39,66 @@ describe('getTextDiff', () => { const oldResolver = (index) => index + 5; const newResolver = (index) => index + 20; - const diffs = getTextDiff('abcd', 'abXYd', oldResolver, newResolver); + const diffs = getTextDiff(buildTextRuns('abcd'), buildTextRuns('abXYd'), oldResolver, newResolver); expect(diffs).toEqual([ { - type: 'deletion', - startIdx: 7, - endIdx: 8, + type: 'deleted', + startPos: 7, + endPos: 7, text: 'c', + runAttrs: {}, }, { - type: 'addition', - startIdx: 22, - endIdx: 24, + type: 'added', + startPos: 8, + endPos: 8, text: 'XY', + runAttrs: {}, }, ]); }); - it('merges interleaved delete/insert steps within a contiguous change', () => { - const oldResolver = (index) => index + 1; - const newResolver = (index) => index + 50; - const customOperations = ['delete', 'insert', 'delete', 'insert']; - myersDiff.mockImplementationOnce(() => customOperations); + it('marks attribute-only changes as modifications and surfaces attribute diffs', () => { + const resolver = (index) => index; - const diffs = getTextDiff('ab', 'XY', oldResolver, newResolver); + const diffs = getTextDiff(buildTextRuns('a', { bold: true }), buildTextRuns('a', { italic: true }), resolver); expect(diffs).toEqual([ { - type: 'deletion', - startIdx: 1, - endIdx: 3, - text: 'ab', + type: 'modified', + startPos: 0, + endPos: 0, + oldText: 'a', + newText: 'a', + runAttrsDiff: { + added: { italic: true }, + deleted: { bold: true }, + modified: {}, + }, }, + ]); + }); + + it('merges contiguous attribute edits that share the same diff metadata', () => { + const resolver = (index) => index + 5; + + const diffs = getTextDiff(buildTextRuns('ab', { bold: true }), buildTextRuns('ab', { bold: false }), resolver); + + expect(diffs).toEqual([ { - type: 'addition', - startIdx: 50, - endIdx: 52, - text: 'XY', + type: 'modified', + startPos: 5, + endPos: 6, + oldText: 'ab', + newText: 'ab', + runAttrsDiff: { + added: {}, + deleted: {}, + modified: { + bold: { from: true, to: false }, + }, + }, }, ]); }); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index e1e707658d..d059891ea3 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -5,9 +5,6 @@ import { Editor } from '@core/Editor.js'; import { getStarterExtensions } from '@extensions/index.js'; import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers.js'; -import { ChangeSet } from 'prosemirror-changeset'; -import { Transform } from 'prosemirror-transform'; - const getDocument = async (name) => { const buffer = await getTestDataAsBuffer(name); const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); @@ -45,9 +42,6 @@ describe('Diff', () => { expect(addedDiffs).toHaveLength(5); expect(deletedDiffs).toHaveLength(5); expect(attrOnlyDiffs).toHaveLength(4); - attrOnlyDiffs.forEach((diff) => { - expect(diff.attrsDiff).not.toBeNull(); - }); // Modified paragraph with multiple text diffs let diff = getDiff( @@ -57,7 +51,9 @@ describe('Diff', () => { expect(diff?.newText).toBe( 'Curabitur facilisis ligula suscipit enim pretium et nunc ligula, porttitor augue consequat maximus.', ); - expect(diff?.textDiffs).toHaveLength(6); + const textPropsChanges = diff?.textDiffs.filter((textDiff) => textDiff.type === 'modified'); + expect(textPropsChanges).toHaveLength(18); + expect(diff?.textDiffs).toHaveLength(24); // Deleted paragraph diff = getDiff( @@ -139,8 +135,10 @@ describe('Diff', () => { let diff = diffs.find((diff) => diff.type === 'modified' && diff.oldText === 'Here’s some text.'); expect(diff.newText).toBe('Here’s some NEW text.'); - expect(diff.textDiffs).toHaveLength(1); - expect(diff.textDiffs[0].text).toBe('NEW '); + expect(diff.textDiffs).toHaveLength(3); + expect(diff.textDiffs[0].newText).toBe(' '); + expect(diff.textDiffs[1].text).toBe('NEW'); + expect(diff.textDiffs[2].text).toBe(' '); expect(diff.attrsDiff?.modified?.textId).toBeDefined(); diff = diffs.find((diff) => diff.type === 'deleted' && diff.oldText === 'I deleted this sentence.'); @@ -155,31 +153,14 @@ describe('Diff', () => { expect(diff.attrsDiff?.modified?.textId).toBeDefined(); }); - // it.only('Test prosemirror-changeset', async () => { - // const docA = await getDocument('diff_before.docx'); - // const docB = await getDocument('diff_after.docx'); - // - // // Produce StepMaps that turn A into B - // const tr = new Transform(docA) - // tr.replaceWith(0, docA.content.size, docB.content) - // - // // Diff them: metadata tags each span with the author - // const encoder = { - // encodeCharacter: (char, marks) => (JSON.stringify({type: "char", char, marks})), - // encodeNodeStart: node => (JSON.stringify({type: "open", name: node.type.name, attrs: node.attrs})), - // encodeNodeEnd: node => (JSON.stringify({type: "close", name: node.type.name})), - // compareTokens: (a, b) => JSON.stringify(a) === JSON.stringify(b) - // } - // const originalChangeSet = ChangeSet - // .create(docA, (a, b) => a === b ? a : null, encoder); - // - // debugger; - // const changeSet = originalChangeSet - // .addSteps(docB, tr.mapping.maps) - // - // // Inspect the replacements - // for (const change of changeSet.changes) { - // console.log(JSON.stringify(change, null, 2)); - // } - // }); + it('Compare another set of two documents with only formatting changes', async () => { + const docBefore = await getDocument('diff_before4.docx'); + const docAfter = await getDocument('diff_after4.docx'); + + const diffs = computeDiff(docBefore, docAfter); + + expect(diffs).toHaveLength(1); + const diff = diffs[0]; + expect(diff.type).toBe('modified'); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/utils.js b/packages/super-editor/src/extensions/diffing/utils.js index 3b4cc56abf..1336865309 100644 --- a/packages/super-editor/src/extensions/diffing/utils.js +++ b/packages/super-editor/src/extensions/diffing/utils.js @@ -2,10 +2,10 @@ * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. * @param {Node} paragraph - Paragraph node to flatten. * @param {number} [paragraphPos=0] - Position of the paragraph in the document. - * @returns {{text: string, resolvePosition: (index: number) => number|null}} Concatenated text and position resolver. + * @returns {{text: {char: string, runAttrs: Record}[], resolvePosition: (index: number) => number|null}} Concatenated text and position resolver. */ export function getTextContent(paragraph, paragraphPos = 0) { - let text = ''; + let text = []; const segments = []; paragraph.nodesBetween( @@ -27,8 +27,12 @@ export function getTextContent(paragraph, paragraphPos = 0) { const start = text.length; const end = start + nodeText.length; - segments.push({ start, end, pos }); - text += nodeText; + // Get parent run node and its attributes + const runNode = paragraph.nodeAt(pos - 1); + const runAttrs = runNode.attrs || {}; + + segments.push({ start, end, pos, runAttrs }); + text = text.concat(nodeText.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs) }))); }, 0, ); @@ -61,7 +65,15 @@ export function extractParagraphs(pmDoc) { pmDoc.descendants((node, pos) => { if (node.type.name === 'paragraph') { const { text, resolvePosition } = getTextContent(node, pos); - paragraphs.push({ node, pos, text, resolvePosition }); + paragraphs.push({ + node, + pos, + text, + resolvePosition, + get fullText() { + return text.map((c) => c.char).join(''); + }, + }); return false; // Do not descend further } }); diff --git a/packages/super-editor/src/extensions/diffing/utils.test.js b/packages/super-editor/src/extensions/diffing/utils.test.js index 1c3dd9ddbc..fbf85fa726 100644 --- a/packages/super-editor/src/extensions/diffing/utils.test.js +++ b/packages/super-editor/src/extensions/diffing/utils.test.js @@ -1,11 +1,7 @@ import { extractParagraphs, getTextContent } from './utils'; -/** - * Creates a lightweight mock paragraph node for tests. - * @param {string} text - * @param {Record} [attrs={}] - * @returns {object} - */ +const buildRuns = (text, attrs = {}) => text.split('').map((char) => ({ char, runAttrs: JSON.stringify(attrs) })); + const createParagraphNode = (text, attrs = {}) => ({ type: { name: 'paragraph' }, attrs, @@ -14,8 +10,42 @@ const createParagraphNode = (text, attrs = {}) => ({ nodesBetween: (from, to, callback) => { callback({ isText: true, text }, 0); }, + nodeAt: () => ({ attrs }), }); +const createParagraphWithSegments = (segments, contentSize) => { + const computedSegments = segments.map((segment) => { + const segmentText = segment.text ?? segment.leafText(); + const length = segmentText.length; + return { + ...segment, + length, + start: segment.start ?? 0, + attrs: segment.attrs ?? {}, + }; + }); + const size = + contentSize ?? computedSegments.reduce((max, segment) => Math.max(max, segment.start + segment.length), 0); + const attrsMap = new Map(); + computedSegments.forEach((segment) => { + attrsMap.set(segment.start - 1, segment.attrs); + }); + + return { + content: { size }, + nodesBetween: (from, to, callback) => { + computedSegments.forEach((segment) => { + if (segment.text != null) { + callback({ isText: true, text: segment.text }, segment.start); + } else { + callback({ isLeaf: true, type: { spec: { leafText: segment.leafText } } }, segment.start); + } + }); + }, + nodeAt: (pos) => ({ attrs: attrsMap.get(pos) ?? {} }), + }; +}; + describe('extractParagraphs', () => { it('collects paragraph nodes in document order', () => { const firstParagraph = createParagraphNode('First paragraph', { paraId: 'para-1' }); @@ -35,8 +65,11 @@ describe('extractParagraphs', () => { const paragraphs = extractParagraphs(pmDoc); expect(paragraphs).toHaveLength(2); - expect(paragraphs[0]).toMatchObject({ node: firstParagraph, pos: 0, text: 'First paragraph' }); - expect(paragraphs[1]).toMatchObject({ node: secondParagraph, pos: 10, text: 'Second paragraph' }); + expect(paragraphs[0]).toMatchObject({ node: firstParagraph, pos: 0 }); + expect(paragraphs[0].text).toEqual(buildRuns('First paragraph', { paraId: 'para-1' })); + expect(paragraphs[0].fullText).toBe('First paragraph'); + expect(paragraphs[1]).toMatchObject({ node: secondParagraph, pos: 10 }); + expect(paragraphs[1].text).toEqual(buildRuns('Second paragraph', { paraId: 'para-2' })); }); it('includes position resolvers for paragraphs with missing IDs', () => { @@ -60,82 +93,54 @@ describe('extractParagraphs', () => { }); describe('getTextContent', () => { - it('Handles basic text nodes', () => { - const mockParagraph = { - content: { - size: 5, - }, - nodesBetween: (from, to, callback) => { - callback({ isText: true, text: 'Hello' }, 0); - }, - }; + it('handles basic text nodes', () => { + const mockParagraph = createParagraphWithSegments([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); const result = getTextContent(mockParagraph); - expect(result.text).toBe('Hello'); + expect(result.text).toEqual(buildRuns('Hello', { bold: true })); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(4)).toBe(5); }); - it('Handles leaf nodes with leafText', () => { - const mockParagraph = { - content: { - size: 4, - }, - nodesBetween: (from, to, callback) => { - callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 0); - }, - }; + it('handles leaf nodes with leafText', () => { + const mockParagraph = createParagraphWithSegments( + [{ leafText: () => 'Leaf', start: 0, attrs: { type: 'leaf' } }], + 4, + ); const result = getTextContent(mockParagraph); - expect(result.text).toBe('Leaf'); + expect(result.text).toEqual(buildRuns('Leaf', { type: 'leaf' })); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(3)).toBe(4); }); - it('Handles mixed content', () => { - const mockParagraph = { - content: { - size: 9, - }, - nodesBetween: (from, to, callback) => { - callback({ isText: true, text: 'Hello' }, 0); - callback({ isLeaf: true, type: { spec: { leafText: () => 'Leaf' } } }, 5); - }, - }; + it('handles mixed content', () => { + const mockParagraph = createParagraphWithSegments([ + { text: 'Hello', start: 0, attrs: { bold: true } }, + { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, + ]); const result = getTextContent(mockParagraph); - expect(result.text).toBe('HelloLeaf'); + expect(result.text).toEqual([...buildRuns('Hello', { bold: true }), ...buildRuns('Leaf', { italic: true })]); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(5)).toBe(6); expect(result.resolvePosition(9)).toBe(10); }); - it('Handles empty content', () => { - const mockParagraph = { - content: { - size: 0, - }, - nodesBetween: () => {}, - }; + it('handles empty content', () => { + const mockParagraph = createParagraphWithSegments([], 0); const result = getTextContent(mockParagraph); - expect(result.text).toBe(''); + expect(result.text).toEqual([]); expect(result.resolvePosition(0)).toBe(1); }); - it('Handles nested nodes', () => { - const mockParagraph = { - content: { - size: 6, - }, - nodesBetween: (from, to, callback) => { - callback({ isText: true, text: 'Nested' }, 0); - }, - }; + it('applies paragraph position offsets to the resolver', () => { + const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); - const result = getTextContent(mockParagraph); - expect(result.text).toBe('Nested'); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(6)).toBe(7); + const result = getTextContent(mockParagraph, 10); + expect(result.text).toEqual(buildRuns('Nested', {})); + expect(result.resolvePosition(0)).toBe(11); + expect(result.resolvePosition(6)).toBe(17); }); }); diff --git a/packages/super-editor/src/tests/data/diff_after3.docx b/packages/super-editor/src/tests/data/diff_after3.docx new file mode 100644 index 0000000000000000000000000000000000000000..df9a28ae24ca01ce66d04e4c608c257e4453e9a6 GIT binary patch literal 13380 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_after4.docx b/packages/super-editor/src/tests/data/diff_after4.docx new file mode 100644 index 0000000000000000000000000000000000000000..bf426c169a8cb49e48d5547280e6c87f241231d0 GIT binary patch literal 13345 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 B)OG*> literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_before3.docx b/packages/super-editor/src/tests/data/diff_before3.docx new file mode 100644 index 0000000000000000000000000000000000000000..b094d85c8392e2c10d8c475899d89a8d84bf1b8e GIT binary patch literal 13370 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_before4.docx b/packages/super-editor/src/tests/data/diff_before4.docx new file mode 100644 index 0000000000000000000000000000000000000000..155ce140b4203080b329d9e4398b126af9ee3a96 GIT binary patch literal 13370 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 literal 0 HcmV?d00001 From bb7e16caef4936b3777a455f3754433367cbd2bc Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 26 Dec 2025 15:48:45 -0300 Subject: [PATCH 017/125] refactor: change from "type" to "action" --- .../diffing/algorithm/paragraph-diffing.js | 12 +++++----- .../algorithm/paragraph-diffing.test.js | 12 +++++----- .../algorithm/sequence-diffing.test.js | 14 +++++------ .../diffing/algorithm/text-diffing.js | 24 +++++++++---------- .../diffing/algorithm/text-diffing.test.js | 10 ++++---- .../extensions/diffing/computeDiff.test.js | 20 ++++++++-------- 6 files changed, 46 insertions(+), 46 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index feeafecd40..4890d289d4 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -11,7 +11,7 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; /** * A paragraph addition diff emitted when new content is inserted. * @typedef {Object} AddedParagraphDiff - * @property {'added'} type + * @property {'added'} action * @property {Node} node reference to the ProseMirror node for consumers needing schema details * @property {string} text textual contents of the inserted paragraph * @property {number} pos document position where the paragraph was inserted @@ -20,7 +20,7 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; /** * A paragraph deletion diff emitted when content is removed. * @typedef {Object} DeletedParagraphDiff - * @property {'deleted'} type + * @property {'deleted'} action * @property {Node} node reference to the original ProseMirror node * @property {string} oldText text that was removed * @property {number} pos starting document position of the original paragraph @@ -29,7 +29,7 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; /** * A paragraph modification diff that carries inline text-level changes. * @typedef {Object} ModifiedParagraphDiff - * @property {'modified'} type + * @property {'modified'} action * @property {string} oldText text before the edit * @property {string} newText text after the edit * @property {number} pos original document position for anchoring UI @@ -88,7 +88,7 @@ function paragraphComparator(oldParagraph, newParagraph) { */ function buildAddedParagraphDiff(paragraph) { return { - type: 'added', + action: 'added', node: paragraph.node, text: paragraph.fullText, pos: paragraph.pos, @@ -102,7 +102,7 @@ function buildAddedParagraphDiff(paragraph) { */ function buildDeletedParagraphDiff(paragraph) { return { - type: 'deleted', + action: 'deleted', node: paragraph.node, oldText: paragraph.fullText, pos: paragraph.pos, @@ -129,7 +129,7 @@ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { } return { - type: 'modified', + action: 'modified', oldText: oldParagraph.fullText, newText: newParagraph.fullText, pos: oldParagraph.pos, diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index f81180663a..b37350eee0 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -27,7 +27,7 @@ describe('diffParagraphs', () => { const diffs = diffParagraphs(oldParagraphs, newParagraphs); expect(diffs).toHaveLength(1); - expect(diffs[0].type).toBe('modified'); + expect(diffs[0].action).toBe('modified'); expect(diffs[0].textDiffs.length).toBeGreaterThan(0); }); @@ -38,8 +38,8 @@ describe('diffParagraphs', () => { const diffs = diffParagraphs(oldParagraphs, newParagraphs); expect(diffs).toHaveLength(2); - expect(diffs[0].type).toBe('deleted'); - expect(diffs[1].type).toBe('added'); + expect(diffs[0].action).toBe('deleted'); + expect(diffs[1].action).toBe('added'); }); it('detects modifications even when Myers emits grouped deletes and inserts', () => { @@ -55,9 +55,9 @@ describe('diffParagraphs', () => { const diffs = diffParagraphs(oldParagraphs, newParagraphs); expect(diffs).toHaveLength(3); - expect(diffs[0].type).toBe('modified'); + expect(diffs[0].action).toBe('modified'); expect(diffs[0].textDiffs.length).toBeGreaterThan(0); - expect(diffs[1].type).toBe('deleted'); - expect(diffs[2].type).toBe('added'); + expect(diffs[1].action).toBe('deleted'); + expect(diffs[2].action).toBe('added'); }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js index 4f771cd123..679b4cc63b 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js @@ -1,10 +1,10 @@ import { describe, it, expect } from 'vitest'; import { diffSequences } from './sequence-diffing.js'; -const buildAdded = (item) => ({ type: 'added', id: item.id }); -const buildDeleted = (item) => ({ type: 'deleted', id: item.id }); +const buildAdded = (item) => ({ action: 'added', id: item.id }); +const buildDeleted = (item) => ({ action: 'deleted', id: item.id }); const buildModified = (oldItem, newItem) => ({ - type: 'modified', + action: 'modified', id: oldItem.id ?? newItem.id, from: oldItem.value, to: newItem.value, @@ -29,7 +29,7 @@ describe('diffSequences', () => { buildModified, }); - expect(diffs).toEqual([{ type: 'modified', id: 'b', from: 'World', to: 'World!!!' }]); + expect(diffs).toEqual([{ action: 'modified', id: 'b', from: 'World', to: 'World!!!' }]); }); it('pairs delete/insert operations into modifications when allowed', () => { @@ -51,7 +51,7 @@ describe('diffSequences', () => { buildModified, }); - expect(diffs).toEqual([{ type: 'modified', id: 'b', from: 'Beta', to: 'Beta v2' }]); + expect(diffs).toEqual([{ action: 'modified', id: 'b', from: 'Beta', to: 'Beta v2' }]); }); it('emits additions and deletions when items cannot be paired', () => { @@ -66,8 +66,8 @@ describe('diffSequences', () => { }); expect(diffs).toEqual([ - { type: 'deleted', id: 'a' }, - { type: 'added', id: 'b' }, + { action: 'deleted', id: 'a' }, + { action: 'added', id: 'b' }, ]); }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js index b6bff482b7..ade376764d 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js @@ -11,8 +11,8 @@ import { diffSequences } from './sequence-diffing.js'; * @returns {Array} List of addition/deletion ranges with document positions and text content. */ export function getTextDiff(oldText, newText, oldPositionResolver, newPositionResolver = oldPositionResolver) { - const buildCharDiff = (type, char, oldIdx) => ({ - type, + const buildCharDiff = (action, char, oldIdx) => ({ + action, idx: oldIdx, text: char.char, runAttrs: char.runAttrs, @@ -24,7 +24,7 @@ export function getTextDiff(oldText, newText, oldPositionResolver, newPositionRe buildAdded: (char, oldIdx, newIdx) => buildCharDiff('added', char, oldIdx), buildDeleted: (char, oldIdx, newIdx) => buildCharDiff('deleted', char, oldIdx), buildModified: (oldChar, newChar, oldIdx, newIdx) => ({ - type: 'modified', + action: 'modified', idx: oldIdx, newText: newChar.char, oldText: oldChar.char, @@ -42,17 +42,17 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { let currentGroup = null; const compareDiffs = (group, diff) => { - if (group.type !== diff.type) { + if (group.action !== diff.action) { return false; } - if (group.type === 'modified') { + if (group.action === 'modified') { return group.oldAttrs === diff.oldAttrs && group.newAttrs === diff.newAttrs; } return group.runAttrs === diff.runAttrs; }; const comparePositions = (group, diff) => { - if (group.type === 'added') { + if (group.action === 'added') { return group.startPos === oldPositionResolver(diff.idx); } else { return group.endPos + 1 === oldPositionResolver(diff.idx); @@ -62,11 +62,11 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { for (const diff of diffs) { if (currentGroup == null) { currentGroup = { - type: diff.type, + action: diff.action, startPos: oldPositionResolver(diff.idx), endPos: oldPositionResolver(diff.idx), }; - if (diff.type === 'modified') { + if (diff.action === 'modified') { currentGroup.newText = diff.newText; currentGroup.oldText = diff.oldText; currentGroup.oldAttrs = diff.oldAttrs; @@ -78,11 +78,11 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { } else if (!compareDiffs(currentGroup, diff) || !comparePositions(currentGroup, diff)) { grouped.push(currentGroup); currentGroup = { - type: diff.type, + action: diff.action, startPos: oldPositionResolver(diff.idx), endPos: oldPositionResolver(diff.idx), }; - if (diff.type === 'modified') { + if (diff.action === 'modified') { currentGroup.newText = diff.newText; currentGroup.oldText = diff.oldText; currentGroup.oldAttrs = diff.oldAttrs; @@ -93,7 +93,7 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { } } else { currentGroup.endPos = oldPositionResolver(diff.idx); - if (diff.type === 'modified') { + if (diff.action === 'modified') { currentGroup.newText += diff.newText; currentGroup.oldText += diff.oldText; } else { @@ -105,7 +105,7 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { if (currentGroup != null) grouped.push(currentGroup); return grouped.map((group) => { let ret = { ...group }; - if (group.type === 'modified') { + if (group.action === 'modified') { ret.oldAttrs = JSON.parse(group.oldAttrs); ret.newAttrs = JSON.parse(group.newAttrs); ret.runAttrsDiff = getAttributesDiff(ret.oldAttrs, ret.newAttrs); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js index 9f3005a2a7..239aebd2f2 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js @@ -26,7 +26,7 @@ describe('getTextDiff', () => { expect(diffs).toEqual([ { - type: 'added', + action: 'added', startPos: 12, endPos: 12, text: 'X', @@ -43,14 +43,14 @@ describe('getTextDiff', () => { expect(diffs).toEqual([ { - type: 'deleted', + action: 'deleted', startPos: 7, endPos: 7, text: 'c', runAttrs: {}, }, { - type: 'added', + action: 'added', startPos: 8, endPos: 8, text: 'XY', @@ -66,7 +66,7 @@ describe('getTextDiff', () => { expect(diffs).toEqual([ { - type: 'modified', + action: 'modified', startPos: 0, endPos: 0, oldText: 'a', @@ -87,7 +87,7 @@ describe('getTextDiff', () => { expect(diffs).toEqual([ { - type: 'modified', + action: 'modified', startPos: 5, endPos: 6, oldText: 'ab', diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index d059891ea3..b0df12128b 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -30,11 +30,11 @@ describe('Diff', () => { const docAfter = await getDocument('diff_after.docx'); const diffs = computeDiff(docBefore, docAfter); - const getDiff = (type, predicate) => diffs.find((diff) => diff.type === type && predicate(diff)); + const getDiff = (action, predicate) => diffs.find((diff) => diff.action === action && predicate(diff)); - const modifiedDiffs = diffs.filter((diff) => diff.type === 'modified'); - const addedDiffs = diffs.filter((diff) => diff.type === 'added'); - const deletedDiffs = diffs.filter((diff) => diff.type === 'deleted'); + const modifiedDiffs = diffs.filter((diff) => diff.action === 'modified'); + const addedDiffs = diffs.filter((diff) => diff.action === 'added'); + const deletedDiffs = diffs.filter((diff) => diff.action === 'deleted'); const attrOnlyDiffs = modifiedDiffs.filter((diff) => diff.textDiffs.length === 0); expect(diffs).toHaveLength(19); @@ -51,7 +51,7 @@ describe('Diff', () => { expect(diff?.newText).toBe( 'Curabitur facilisis ligula suscipit enim pretium et nunc ligula, porttitor augue consequat maximus.', ); - const textPropsChanges = diff?.textDiffs.filter((textDiff) => textDiff.type === 'modified'); + const textPropsChanges = diff?.textDiffs.filter((textDiff) => textDiff.action === 'modified'); expect(textPropsChanges).toHaveLength(18); expect(diff?.textDiffs).toHaveLength(24); @@ -132,7 +132,7 @@ describe('Diff', () => { const diffs = computeDiff(docBefore, docAfter); expect(diffs).toHaveLength(4); - let diff = diffs.find((diff) => diff.type === 'modified' && diff.oldText === 'Here’s some text.'); + let diff = diffs.find((diff) => diff.action === 'modified' && diff.oldText === 'Here’s some text.'); expect(diff.newText).toBe('Here’s some NEW text.'); expect(diff.textDiffs).toHaveLength(3); @@ -141,13 +141,13 @@ describe('Diff', () => { expect(diff.textDiffs[2].text).toBe(' '); expect(diff.attrsDiff?.modified?.textId).toBeDefined(); - diff = diffs.find((diff) => diff.type === 'deleted' && diff.oldText === 'I deleted this sentence.'); + diff = diffs.find((diff) => diff.action === 'deleted' && diff.oldText === 'I deleted this sentence.'); expect(diff).toBeDefined(); - diff = diffs.find((diff) => diff.type === 'added' && diff.text === 'I added this sentence.'); + diff = diffs.find((diff) => diff.action === 'added' && diff.text === 'I added this sentence.'); expect(diff).toBeDefined(); - diff = diffs.find((diff) => diff.type === 'modified' && diff.oldText === 'We are not done yet.'); + diff = diffs.find((diff) => diff.action === 'modified' && diff.oldText === 'We are not done yet.'); expect(diff.newText).toBe('We are done now.'); expect(diff.textDiffs).toHaveLength(3); expect(diff.attrsDiff?.modified?.textId).toBeDefined(); @@ -161,6 +161,6 @@ describe('Diff', () => { expect(diffs).toHaveLength(1); const diff = diffs[0]; - expect(diff.type).toBe('modified'); + expect(diff.action).toBe('modified'); }); }); From 5068fef03dc155822f98b2c2584b56f43850e573 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 26 Dec 2025 17:20:30 -0300 Subject: [PATCH 018/125] feat: support diffing non-textual inline nodes --- .../{text-diffing.js => inline-diffing.js} | 118 ++++++++++++++---- ...diffing.test.js => inline-diffing.test.js} | 21 ++-- .../diffing/algorithm/paragraph-diffing.js | 10 +- .../algorithm/paragraph-diffing.test.js | 4 +- .../extensions/diffing/computeDiff.test.js | 44 +++++-- .../src/extensions/diffing/utils.js | 36 ++++-- .../src/extensions/diffing/utils.test.js | 79 ++++++++++-- .../src/tests/data/diff_after5.docx | Bin 0 -> 13330 bytes .../src/tests/data/diff_after6.docx | Bin 0 -> 24121 bytes .../src/tests/data/diff_before5.docx | Bin 0 -> 13370 bytes .../src/tests/data/diff_before6.docx | Bin 0 -> 13422 bytes 11 files changed, 243 insertions(+), 69 deletions(-) rename packages/super-editor/src/extensions/diffing/algorithm/{text-diffing.js => inline-diffing.js} (53%) rename packages/super-editor/src/extensions/diffing/algorithm/{text-diffing.test.js => inline-diffing.test.js} (73%) create mode 100644 packages/super-editor/src/tests/data/diff_after5.docx create mode 100644 packages/super-editor/src/tests/data/diff_after6.docx create mode 100644 packages/super-editor/src/tests/data/diff_before5.docx create mode 100644 packages/super-editor/src/tests/data/diff_before6.docx diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js similarity index 53% rename from packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js rename to packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js index ade376764d..638b553d4f 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js @@ -4,39 +4,85 @@ import { diffSequences } from './sequence-diffing.js'; /** * Computes text-level additions and deletions between two strings using Myers diff algorithm, mapping back to document positions. - * @param {{char: string, runAttrs: Record}[]} oldText - Source text. - * @param {{char: string, runAttrs: Record}[]} newText - Target text. + * @param {{char: string, runAttrs: Record}[]} oldContent - Source text. + * @param {{char: string, runAttrs: Record}[]} newContent - Target text. * @param {(index: number) => number|null} oldPositionResolver - Maps string indexes to the original document. * @param {(index: number) => number|null} [newPositionResolver=oldPositionResolver] - Maps string indexes to the updated document. * @returns {Array} List of addition/deletion ranges with document positions and text content. */ -export function getTextDiff(oldText, newText, oldPositionResolver, newPositionResolver = oldPositionResolver) { - const buildCharDiff = (action, char, oldIdx) => ({ - action, - idx: oldIdx, - text: char.char, - runAttrs: char.runAttrs, - }); - let diffs = diffSequences(oldText, newText, { - comparator: (a, b) => a.char === b.char, - shouldProcessEqualAsModification: (oldChar, newChar) => oldChar.runAttrs !== newChar.runAttrs, - canTreatAsModification: (oldChar, newChar) => false, - buildAdded: (char, oldIdx, newIdx) => buildCharDiff('added', char, oldIdx), - buildDeleted: (char, oldIdx, newIdx) => buildCharDiff('deleted', char, oldIdx), - buildModified: (oldChar, newChar, oldIdx, newIdx) => ({ - action: 'modified', - idx: oldIdx, - newText: newChar.char, - oldText: oldChar.char, - oldAttrs: oldChar.runAttrs, - newAttrs: newChar.runAttrs, - }), +export function getInlineDiff(oldContent, newContent, oldPositionResolver, newPositionResolver = oldPositionResolver) { + const buildCharDiff = (action, token, oldIdx) => { + if (token.kind !== 'text') { + return { + action, + idx: oldIdx, + ...token, + }; + } else { + return { + action, + idx: oldIdx, + kind: 'text', + text: token.char, + runAttrs: token.runAttrs, + }; + } + }; + let diffs = diffSequences(oldContent, newContent, { + comparator: inlineComparator, + shouldProcessEqualAsModification, + canTreatAsModification: (oldToken, newToken, oldIdx, newIdx) => + oldToken.kind === newToken.kind && oldToken.kind !== 'text' && oldToken.node.type.type === newToken.node.type, + buildAdded: (token, oldIdx, newIdx) => buildCharDiff('added', token, oldIdx), + buildDeleted: (token, oldIdx, newIdx) => buildCharDiff('deleted', token, oldIdx), + buildModified: (oldToken, newToken, oldIdx, newIdx) => { + if (oldToken.kind !== 'text') { + return { + action: 'modified', + idx: oldIdx, + kind: 'inlineNode', + oldNode: oldToken.node, + newNode: newToken.node, + nodeType: oldToken.nodeType, + }; + } else { + return { + action: 'modified', + idx: oldIdx, + kind: 'text', + newText: newToken.char, + oldText: oldToken.char, + oldAttrs: oldToken.runAttrs, + newAttrs: newToken.runAttrs, + }; + } + }, }); const groupedDiffs = groupDiffs(diffs, oldPositionResolver, newPositionResolver); return groupedDiffs; } +function inlineComparator(a, b) { + if (a.kind !== b.kind) { + return false; + } + + if (a.kind === 'text') { + return a.char === b.char; + } else { + return true; + } +} + +function shouldProcessEqualAsModification(oldToken, newToken) { + if (oldToken.kind === 'text') { + return oldToken.runAttrs !== newToken.runAttrs; + } else { + return JSON.stringify(oldToken.nodeAttrs) !== JSON.stringify(newToken.nodeAttrs); + } +} + function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { const grouped = []; let currentGroup = null; @@ -60,11 +106,33 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { }; for (const diff of diffs) { + if (diff.kind !== 'text') { + if (currentGroup != null) { + grouped.push(currentGroup); + currentGroup = null; + } + grouped.push({ + action: diff.action, + kind: 'inlineNode', + startPos: oldPositionResolver(diff.idx), + endPos: oldPositionResolver(diff.idx), + nodeType: diff.nodeType, + ...(diff.action === 'modified' + ? { + oldNode: diff.oldNode, + newNode: diff.newNode, + diffNodeAttrs: getAttributesDiff(diff.oldAttrs, diff.newAttrs), + } + : { node: diff.node }), + }); + continue; + } if (currentGroup == null) { currentGroup = { action: diff.action, startPos: oldPositionResolver(diff.idx), endPos: oldPositionResolver(diff.idx), + kind: 'text', }; if (diff.action === 'modified') { currentGroup.newText = diff.newText; @@ -81,6 +149,7 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { action: diff.action, startPos: oldPositionResolver(diff.idx), endPos: oldPositionResolver(diff.idx), + kind: 'text', }; if (diff.action === 'modified') { currentGroup.newText = diff.newText; @@ -105,6 +174,9 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { if (currentGroup != null) grouped.push(currentGroup); return grouped.map((group) => { let ret = { ...group }; + if (group.kind === 'inlineNode') { + return ret; + } if (group.action === 'modified') { ret.oldAttrs = JSON.parse(group.oldAttrs); ret.newAttrs = JSON.parse(group.newAttrs); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js similarity index 73% rename from packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js rename to packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index 239aebd2f2..6a71229ac0 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/text-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -5,15 +5,15 @@ vi.mock('./myers-diff.js', async () => { myersDiff: vi.fn(actual.myersDiff), }; }); -import { getTextDiff } from './text-diffing.js'; +import { getInlineDiff } from './inline-diffing.js'; const buildTextRuns = (text, runAttrs = {}) => - text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs) })); + text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs), kind: 'text' })); -describe('getTextDiff', () => { +describe('getInlineDiff', () => { it('returns an empty diff list when both strings are identical', () => { const resolver = (index) => index; - const diffs = getTextDiff(buildTextRuns('unchanged'), buildTextRuns('unchanged'), resolver); + const diffs = getInlineDiff(buildTextRuns('unchanged'), buildTextRuns('unchanged'), resolver); expect(diffs).toEqual([]); }); @@ -22,11 +22,12 @@ describe('getTextDiff', () => { const oldResolver = (index) => index + 10; const newResolver = (index) => index + 100; - const diffs = getTextDiff(buildTextRuns('abc'), buildTextRuns('abXc'), oldResolver, newResolver); + const diffs = getInlineDiff(buildTextRuns('abc'), buildTextRuns('abXc'), oldResolver, newResolver); expect(diffs).toEqual([ { action: 'added', + kind: 'text', startPos: 12, endPos: 12, text: 'X', @@ -39,11 +40,12 @@ describe('getTextDiff', () => { const oldResolver = (index) => index + 5; const newResolver = (index) => index + 20; - const diffs = getTextDiff(buildTextRuns('abcd'), buildTextRuns('abXYd'), oldResolver, newResolver); + const diffs = getInlineDiff(buildTextRuns('abcd'), buildTextRuns('abXYd'), oldResolver, newResolver); expect(diffs).toEqual([ { action: 'deleted', + kind: 'text', startPos: 7, endPos: 7, text: 'c', @@ -51,6 +53,7 @@ describe('getTextDiff', () => { }, { action: 'added', + kind: 'text', startPos: 8, endPos: 8, text: 'XY', @@ -62,11 +65,12 @@ describe('getTextDiff', () => { it('marks attribute-only changes as modifications and surfaces attribute diffs', () => { const resolver = (index) => index; - const diffs = getTextDiff(buildTextRuns('a', { bold: true }), buildTextRuns('a', { italic: true }), resolver); + const diffs = getInlineDiff(buildTextRuns('a', { bold: true }), buildTextRuns('a', { italic: true }), resolver); expect(diffs).toEqual([ { action: 'modified', + kind: 'text', startPos: 0, endPos: 0, oldText: 'a', @@ -83,11 +87,12 @@ describe('getTextDiff', () => { it('merges contiguous attribute edits that share the same diff metadata', () => { const resolver = (index) => index + 5; - const diffs = getTextDiff(buildTextRuns('ab', { bold: true }), buildTextRuns('ab', { bold: false }), resolver); + const diffs = getInlineDiff(buildTextRuns('ab', { bold: true }), buildTextRuns('ab', { bold: false }), resolver); expect(diffs).toEqual([ { action: 'modified', + kind: 'text', startPos: 5, endPos: 6, oldText: 'ab', diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index 4890d289d4..a7a6ce0f62 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -1,5 +1,5 @@ import { myersDiff } from './myers-diff.js'; -import { getTextDiff } from './text-diffing.js'; +import { getInlineDiff } from './inline-diffing.js'; import { getAttributesDiff } from './attributes-diffing.js'; import { diffSequences, reorderDiffOperations } from './sequence-diffing.js'; import { levenshteinDistance } from './similarity.js'; @@ -33,7 +33,7 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; * @property {string} oldText text before the edit * @property {string} newText text after the edit * @property {number} pos original document position for anchoring UI - * @property {Array} textDiffs granular inline diff data returned by `getTextDiff` + * @property {Array} contentDiff granular inline diff data * @property {import('./attributes-diffing.js').AttributesDiff|null} attrsDiff attribute-level changes between the old and new paragraph nodes */ @@ -116,7 +116,7 @@ function buildDeletedParagraphDiff(paragraph) { * @returns {ModifiedParagraphDiff} */ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { - const textDiffs = getTextDiff( + const contentDiff = getInlineDiff( oldParagraph.text, newParagraph.text, oldParagraph.resolvePosition, @@ -124,7 +124,7 @@ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { ); const attrsDiff = getAttributesDiff(oldParagraph.node.attrs, newParagraph.node.attrs); - if (textDiffs.length === 0 && !attrsDiff) { + if (contentDiff.length === 0 && !attrsDiff) { return null; } @@ -133,7 +133,7 @@ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { oldText: oldParagraph.fullText, newText: newParagraph.fullText, pos: oldParagraph.pos, - textDiffs, + contentDiff, attrsDiff, }; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index b37350eee0..3429bd9066 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -28,7 +28,7 @@ describe('diffParagraphs', () => { expect(diffs).toHaveLength(1); expect(diffs[0].action).toBe('modified'); - expect(diffs[0].textDiffs.length).toBeGreaterThan(0); + expect(diffs[0].contentDiff.length).toBeGreaterThan(0); }); it('keeps unrelated paragraphs as deletion + addition', () => { @@ -56,7 +56,7 @@ describe('diffParagraphs', () => { expect(diffs).toHaveLength(3); expect(diffs[0].action).toBe('modified'); - expect(diffs[0].textDiffs.length).toBeGreaterThan(0); + expect(diffs[0].contentDiff.length).toBeGreaterThan(0); expect(diffs[1].action).toBe('deleted'); expect(diffs[2].action).toBe('added'); }); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index b0df12128b..6ee9bef813 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -35,7 +35,7 @@ describe('Diff', () => { const modifiedDiffs = diffs.filter((diff) => diff.action === 'modified'); const addedDiffs = diffs.filter((diff) => diff.action === 'added'); const deletedDiffs = diffs.filter((diff) => diff.action === 'deleted'); - const attrOnlyDiffs = modifiedDiffs.filter((diff) => diff.textDiffs.length === 0); + const attrOnlyDiffs = modifiedDiffs.filter((diff) => diff.contentDiff.length === 0); expect(diffs).toHaveLength(19); expect(modifiedDiffs).toHaveLength(9); @@ -51,9 +51,9 @@ describe('Diff', () => { expect(diff?.newText).toBe( 'Curabitur facilisis ligula suscipit enim pretium et nunc ligula, porttitor augue consequat maximus.', ); - const textPropsChanges = diff?.textDiffs.filter((textDiff) => textDiff.action === 'modified'); + const textPropsChanges = diff?.contentDiff.filter((textDiff) => textDiff.action === 'modified'); expect(textPropsChanges).toHaveLength(18); - expect(diff?.textDiffs).toHaveLength(24); + expect(diff?.contentDiff).toHaveLength(24); // Deleted paragraph diff = getDiff( @@ -135,10 +135,10 @@ describe('Diff', () => { let diff = diffs.find((diff) => diff.action === 'modified' && diff.oldText === 'Here’s some text.'); expect(diff.newText).toBe('Here’s some NEW text.'); - expect(diff.textDiffs).toHaveLength(3); - expect(diff.textDiffs[0].newText).toBe(' '); - expect(diff.textDiffs[1].text).toBe('NEW'); - expect(diff.textDiffs[2].text).toBe(' '); + expect(diff.contentDiff).toHaveLength(3); + expect(diff.contentDiff[0].newText).toBe(' '); + expect(diff.contentDiff[1].text).toBe('NEW'); + expect(diff.contentDiff[2].text).toBe(' '); expect(diff.attrsDiff?.modified?.textId).toBeDefined(); diff = diffs.find((diff) => diff.action === 'deleted' && diff.oldText === 'I deleted this sentence.'); @@ -149,7 +149,7 @@ describe('Diff', () => { diff = diffs.find((diff) => diff.action === 'modified' && diff.oldText === 'We are not done yet.'); expect(diff.newText).toBe('We are done now.'); - expect(diff.textDiffs).toHaveLength(3); + expect(diff.contentDiff).toHaveLength(3); expect(diff.attrsDiff?.modified?.textId).toBeDefined(); }); @@ -163,4 +163,32 @@ describe('Diff', () => { const diff = diffs[0]; expect(diff.action).toBe('modified'); }); + + it('Compare another set of two documents with only formatting changes', async () => { + const docBefore = await getDocument('diff_before5.docx'); + const docAfter = await getDocument('diff_after5.docx'); + + const diffs = computeDiff(docBefore, docAfter); + + expect(diffs).toHaveLength(1); + const diff = diffs[0]; + expect(diff.action).toBe('modified'); + }); + + it('Compare another set of two documents where an image was added', async () => { + const docBefore = await getDocument('diff_before6.docx'); + const docAfter = await getDocument('diff_after6.docx'); + + const diffs = computeDiff(docBefore, docAfter); + expect(diffs).toHaveLength(1); + const diff = diffs[0]; + expect(diff.action).toBe('modified'); + expect(diff.contentDiff).toHaveLength(3); + expect(diff.contentDiff[0].action).toBe('modified'); + expect(diff.contentDiff[0].kind).toBe('text'); + expect(diff.contentDiff[1].action).toBe('added'); + expect(diff.contentDiff[1].kind).toBe('inlineNode'); + expect(diff.contentDiff[2].action).toBe('added'); + expect(diff.contentDiff[2].kind).toBe('text'); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/utils.js b/packages/super-editor/src/extensions/diffing/utils.js index 1336865309..f476b13b6f 100644 --- a/packages/super-editor/src/extensions/diffing/utils.js +++ b/packages/super-editor/src/extensions/diffing/utils.js @@ -4,8 +4,8 @@ * @param {number} [paragraphPos=0] - Position of the paragraph in the document. * @returns {{text: {char: string, runAttrs: Record}[], resolvePosition: (index: number) => number|null}} Concatenated text and position resolver. */ -export function getTextContent(paragraph, paragraphPos = 0) { - let text = []; +export function getParagraphContent(paragraph, paragraphPos = 0) { + let content = []; const segments = []; paragraph.nodesBetween( @@ -18,27 +18,39 @@ export function getTextContent(paragraph, paragraphPos = 0) { nodeText = node.text; } else if (node.isLeaf && node.type.spec.leafText) { nodeText = node.type.spec.leafText(node); - } - - if (!nodeText) { + } else if (node.type.name !== 'run' && node.isInline) { + const start = content.length; + const end = start + 1; + content.push({ + kind: 'inlineNode', + node: node, + }); + segments.push({ start, end, pos }); + return; + } else { return; } - const start = text.length; + const start = content.length; const end = start + nodeText.length; - // Get parent run node and its attributes const runNode = paragraph.nodeAt(pos - 1); const runAttrs = runNode.attrs || {}; - segments.push({ start, end, pos, runAttrs }); - text = text.concat(nodeText.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs) }))); + segments.push({ start, end, pos }); + const chars = nodeText.split('').map((char) => ({ + kind: 'text', + char, + runAttrs: JSON.stringify(runAttrs), + })); + + content = content.concat(chars); }, 0, ); const resolvePosition = (index) => { - if (index < 0 || index > text.length) { + if (index < 0 || index > content.length) { return null; } @@ -52,7 +64,7 @@ export function getTextContent(paragraph, paragraphPos = 0) { return paragraphPos + 1 + paragraph.content.size; }; - return { text, resolvePosition }; + return { text: content, resolvePosition }; } /** @@ -64,7 +76,7 @@ export function extractParagraphs(pmDoc) { const paragraphs = []; pmDoc.descendants((node, pos) => { if (node.type.name === 'paragraph') { - const { text, resolvePosition } = getTextContent(node, pos); + const { text, resolvePosition } = getParagraphContent(node, pos); paragraphs.push({ node, pos, diff --git a/packages/super-editor/src/extensions/diffing/utils.test.js b/packages/super-editor/src/extensions/diffing/utils.test.js index fbf85fa726..06a6a54489 100644 --- a/packages/super-editor/src/extensions/diffing/utils.test.js +++ b/packages/super-editor/src/extensions/diffing/utils.test.js @@ -1,6 +1,7 @@ -import { extractParagraphs, getTextContent } from './utils'; +import { extractParagraphs, getParagraphContent } from './utils'; -const buildRuns = (text, attrs = {}) => text.split('').map((char) => ({ char, runAttrs: JSON.stringify(attrs) })); +const buildRuns = (text, attrs = {}) => + text.split('').map((char) => ({ char, runAttrs: JSON.stringify(attrs), kind: 'text' })); const createParagraphNode = (text, attrs = {}) => ({ type: { name: 'paragraph' }, @@ -15,10 +16,26 @@ const createParagraphNode = (text, attrs = {}) => ({ const createParagraphWithSegments = (segments, contentSize) => { const computedSegments = segments.map((segment) => { + if (segment.inlineNode) { + return { + ...segment, + kind: 'inline', + length: segment.length ?? 1, + start: segment.start ?? 0, + attrs: segment.attrs ?? segment.inlineNode.attrs ?? {}, + inlineNode: { + typeName: segment.inlineNode.typeName ?? 'inline', + attrs: segment.inlineNode.attrs ?? {}, + isLeaf: segment.inlineNode.isLeaf ?? true, + }, + }; + } + const segmentText = segment.text ?? segment.leafText(); const length = segmentText.length; return { ...segment, + kind: segment.text != null ? 'text' : 'leaf', length, start: segment.start ?? 0, attrs: segment.attrs ?? {}, @@ -28,17 +45,28 @@ const createParagraphWithSegments = (segments, contentSize) => { contentSize ?? computedSegments.reduce((max, segment) => Math.max(max, segment.start + segment.length), 0); const attrsMap = new Map(); computedSegments.forEach((segment) => { - attrsMap.set(segment.start - 1, segment.attrs); + const key = segment.kind === 'inline' ? segment.start : segment.start - 1; + attrsMap.set(key, segment.attrs); }); return { content: { size }, nodesBetween: (from, to, callback) => { computedSegments.forEach((segment) => { - if (segment.text != null) { + if (segment.kind === 'text') { callback({ isText: true, text: segment.text }, segment.start); - } else { + } else if (segment.kind === 'leaf') { callback({ isLeaf: true, type: { spec: { leafText: segment.leafText } } }, segment.start); + } else { + callback( + { + isInline: true, + isLeaf: segment.inlineNode.isLeaf, + type: { name: segment.inlineNode.typeName, spec: {} }, + attrs: segment.inlineNode.attrs, + }, + segment.start, + ); } }); }, @@ -92,11 +120,11 @@ describe('extractParagraphs', () => { }); }); -describe('getTextContent', () => { +describe('getParagraphContent', () => { it('handles basic text nodes', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); - const result = getTextContent(mockParagraph); + const result = getParagraphContent(mockParagraph); expect(result.text).toEqual(buildRuns('Hello', { bold: true })); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(4)).toBe(5); @@ -108,7 +136,7 @@ describe('getTextContent', () => { 4, ); - const result = getTextContent(mockParagraph); + const result = getParagraphContent(mockParagraph); expect(result.text).toEqual(buildRuns('Leaf', { type: 'leaf' })); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(3)).toBe(4); @@ -120,7 +148,7 @@ describe('getTextContent', () => { { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, ]); - const result = getTextContent(mockParagraph); + const result = getParagraphContent(mockParagraph); expect(result.text).toEqual([...buildRuns('Hello', { bold: true }), ...buildRuns('Leaf', { italic: true })]); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(5)).toBe(6); @@ -130,15 +158,44 @@ describe('getTextContent', () => { it('handles empty content', () => { const mockParagraph = createParagraphWithSegments([], 0); - const result = getTextContent(mockParagraph); + const result = getParagraphContent(mockParagraph); expect(result.text).toEqual([]); expect(result.resolvePosition(0)).toBe(1); }); + it('includes inline nodes that have no textual content', () => { + const inlineAttrs = { kind: 'tab', width: 120 }; + const mockParagraph = createParagraphWithSegments([ + { inlineNode: { typeName: 'tab', attrs: inlineAttrs }, start: 0 }, + { text: 'Text', start: 1, attrs: { bold: false } }, + ]); + + const result = getParagraphContent(mockParagraph); + debugger; + expect(result.text[0]).toEqual({ + kind: 'inlineNode', + node: { + attrs: { + kind: 'tab', + width: 120, + }, + isInline: true, + isLeaf: true, + type: { + name: 'tab', + spec: {}, + }, + }, + }); + expect(result.text.slice(1)).toEqual(buildRuns('Text', { bold: false })); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(1)).toBe(2); + }); + it('applies paragraph position offsets to the resolver', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); - const result = getTextContent(mockParagraph, 10); + const result = getParagraphContent(mockParagraph, 10); expect(result.text).toEqual(buildRuns('Nested', {})); expect(result.resolvePosition(0)).toBe(11); expect(result.resolvePosition(6)).toBe(17); diff --git a/packages/super-editor/src/tests/data/diff_after5.docx b/packages/super-editor/src/tests/data/diff_after5.docx new file mode 100644 index 0000000000000000000000000000000000000000..44e2dcbb8b5a730d6e4bec612d426e5035bbe457 GIT binary patch literal 13330 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_after6.docx b/packages/super-editor/src/tests/data/diff_after6.docx new file mode 100644 index 0000000000000000000000000000000000000000..9fc16f08531e7a45ea201105c8b26d682a909f6d GIT binary patch literal 24121 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_before5.docx b/packages/super-editor/src/tests/data/diff_before5.docx new file mode 100644 index 0000000000000000000000000000000000000000..155ce140b4203080b329d9e4398b126af9ee3a96 GIT binary patch literal 13370 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_before6.docx b/packages/super-editor/src/tests/data/diff_before6.docx new file mode 100644 index 0000000000000000000000000000000000000000..34f9c220cf6e1121647664d01cd937b11a0c983c GIT binary patch literal 13422 zcmeHuWl$yAvhK#+-5YmzcXxMh+^vCzhQ{5U#@%V$Y24l2-CY}a%-l0~X8O#H7w`SO zry^EH)L!*v?W)RLnU(pKf;0#yDgYb+2><{H0qc2F)>=RSzy~k@00jUEtSxM3>uh4{ ztgqs3Z{nm&=VoL5AqNzgA`1Zge*Ay7|HXHpHh$Q)ivdyeKH&)=ra{%{Ag6>1IE*im zR_PD|(*s!TCAPoywH*amQ57f#+M0-z`F@RAt#`WeE*;5 z%p3P@YamH$r1q5Zbr3l4dRfRYan3AX$oL!7qJ|uK9?oROdnPGF zJ1+Y<;ax;xWAY~}s7FGaI1@OtC{hpf5f!)^7Kc@Os_3{keb1wjTgKhEQOzfj}M zS*=3Fn1f`y-;M7rETx6!jXB%^S>$f>_pMc0mycO&02mLay>-7y%$bct+}dOb;0^38 zKifQj003`qAOMBGxg>rJcEkC*oyom>9L&2*>N}cPJJHkqCjaA#|BLEtMREz`562)t(y26UJZwK6C^Jc_btAY2iRhWVf2a7mScJu- zb}P_Hfv7P{EZZNW_t?0|5j#&l+8^_i&w?>>rbVvRyHiw-c_BPtN26QC7ODTrBuO8@ z(a*J-M>9)qz*U3oH+^E_FZy8?v5_EMHkp`?Xy|8AL2!OsoTkR0KFd|#&G-1qW-;Gt zLrcL`(j4*8_zII<#Px)&Fdcv_x7r6r}v3s&E8^#vjQ)Z%HwBZ+=)H1nu&N@_{ z^)0lM49$InM=Fi_H7y>OMdq;(W&O-a0+TNq#+H!b*&9`PhFJ0Tn?b_l;VwRZ#mWZp zMrSovWJI*6S+<|@u~2myD#Dao;+n(L0C{6A015tNM#%G{zS~)>wOc7BGWOcuB|JK& z7n@vzRZ?qMy)*fPEHAUn=ZxtBxQiZc#*v0|=@|&hPwvvv>*5~P(s!La z8Dj>jQ0ufpM_>AQ$T@v1^ZJceS28UTnVEw> zB~pgmLF4=2Af?M>c8ekIX>5rP5RPX)-JiXr>y~xVt9+Z?m}_clYH=`R^@lLKak1!j zT?0FQtku+-#yn3xJHc#biO~B}5c~T2D6J`FZ;5rX1DyglJ(M##Dk&P`6zbFXpSW6Ku&%FRd@%f8rphj;te^g3H9#0rFUpQ7IJB@#3TORKWbq$~KD9jpg zL_7$u^q8k|E5@%p6GXI9w>rk7!i+J{*3+}jn6Q+Sp1JiA$>C6%U<|5@|Hy^QV#1dt zO&<~Ex5v__25zJ066Tn&@5&^HrI5kUTcL*NddnJY3Hv}$ZzsAcyxGcC55l$W7 za%B!14pdH}k~-Q7YQhGbRDZ{3aHG5J%R6haZNV2#dj|etRaLRRu3y7Cr6r&3W)RB<|~Otx5Va6_r(ygxf`gW3Xp=CjHc*Sgus z{UZ4pFR)RO(rE4{Pvshx$0or(3J%gzx6a$Pq&vW`=N#o94DFyOqFFI|N-U}X*E(f) zKp`HZ(r)N%ffr}thBL}T>2QAtfZBCjxaE}x*PFf#ORDE+jWm$t!b!buBkYB^;Os6w z;BLrQD+G1Fx*m@rczJl3l#k+n*tpC+?*M`)HjHTji~CM<-#<_A_PG1JaZk|xv>hjZ z>ZaGn|8mz|_~Yl3>rsH%&XjIRDe>H+h;1Aio->pQ!!8ek}*MxYHW86V-s! zs{J^Qh!1qqu(8qIpj22epNWV-zPQ3c)ouh1)NX^2O$Wd|>>XtbK9Cqu`_Oi9D_R2( zC`pBf$~>BL=cu#|6a4Rb7fZsq120DE@67v$<5a1(@t0L1i9Sy75KZkeh(I9=j82jY zp;x&wu$_Dk-Vb+dM%=)I4MfzIbqqBVW3dUa-PCw8u_2~-v02!=0K!xU`<*#M4brqYw@Ijs*SDmxau9J94M_z@QF5N95EzP`??J+0UHPA_ z*OM#;@IP3Z_F9VrD_-+d3<48YS5gu*w(>l(4MprV=uzFuG&f zTuSXp6DJrIz?Y}@@Z#e;djs(LeCP7^Ys z`3{$?9Ng(cyDEj${i2QJl2*GgMAg86a5@Kfo1R17H^@wt^;U5ebK4t7-(G7#U$|5S zqMtWbEJfNfD~o2^P=KX~zM=jj535_%(SL{5$VX3=MICMQtv#ohYh2xBL>13TwSPfW zPYADuR`&)ZYt$IOoV3DoucpI4EtpjhLI;CaC*#F{3c^Jk1}!RiN`mcr7glE=%N9he zcUeP(97$%EDMOENr|Br#FWym;OS< zbnFhvJX`Nx=q1@jSYVJ3A!N#kEF>^M#Ekg?7WuPTQdf?d;iT#jwdO&?3iXvEumUfl z9V@dK)5=E)h#~oupM5P!XNOeAsmph?%g2-zN!u2FB9tpK$oUN6JG)ifo`daYHoBG* z$^{FBlZWlF`lTe*aX1o2cO6YzGm4-07*4ri9z!JAwpFNhs8j`!$-bD;IZD5Mn~7zj z>x&l0l94w753Uk`MZ_I8pnvuuA$8<+H`h~jY~i7Ny7%^M<>ldLb4#r`nJs0F~)8Hl%FmV51Wi0O%}0h`%X zh14pygx+%t7>2hdOapsZhsHquY@+Fb(bY`TK#7RaJA}pOq!GjFC|#^mV~4d&YERatAW*g2E1IY`&%uKE6>e(+>HpT zNBM}4GNy6$nD=v5|Gn26q8;CNoo~~Pa<_#c&FFJKyf1zpt@BHiN@%_ISUrJwtKdYm zeJVeUTCTG#WGssKdAC3?AhVVMzvk4D0`Ad$>BeRASa&C}m3o$?iUW(2tJT7d^`vY! zh1-Ih#=S)}-q}RUrs#f6{~kR5J-lY?FFWFc0szvme|e#CGI4gcur+h~Ewt9E+t@9$ zA-?h%yme0Ob0&U#%oj@U`gB4n+6tc#_N9Pih-?JICvU5<_w_k4-rOQgy@&RymuuDO ze&y1QXXu=thk41PO9`pdOwWGXgLi~E2BrO*yMF!g>&!7_gj;0MhTC5H_ba}Y*QeoU zw7)TIQ7so-VW5_78MKZy& z&!gG`#YS4Ct{Srsm}4cgMY1ELX+nKJHo9{lJf=3*4W|!K1vb?qK_Dv+2-???=Q~=T zh%W+GxMK^?X}3ZY&0JxBs?*$4eDu0=ll|P69Z%FP)d|jcgiO*3huijntH0f6VHBAb ztr4OYWCi-%<==>zSLGH`*S6*>j$X=9^cBKXkVuog4k;G8yv|-S2Rh#w(_M&CWW5x71U$sKF^y5rR>+q$hpjc4G$;-TOw~? z{KX8Z);HA#HqgA*;?a`CWX=7bk9u=PwgB`VUJ32`GFp+2aMTZfL8rse8=kVGmw6 zwwz7={@a5_waxypL9d?3xoQzZES|a;EJ=22!xKc`k*)^7p=;5U zF+Te;)i8ax^;g5-((SiBaPC&a;MAQt5|d-MbTKZ(!CA#Gi19Do1oZcWi0MO0^&;)x z)4mGr(nW-KM3R#y*1LAfMkwZNtR&jom=ogNee3n57!$oSpldFg6F2rost7#B#$P-Z zTh4{ce+dr*Q{u2=*yk$I{ZXFVdqbBx{yaQuxt1xSIFng1Kiy7H7G%f(w|_mmx<1Nj z{|0RP_K(#O$kat3dqe=hq8I=`_#;<$a(1^i`F$xl(Oq_27DN8BUh)DFpYe$RH-t!Z zsDgr0cfO(yuRoT3T-bnu2pEVCprzLCwI7Is1Cj$lE9PL+G(<%A#dM-j-nhWw`EuW` zbl`btnnq@;#%~fq90EV;g#>c@xyFy)mAz69p_RtWp(BT6&kRDIhx_5N@We`6C{v&G)wFk8XOW@c3gx{8f?vk-bi@x%a1r$W_qA zlDtr};FkU+*s_Q_8OF4Hu_lZ3(YP$~e#-qrpotgeTF7gtn0mJP+o^k60E7{YnWk4p zK$*+7(yRIEmYKWFtth5HL{N1vL`I*{wK^HDcbU40cRV#&Z>scSabI(A?|m;9{*Na| z?QY0>%YNRq7M$P19bvfdKE2YqFXIT1N(nZ?qu z-VM7ansc-N76xYqQ9@gFHQXX^k(@^~oPpQsWuvxsrTV}I3yeSiDLl!r!(036LAuY+ z@}-iUDtZ)}f3aul-i=LF5!IygmOZo5WDQN*n2hs<0*1jp5wU-Ys1(nJd(ZTEVOFmwu@&;tO$(Vk9=T`D~+4$Kw}u%F^IB`9#CgM zpq9$s^PeA10a7OH9X@eg!7)e&RILQ2>&_EJ(jrwg+0(WP1Nm zg9ko%RsBOONdQw;?@xD1QDkJ$+t5b~rdBH`;$ejIZtKQMl3>@W5F$DM+ZeJQ)VYf$ zA73m!Rt1J`GjM3rhn}oHtb{OF?3lv$(fvNwojsKvN3)RrHQ?@-b(6)ZdgsOQa$oCO zhACp^6~OPe*;=DiRX;Jr7N>m9)EGKbuGjlqU9t+V&2MVWjUjolv#OXjEk#n|&<2g9 zISju&Y9GWlQPiWlg)~^&LyW8u!meXP(8Hh!Ke0A7VrI*J-Kts(U7TcYr&&7*vb1Sw z{CELb3Tls1fRzHfWC%s{kc&Ge#YM@aKRdjMSNc70*piz%=F_+U@{N+7eZFM3UFIAQ z+H`eLrv$qsDrpo?mT>Fnv`D{}?p1$itX}L7z49a)m|2}-pvgBC{gp49Ukr{rA#Ny* z3}w2PZ%ff&h@)&lFYnH}JHh&_~fBt3v_` z(CIMtYh{F{inyQP7OLqSK;mW+>LZwhd3Xw79pKL!jV zWC3^Y%!gv53UEo+oDipWEpkff%-|1|#9rf&(0SOW%BeIvaSW1Wc3Wg$<5`b_?Z20A z7D>EDj1M-GRZ%>PDj=CC#*>KD)gAfg(tNwGIAv0n_k}&{Dhz(~Oc4Q+r|tjPfOfsB z{i4zL>0Xuna{}*r(EadAi*DlVE7!=4d7%lTprsz2z6F$u zC00FGxi(h`-;8m83SNU6fS;sB(HvEz9E_aeW?v-yOisxS%B9`O3{0mj=%G{Zdq=kj zozwWS6et(KEpop36%UwJ1=0uo=xdBG9x$nj!5N84urE55zW@xHP*wmmgaJpkkVl$A zc3YSNVd(pS)+$2$FUTLq9C6e)q;f-{<-8wGI3W~(Xr5hixdr&Y!Jr8hguwRXgaRnc zvxOjQ6$nAKik=jOUH^Y@M@F0f@8=Uy_e_e{DIT9tp8nS^L}9^`?^ zu1EpCkkpq}P)>0U@LWZfxgyhz(Q5$B9g|eQE7$g&-pHdqq|!xa&kvqPVmOmxX5EhI zZKc+pAIT1DadaL<{M<;*JP(`g*K*}BdeIX%=)U}vSD0C_`;rgHrpC2`Wabu9*AS`* zb%qU?Ok&{{(!V=_{9;i{ob^!KwGmP$oQ+j4+@uI+5}3cFTl5K(W)`tC#1gPA$LjA` zfGzYsgF>8W8T>VWiI;O3DXj>c;Y>xC!mNZa9%uGKB`_bG$e=h7QlkVSBf9)AQ}*^j z|2;+Mi!ux7OSgpFm3dd1i#-xMsUrN_iGZY8MeK91I~tYYveSwK6?9cfsigcYQM*~4 zRz8%O26Ge6!#WH$nI14`muPa2C0as8){qXUc5>R*tB{XIP9*WZUk>&uBn4kNgPYN* zf_dPng00H7skDts3(Rcf*L-Yt?P{fnZ?rD|E#4E6(Zr>q-^C~Su}`4nB@Q+Da(@U? z?%BpgC7izq5cvT$OxOQ;zHu=&!E(jAIPMQID937BKO^=x@$t8Ra+LRnc={kC z#|xwkNQJu{W@ubR(s&VN+>>{tObw4M$;u^c$X;BTw6RHz2l!&Pzgz{zi7fI6;}CAb zjYdCwp;`}Iq^jL~&v8(xtqywDh=927NCSU8PZJaMTU2Dhd|YWt(~2dZ-d)GzQ?9vw zc^r%{K}K=@QH!b5qa5R=Pu1)9l*f_9Vnv&r^`)CvE0y|>Ma(wNULPZ0)-Gc>n=Y5i z;+ApNQ>--9)>Gn2>4(lo9+h@Ye%O-L6o4};?jCEOA4^#vt>9I4k z_RU=|HF!+;&p&WORd($rUM!)BJVPcJGdo&&eo!vQ!K6a5DoTF#Fc&hp>Jr|q#itZq z3W~|u5hkF_etlEAw>4jZ4G%`K62W|%66qPdM?#V!rKfj=4F`IGTByflsL@EpOm4rx zOrA0Bzy>byX(J1Wo4;EBBrs4(r@Cp6F;w}OLER26);)p^S3o3)0#|cRgbf|UZzi~GKIn})lyS?7`YjL*`&Iu<^pRfYXIf~X*$T#( zX}ddPOMav&-*=UELWwVW7ToAG`i9jP=Ap(dZngK^NwX`Fe5IClWjPFBx4-dbIjnI%?; zYG1oe&2Efb(+;9!1D`fAt=d%4m$X;PGiI=l4l@`}?3gxFwVS#>yJ_oPIwL#p_KS5rs+3At2NGJW$B?5nT5U1Gy9KDL4`CMwIPFebAuTEe1;KBP9S<{;B44BK_w zycPq;THcY|+|p>a?AYkzt9#xr)9v1EXl{U_VppJO0vw~(Pzq%C;M%D@iDPyySB&(T(K#54 z6MlV;;mmuH^Tdf?7$BgUFhyMC^xg#NH!CR9O?mnTygYJHhnlJ)q3g@T=7-f^WA$Ro zR@Z;-Wk|VSp;HG_yU19dhCAr}MI$!@T)o0F-?&K1GHpq7fikA;a|Q3mUDddw8r5J_&pV+xN(QOQ8W$?h;kY_E<=)V5L<5H2>~8cVxbS{MuoRt<9@DsaZ)(g9o|s zG%v9bytuXQ85}q5x{<7g`rY)~ zKUO-))}AEn-pdxW@6}G!KZ+BsCPvDCDR!n!uiAEfKm}|(lX?UNdgODlN*l9kq9?7= zNZ0cMx{67G3xRZ8O{pJ7zD!Aq&qv`b5ZMl0%=9?ZYH7VGfCagyJ;VyaA^e{T|uN~Fsv3RO+nCY z$xdB7t-!XQLA!ROO}K&JlAFe|!14(56(!{4Azrs&Xdf&@S3#U?R8l+3n{6;>)l$^l z+0fC5QWKYFwip{RcLcK-q~)Ud$v{(3UX(5LL}5cz{`%E|-@p@WgyZBHE2>;j*mOQ7 zCzF|*Tgf@?4Q(2zrvih~i(?k)Tk={}+C|PufBIN(pU$4Q++#lB2F&)jZS&Nr!h)+lL%9bGP!=co^2;h^G*!?gTRw^;CGql4X z!F)C3bN7lOz(>#`_1F~9sv%hnjupYQg|VoYzIv^1PmcrTVFpv43nt}+{t#9A%?@ES zr?yYn_ZA#Im0oi9OPhr9M#2QFSUoy;T)s=H`%mX(73TY@QoE*E)@w)NgqwbrLT53q z@RmTMVI{{)qenTIZR0OT{z5sd3WL~kwR_lF#=45!!(f2BGS%T}nN()7Z#rLVcgB2a zUm(97s-Y@sWK3dO+(IS8gX~~@#li?O40rFBsHz^1>17x@8Ho{%y0!~D1PWdKAi~F2 zPTVTw9t9RaUt-uejh~;L=&r_C)Q&988qRTuv<#%2=zWu7lx#80d{NYmZ`uA(#X46N zA%rYv;_H_nV(+%~>aPylOL)|oNJpUxIZ>zT>KJEgm@GD-d`c_QWZLIDz))khz>|6- zLzzBdpza|rf$g<}=JWwL=Ow1zaj;gUKMpzq)EuSmrj_f^WACGRwye*Jkr4z=Gl|<3 z#pu3ko@%u~}RXO}`x$1Seu`ZpMYwLJ9bpQy4|!u#yq-tarXAyj#Kp8q6rpjyMxjiB zeSd=cr$&Zd2Ccr$yL(^0TM*JayX2ixqTpy}??i8G=lHwvyz>|TLn(Q8tF%~MJ6{IW z!1JUN{^&JfAZBAo115}07EPuk+Lq&`+)qNwwW>Som0vd&T9;NI-Nu%u8)WzQt1slT z;F5@h6%mOLKoi2lbOZI+rM&}rj6)3aqJf!I`~yHSVb$#cCuS;i>uK55U{w1}f|Ll7?&e;t1-)g&q(M9(*W{Y&HkO z>{Sqe>cYkaLu#)^e{V#=*QOJE9JDFlAX{RGc(Q%~sHvi<#G$)9i$8p6`)pBp7Ax_NQ?w42x0=Gas$cK#vU zz7B=a1Q+_n;wb1yy5K6S`&w=Ild9J*6Z%;xllEJq>jT?~m{T`K&JDN><5=;|pYGBd z2DdC~MBH)v5WG;IFP%|>BzdH}E^-&`SiI3_=wW_pS798`V0%yf#Q7&170}(Fwtu(L z{&yQi{Hu)`+S~uOzWv8U-|h1^6IB|PduKhh5?>-Ho|RAILzmQ7C{XwKi0231SucL; z>8he#&bm8aWI^<8+?+lub7f&>E0ZrDyKvX3#YKw*_D;@8q|n~t0$7Pu(nWYng|uKDM~4&qIEdl@d#t9 za#y6m%s|!(u-t;^YBkgG%6p5YBIo{csgS{Y=|E9+D@L+2zFLq%m84|=0-Z1272hn% zN9<;9KyDe1H-};GEGWtcF^BQpLIjaX(aWB(flA{&#ngCE65pmXW4g-q z{Sxg1gh%|jU?DU8*9dL5nfjzj3=-;KF35FH3mmQmX+wMAHFr`O5d(gJwa#$>DHoec z&po>Sm&1BpSbgdroiY8na-(Z7ixy2-EqHJS@)T6D{1lh~x2%20g4{w~?cAsKYuAZg z*Mm1wQEu7;9pLA_fx8RC2lDrO{a-C%AYj_}r0AbN%=rD0{6+l3XBrC9e^>B#8u?$a zfVg+^-(N`OzXE^d*Zv8u0sjZK?XU2^Qw;wE0|4hx|APMygu`Do{YpFgQy1xbr~DsD zXuqoXwYC1I3V)P;srYN7{a5&}&9pz^lNf)%|GTyJEBM!B_fN1b#lOJ6q`tpu_%$2* zQv(9kzcl Date: Mon, 29 Dec 2025 14:07:22 -0300 Subject: [PATCH 019/125] feat: include previous element when building add diff --- .../src/extensions/diffing/algorithm/sequence-diffing.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js index 68af0d854a..21fceb8215 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js @@ -3,7 +3,7 @@ import { myersDiff } from './myers-diff.js'; /** * @typedef {Object} SequenceDiffOptions * @property {(a: any, b: any) => boolean} [comparator] equality test passed to Myers diff - * @property {(item: any, index: number) => any} buildAdded maps newly inserted entries + * @property {(item: any, oldIdx: number, previousOldItem: any, index: number) => any} buildAdded maps newly inserted entries * @property {(item: any, index: number) => any} buildDeleted maps removed entries * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => any|null} buildModified maps paired entries. If it returns null/undefined, it means no modification should be recorded. * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [shouldProcessEqualAsModification] decides if equal-aligned entries should emit a modification @@ -82,7 +82,10 @@ export function diffSequences(oldSeq, newSeq, options) { } if (step.type === 'insert') { - diffs.push(options.buildAdded(newSeq[step.newIdx], step.oldIdx, step.newIdx)); + const diff = options.buildAdded(newSeq[step.newIdx], step.oldIdx, oldSeq[step.oldIdx - 1], step.newIdx); + if (diff) { + diffs.push(diff); + } } } From 64473b51c42e3d8540ff1ea23411f487ee6c6f90 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 14:07:46 -0300 Subject: [PATCH 020/125] docs: add JSDoc to inline diffing --- .../diffing/algorithm/inline-diffing.js | 59 +++++++++++++++---- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js index 638b553d4f..2785d8ea49 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js @@ -1,17 +1,32 @@ -import { myersDiff } from './myers-diff.js'; import { getAttributesDiff } from './attributes-diffing.js'; import { diffSequences } from './sequence-diffing.js'; /** - * Computes text-level additions and deletions between two strings using Myers diff algorithm, mapping back to document positions. - * @param {{char: string, runAttrs: Record}[]} oldContent - Source text. - * @param {{char: string, runAttrs: Record}[]} newContent - Target text. + * @typedef {{kind: 'text', char: string, runAttrs: string}} InlineTextToken + */ + +/** + * @typedef {{kind: 'inlineNode', node: import('prosemirror-model').Node, nodeType?: string}} InlineNodeToken + */ + +/** + * @typedef {InlineTextToken|InlineNodeToken} InlineDiffToken + */ + +/** + * @typedef {{action: 'added'|'deleted'|'modified', kind: 'text'|'inlineNode', startPos: number|null, endPos: number|null, text?: string, oldText?: string, newText?: string, runAttrs?: Record, runAttrsDiff?: import('./attributes-diffing.js').AttributesDiff, node?: import('prosemirror-model').Node, nodeType?: string, oldNode?: import('prosemirror-model').Node, newNode?: import('prosemirror-model').Node}} InlineDiffResult + */ + +/** + * Computes text-level additions and deletions between two sequences using the generic sequence diff, mapping back to document positions. + * @param {InlineDiffToken[]} oldContent - Source tokens. + * @param {InlineDiffToken[]} newContent - Target tokens. * @param {(index: number) => number|null} oldPositionResolver - Maps string indexes to the original document. * @param {(index: number) => number|null} [newPositionResolver=oldPositionResolver] - Maps string indexes to the updated document. - * @returns {Array} List of addition/deletion ranges with document positions and text content. + * @returns {InlineDiffResult[]} List of grouped inline diffs with document positions and text content. */ export function getInlineDiff(oldContent, newContent, oldPositionResolver, newPositionResolver = oldPositionResolver) { - const buildCharDiff = (action, token, oldIdx) => { + const buildInlineDiff = (action, token, oldIdx) => { if (token.kind !== 'text') { return { action, @@ -31,11 +46,11 @@ export function getInlineDiff(oldContent, newContent, oldPositionResolver, newPo let diffs = diffSequences(oldContent, newContent, { comparator: inlineComparator, shouldProcessEqualAsModification, - canTreatAsModification: (oldToken, newToken, oldIdx, newIdx) => + canTreatAsModification: (oldToken, newToken) => oldToken.kind === newToken.kind && oldToken.kind !== 'text' && oldToken.node.type.type === newToken.node.type, - buildAdded: (token, oldIdx, newIdx) => buildCharDiff('added', token, oldIdx), - buildDeleted: (token, oldIdx, newIdx) => buildCharDiff('deleted', token, oldIdx), - buildModified: (oldToken, newToken, oldIdx, newIdx) => { + buildAdded: (token, oldIdx) => buildInlineDiff('added', token, oldIdx), + buildDeleted: (token, oldIdx) => buildInlineDiff('deleted', token, oldIdx), + buildModified: (oldToken, newToken, oldIdx) => { if (oldToken.kind !== 'text') { return { action: 'modified', @@ -63,6 +78,13 @@ export function getInlineDiff(oldContent, newContent, oldPositionResolver, newPo return groupedDiffs; } +/** + * Compares two inline tokens to decide if they can be considered equal for the Myers diff. + * Text tokens compare character equality while inline nodes compare their type. + * @param {InlineDiffToken} a + * @param {InlineDiffToken} b + * @returns {boolean} + */ function inlineComparator(a, b) { if (a.kind !== b.kind) { return false; @@ -71,18 +93,31 @@ function inlineComparator(a, b) { if (a.kind === 'text') { return a.char === b.char; } else { - return true; + return a.node.type === b.node.type; } } +/** + * Determines whether equal tokens should still be treated as modifications, either because run attributes changed or the node payload differs. + * @param {InlineDiffToken} oldToken + * @param {InlineDiffToken} newToken + * @returns {boolean} + */ function shouldProcessEqualAsModification(oldToken, newToken) { if (oldToken.kind === 'text') { return oldToken.runAttrs !== newToken.runAttrs; } else { - return JSON.stringify(oldToken.nodeAttrs) !== JSON.stringify(newToken.nodeAttrs); + return JSON.stringify(oldToken.toJSON()) !== JSON.stringify(newToken.toJSON()); } } +/** + * Groups raw diff operations into contiguous ranges and converts serialized run attrs back to objects. + * @param {Array<{action:'added'|'deleted'|'modified', idx:number, kind:'text'|'inlineNode', text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string, nodeType?: string, node?: import('prosemirror-model').Node, oldNode?: import('prosemirror-model').Node, newNode?: import('prosemirror-model').Node}>} diffs + * @param {(index: number) => number|null} oldPositionResolver + * @param {(index: number) => number|null} newPositionResolver + * @returns {InlineDiffResult[]} + */ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { const grouped = []; let currentGroup = null; From 907dd3df711e4374a7a418cfb515e64473896f96 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 14:08:18 -0300 Subject: [PATCH 021/125] fix: handle arrays in attributes diff --- .../diffing/algorithm/attributes-diffing.js | 46 +++++++++++++++++++ .../algorithm/attributes-diffing.test.js | 41 +++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js index 776fce854a..2346d5c28e 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js @@ -65,6 +65,12 @@ function diffObjects(objectA, objectB, basePath, diff) { continue; } + if (Array.isArray(valueA) && Array.isArray(valueB)) { + if (valueA.length === valueB.length && valueA.every((item, index) => deepEquals(item, valueB[index]))) { + continue; + } + } + if (valueA !== valueB) { diff.modified[path] = { from: valueA, @@ -130,3 +136,43 @@ function joinPath(base, key) { function isPlainObject(value) { return Boolean(value) && typeof value === 'object' && !Array.isArray(value); } + +/** + * Checks deep equality for primitives, arrays, and plain objects. + * @param {any} a + * @param {any} b + * @returns {boolean} + */ +function deepEquals(a, b) { + if (a === b) { + return true; + } + + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (!deepEquals(a[i], b[i])) { + return false; + } + } + return true; + } + + if (isPlainObject(a) && isPlainObject(b)) { + const keysA = Object.keys(a); + const keysB = Object.keys(b); + if (keysA.length !== keysB.length) { + return false; + } + for (const key of keysA) { + if (!deepEquals(a[key], b[key])) { + return false; + } + } + return true; + } + + return false; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js index 0b9316c837..2b9c26998c 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js @@ -122,4 +122,45 @@ describe('getAttributesDiff', () => { 'nested.value': { from: 1, to: 2 }, }); }); + + it('handles array equality and modifications', () => { + const objectA = { + tags: ['alpha', 'beta'], + nested: { + metrics: [ + { name: 'views', value: 10 }, + { name: 'likes', value: 5 }, + ], + }, + }; + + const objectB = { + tags: ['alpha', 'beta'], + nested: { + metrics: [ + { name: 'views', value: 12 }, + { name: 'likes', value: 5 }, + ], + }, + }; + + let diff = getAttributesDiff(objectA, objectB); + expect(diff.added).toEqual({}); + expect(diff.deleted).toEqual({}); + expect(diff.modified).toEqual({ + 'nested.metrics': { + from: [ + { name: 'views', value: 10 }, + { name: 'likes', value: 5 }, + ], + to: [ + { name: 'views', value: 12 }, + { name: 'likes', value: 5 }, + ], + }, + }); + + diff = getAttributesDiff(objectA, { ...objectA }); + expect(diff).toBeNull(); + }); }); From 37feb55a7565518f8f66b6ee4d56dff1dd19b5d7 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 14:09:03 -0300 Subject: [PATCH 022/125] feat: implement generic diffing for all nodes --- .../diffing/algorithm/generic-diffing.js | 199 ++++++++++++++++++ .../diffing/algorithm/generic-diffing.test.js | 166 +++++++++++++++ 2 files changed, 365 insertions(+) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.js new file mode 100644 index 0000000000..b5d160bebc --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.js @@ -0,0 +1,199 @@ +import { + getParagraphContent, + paragraphComparator, + canTreatAsModification as canTreatParagraphDeletionInsertionAsModification, + shouldProcessEqualAsModification as shouldProcessEqualParagraphsAsModification, + buildAddedParagraphDiff, + buildDeletedParagraphDiff, + buildModifiedParagraphDiff, +} from './paragraph-diffing.js'; +import { diffSequences, reorderDiffOperations } from './sequence-diffing.js'; +import { getAttributesDiff } from './attributes-diffing.js'; + +/** + * @typedef {import('prosemirror-model').Node} PMNode + */ + +/** + * @typedef {Object} BaseNodeInfo + * @property {PMNode} node + * @property {number} pos + */ + +/** + * @typedef {BaseNodeInfo & { + * text: import('./paragraph-diffing.js').ParagraphContentToken[], + * resolvePosition: (idx: number) => number|null, + * fullText: string + * }} ParagraphNodeInfo + */ + +/** + * @typedef {BaseNodeInfo | ParagraphNodeInfo} NodeInfo + */ + +/** + * Produces a sequence diff between two ProseMirror documents, flattening paragraphs for inline-aware comparisons. + * @param {PMNode} oldRoot + * @param {PMNode} newRoot + * @returns {Array} + */ +export function diffNodes(oldRoot, newRoot) { + const oldNodes = normalizeNodes(oldRoot); + const newNodes = normalizeNodes(newRoot); + + const addedNodesSet = new Set(); + return diffSequences(oldNodes, newNodes, { + comparator: nodeComparator, + reorderOperations: reorderDiffOperations, + shouldProcessEqualAsModification, + canTreatAsModification, + buildAdded: (nodeInfo, oldIdx, previousOldNodeInfo) => buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet), + buildDeleted: buildDeletedDiff, + buildModified: buildModifiedDiff, + }); +} + +/** + * Traverses a ProseMirror document and converts paragraphs to richer node info objects. + * @param {PMNode} pmDoc + * @returns {NodeInfo[]} + */ +function normalizeNodes(pmDoc) { + const nodes = []; + pmDoc.descendants((node, pos) => { + if (node.type.name === 'paragraph') { + const { text, resolvePosition } = getParagraphContent(node, pos); + nodes.push({ + node, + pos, + text, + resolvePosition, + get fullText() { + return text.map((c) => c.char).join(''); + }, + }); + return false; // Do not descend further + } else { + nodes.push({ node, pos }); + } + }); + return nodes; +} + +/** + * Compares two node infos to determine if they correspond to the same logical node. + * Paragraphs are compared with `paragraphComparator`, while other nodes are matched by type name. + * @param {NodeInfo} oldNodeInfo + * @param {NodeInfo} newNodeInfo + * @returns {boolean} + */ +function nodeComparator(oldNodeInfo, newNodeInfo) { + if (oldNodeInfo.node.type.name !== newNodeInfo.node.type.name) { + return false; + } + if (oldNodeInfo.node.type.name === 'paragraph') { + return paragraphComparator(oldNodeInfo, newNodeInfo); + } else { + return oldNodeInfo.node.type.name === newNodeInfo.node.type.name; + } +} + +/** + * Decides whether nodes deemed equal by the diff should still be emitted as modifications. + * Paragraph nodes leverage their specialized handler, while other nodes compare attribute JSON. + * @param {NodeInfo} oldNodeInfo + * @param {NodeInfo} newNodeInfo + * @returns {boolean} + */ +function shouldProcessEqualAsModification(oldNodeInfo, newNodeInfo) { + if (oldNodeInfo.node.type.name === 'paragraph' && newNodeInfo.node.type.name === 'paragraph') { + return shouldProcessEqualParagraphsAsModification(oldNodeInfo, newNodeInfo); + } + return JSON.stringify(oldNodeInfo.node.attrs) !== JSON.stringify(newNodeInfo.node.attrs); +} + +/** + * Determines whether a delete/insert pair should instead be surfaced as a modification. + * Only paragraphs qualify because we can measure textual similarity; other nodes remain as-is. + * @param {NodeInfo} deletedNodeInfo + * @param {NodeInfo} insertedNodeInfo + * @returns {boolean} + */ +function canTreatAsModification(deletedNodeInfo, insertedNodeInfo) { + if (deletedNodeInfo.node.type.name === 'paragraph' && insertedNodeInfo.node.type.name === 'paragraph') { + return canTreatParagraphDeletionInsertionAsModification(deletedNodeInfo, insertedNodeInfo); + } + return false; +} + +/** + * Builds the diff payload for an inserted node and tracks descendants to avoid duplicates. + * @param {NodeInfo} nodeInfo + * @param {NodeInfo} previousOldNodeInfo + * @param {Set} addedNodesSet + * @returns {ReturnType|{action:'added', nodeType:string, node:PMNode, pos:number}|null} + */ +function buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet) { + if (addedNodesSet.has(nodeInfo.node)) { + return null; + } + addedNodesSet.add(nodeInfo.node); + if (nodeInfo.node.type.name === 'paragraph') { + return buildAddedParagraphDiff(nodeInfo, previousOldNodeInfo); + } + nodeInfo.node.descendants((childNode) => { + addedNodesSet.add(childNode); + }); + + const pos = previousOldNodeInfo.pos + previousOldNodeInfo.node.nodeSize; + return { + action: 'added', + nodeType: nodeInfo.node.type.name, + node: nodeInfo.node, + pos, + }; +} + +/** + * Builds the diff payload for a deleted node. + * @param {NodeInfo} nodeInfo + * @returns {ReturnType|{action:'deleted', nodeType:string, node:PMNode, pos:number}} + */ +function buildDeletedDiff(nodeInfo) { + if (nodeInfo.node.type.name === 'paragraph') { + return buildDeletedParagraphDiff(nodeInfo); + } + return { + action: 'deleted', + nodeType: nodeInfo.node.type.name, + node: nodeInfo.node, + pos: nodeInfo.pos, + }; +} + +/** + * Builds the diff payload for a modified node. + * Paragraphs delegate to their inline-aware builder, while other nodes report attribute diffs. + * @param {NodeInfo} oldNodeInfo + * @param {NodeInfo} newNodeInfo + * @returns {ReturnType|{action:'modified', nodeType:string, oldNode:PMNode, newNode:PMNode, pos:number, attrsDiff: import('./attributes-diffing.js').AttributesDiff}|null} + */ +function buildModifiedDiff(oldNodeInfo, newNodeInfo) { + if (oldNodeInfo.node.type.name === 'paragraph' && newNodeInfo.node.type.name === 'paragraph') { + return buildModifiedParagraphDiff(oldNodeInfo, newNodeInfo); + } + + const attrsDiff = getAttributesDiff(oldNodeInfo.node.attrs, newNodeInfo.node.attrs); + if (!attrsDiff) { + return null; + } + return { + action: 'modified', + nodeType: oldNodeInfo.node.type.name, + oldNode: oldNodeInfo.node, + newNode: newNodeInfo.node, + pos: newNodeInfo.pos, + attrsDiff, + }; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js new file mode 100644 index 0000000000..8c5ef5b2e9 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js @@ -0,0 +1,166 @@ +import { describe, it, expect } from 'vitest'; +import { diffNodes } from './generic-diffing.js'; + +const createDocFromNodes = (nodes = []) => ({ + descendants(callback) { + nodes.forEach(({ node, pos }) => callback(node, pos)); + }, +}); + +const buildSimpleNode = (typeName, attrs = {}, options = {}) => { + const { nodeSize = 2, children = [] } = options; + const node = { + attrs, + type: { name: typeName, spec: {} }, + nodeSize, + descendants(cb) { + children.forEach((child, index) => { + cb(child, index + 1); + if (typeof child.descendants === 'function') { + child.descendants(cb); + } + }); + }, + }; + node.toJSON = () => ({ type: node.type.name, attrs: node.attrs }); + return node; +}; + +const createParagraph = (text, attrs = {}, options = {}) => { + const { pos = 0, textAttrs = {} } = options; + const paragraphNode = { + attrs, + type: { name: 'paragraph', spec: {} }, + nodeSize: text.length + 2, + content: { size: text.length }, + nodesBetween(_from, _to, callback) { + if (!text.length) { + return; + } + callback( + { + isText: true, + text, + type: { name: 'text', spec: {} }, + isLeaf: false, + isInline: true, + }, + 1, + ); + }, + nodeAt() { + return { attrs: textAttrs }; + }, + }; + paragraphNode.toJSON = () => ({ type: paragraphNode.type.name, attrs: paragraphNode.attrs }); + + return { node: paragraphNode, pos }; +}; + +describe('diffParagraphs', () => { + it('treats similar paragraphs without IDs as modifications', () => { + const oldParagraphs = [createParagraph('Hello world from ProseMirror.')]; + const newParagraphs = [createParagraph('Hello brave new world from ProseMirror.')]; + const oldRoot = { descendants: (cb) => oldParagraphs.forEach((p) => cb(p.node, p.pos)) }; + const newRoot = { descendants: (cb) => newParagraphs.forEach((p) => cb(p.node, p.pos)) }; + + const diffs = diffNodes(oldRoot, newRoot); + + expect(diffs).toHaveLength(1); + expect(diffs[0].action).toBe('modified'); + expect(diffs[0].contentDiff.length).toBeGreaterThan(0); + }); + + it('keeps unrelated paragraphs as deletion + addition', () => { + const oldParagraphs = [createParagraph('Alpha paragraph with some text.')]; + const newParagraphs = [createParagraph('Zephyr quickly jinxed the new passage.')]; + const oldRoot = { descendants: (cb) => oldParagraphs.forEach((p) => cb(p.node, p.pos)) }; + const newRoot = { descendants: (cb) => newParagraphs.forEach((p) => cb(p.node, p.pos)) }; + + const diffs = diffNodes(oldRoot, newRoot); + + expect(diffs).toHaveLength(2); + expect(diffs[0].action).toBe('deleted'); + expect(diffs[1].action).toBe('added'); + }); + + it('detects modifications even when Myers emits grouped deletes and inserts', () => { + const oldParagraphs = [ + createParagraph('Original introduction paragraph that needs tweaks.'), + createParagraph('Paragraph that will be removed.'), + ]; + const newParagraphs = [ + createParagraph('Original introduction paragraph that now has tweaks.'), + createParagraph('Completely different replacement paragraph.'), + ]; + const oldRoot = { descendants: (cb) => oldParagraphs.forEach((p) => cb(p.node, p.pos)) }; + const newRoot = { descendants: (cb) => newParagraphs.forEach((p) => cb(p.node, p.pos)) }; + + const diffs = diffNodes(oldRoot, newRoot); + + expect(diffs).toHaveLength(3); + expect(diffs[0].action).toBe('modified'); + expect(diffs[0].contentDiff.length).toBeGreaterThan(0); + expect(diffs[1].action).toBe('deleted'); + expect(diffs[2].action).toBe('added'); + }); + + it('treats paragraph attribute-only changes as modifications', () => { + const oldParagraph = createParagraph('Consistent text', { align: 'left' }); + const newParagraph = createParagraph('Consistent text', { align: 'right' }); + const diffs = diffNodes(createDocFromNodes([oldParagraph]), createDocFromNodes([newParagraph])); + + expect(diffs).toHaveLength(1); + expect(diffs[0].action).toBe('modified'); + expect(diffs[0].contentDiff).toEqual([]); + expect(diffs[0].attrsDiff?.modified?.align).toEqual({ from: 'left', to: 'right' }); + }); + + it('emits attribute diffs for non-paragraph nodes', () => { + const oldHeading = { node: buildSimpleNode('heading', { level: 1 }), pos: 0 }; + const newHeading = { node: buildSimpleNode('heading', { level: 2 }), pos: 0 }; + const diffs = diffNodes(createDocFromNodes([oldHeading]), createDocFromNodes([newHeading])); + + expect(diffs).toHaveLength(1); + expect(diffs[0]).toMatchObject({ + action: 'modified', + nodeType: 'heading', + }); + expect(diffs[0].attrsDiff?.modified?.level).toEqual({ from: 1, to: 2 }); + }); + + it('deduplicates added nodes and their descendants', () => { + const childNode = buildSimpleNode('image'); + const parentNode = buildSimpleNode('figure', {}, { children: [childNode] }); + const oldParagraph = createParagraph('Base paragraph', {}, { pos: 0 }); + const newParagraph = createParagraph('Base paragraph', {}, { pos: 0 }); + const insertionPos = oldParagraph.pos + oldParagraph.node.nodeSize; + const diffs = diffNodes( + createDocFromNodes([oldParagraph]), + createDocFromNodes([ + newParagraph, + { node: parentNode, pos: insertionPos }, + { node: childNode, pos: insertionPos + 1 }, + ]), + ); + + const additions = diffs.filter((diff) => diff.action === 'added'); + expect(additions).toHaveLength(1); + expect(additions[0].nodeType).toBe('figure'); + }); + + it('computes insertion position based on the previous old node', () => { + const oldParagraph = createParagraph('Hello!', {}, { pos: 0 }); + const newParagraph = createParagraph('Hello!', {}, { pos: 0 }); + const headingNode = buildSimpleNode('heading', { level: 1 }, { nodeSize: 3 }); + const expectedPos = oldParagraph.pos + oldParagraph.node.nodeSize; + + const diffs = diffNodes( + createDocFromNodes([oldParagraph]), + createDocFromNodes([newParagraph, { node: headingNode, pos: expectedPos }]), + ); + + const addition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'heading'); + expect(addition?.pos).toBe(expectedPos); + }); +}); From 354176512a992fa1e7803b9409cf1a3b3cc62396 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 14:09:31 -0300 Subject: [PATCH 023/125] refactor: move paragraph utility functions --- .../diffing/algorithm/paragraph-diffing.js | 154 ++++++-- .../algorithm/paragraph-diffing.test.js | 343 +++++++++++++++--- .../src/extensions/diffing/utils.js | 93 ----- .../src/extensions/diffing/utils.test.js | 203 ----------- 4 files changed, 419 insertions(+), 374 deletions(-) delete mode 100644 packages/super-editor/src/extensions/diffing/utils.js delete mode 100644 packages/super-editor/src/extensions/diffing/utils.test.js diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js index a7a6ce0f62..e852b01895 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js @@ -1,7 +1,5 @@ -import { myersDiff } from './myers-diff.js'; import { getInlineDiff } from './inline-diffing.js'; import { getAttributesDiff } from './attributes-diffing.js'; -import { diffSequences, reorderDiffOperations } from './sequence-diffing.js'; import { levenshteinDistance } from './similarity.js'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. @@ -12,6 +10,7 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; * A paragraph addition diff emitted when new content is inserted. * @typedef {Object} AddedParagraphDiff * @property {'added'} action + * @property {string} nodeType ProseMirror node.name for downstream handling * @property {Node} node reference to the ProseMirror node for consumers needing schema details * @property {string} text textual contents of the inserted paragraph * @property {number} pos document position where the paragraph was inserted @@ -21,6 +20,7 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; * A paragraph deletion diff emitted when content is removed. * @typedef {Object} DeletedParagraphDiff * @property {'deleted'} action + * @property {string} nodeType ProseMirror node.name for downstream handling * @property {Node} node reference to the original ProseMirror node * @property {string} oldText text that was removed * @property {number} pos starting document position of the original paragraph @@ -30,10 +30,11 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; * A paragraph modification diff that carries inline text-level changes. * @typedef {Object} ModifiedParagraphDiff * @property {'modified'} action + * @property {string} nodeType ProseMirror node.name for downstream handling * @property {string} oldText text before the edit * @property {string} newText text after the edit * @property {number} pos original document position for anchoring UI - * @property {Array} contentDiff granular inline diff data + * @property {ReturnType} contentDiff granular inline diff data * @property {import('./attributes-diffing.js').AttributesDiff|null} attrsDiff attribute-level changes between the old and new paragraph nodes */ @@ -43,36 +44,112 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; */ /** - * Runs a paragraph-level diff using Myers algorithm to align paragraphs that move, get edited, or are added/removed. - * The extra bookkeeping around the raw diff ensures that downstream consumers can map operations back to paragraph - * positions. - * @param {Array} oldParagraphs - * @param {Array} newParagraphs - * @returns {Array} + * A flattened representation of a text token derived from a paragraph. + * @typedef {Object} ParagraphTextToken + * @property {'text'} kind + * @property {string} char + * @property {string} runAttrs JSON stringified run attributes originating from the parent node */ -export function diffParagraphs(oldParagraphs, newParagraphs) { - return diffSequences(oldParagraphs, newParagraphs, { - comparator: paragraphComparator, - reorderOperations: reorderDiffOperations, - shouldProcessEqualAsModification: (oldParagraph, newParagraph) => - JSON.stringify(oldParagraph.text) !== JSON.stringify(newParagraph.text) || - JSON.stringify(oldParagraph.node.attrs) !== JSON.stringify(newParagraph.node.attrs), - canTreatAsModification, - buildAdded: (paragraph) => buildAddedParagraphDiff(paragraph), - buildDeleted: (paragraph) => buildDeletedParagraphDiff(paragraph), - buildModified: (oldParagraph, newParagraph) => buildModifiedParagraphDiff(oldParagraph, newParagraph), - }); + +/** + * A flattened representation of an inline node that is treated as a single token by the diff. + * @typedef {Object} ParagraphInlineNodeToken + * @property {'inlineNode'} kind + * @property {Node} node + */ + +/** + * @typedef {ParagraphTextToken|ParagraphInlineNodeToken} ParagraphContentToken + */ + +/** + * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. + * @param {Node} paragraph - Paragraph node to flatten. + * @param {number} [paragraphPos=0] - Position of the paragraph in the document. + * @returns {{text: ParagraphContentToken[], resolvePosition: (index: number) => number|null}} Concatenated text tokens and a resolver that maps indexes to document positions. + */ +export function getParagraphContent(paragraph, paragraphPos = 0) { + let content = []; + const segments = []; + + paragraph.nodesBetween( + 0, + paragraph.content.size, + (node, pos) => { + let nodeText = ''; + + if (node.isText) { + nodeText = node.text; + } else if (node.isLeaf && node.type.spec.leafText) { + nodeText = node.type.spec.leafText(node); + } else if (node.type.name !== 'run' && node.isInline) { + const start = content.length; + const end = start + 1; + content.push({ + kind: 'inlineNode', + node: node, + }); + segments.push({ start, end, pos }); + return; + } else { + return; + } + + const start = content.length; + const end = start + nodeText.length; + + const runNode = paragraph.nodeAt(pos - 1); + const runAttrs = runNode.attrs || {}; + + segments.push({ start, end, pos }); + const chars = nodeText.split('').map((char) => ({ + kind: 'text', + char, + runAttrs: JSON.stringify(runAttrs), + })); + + content = content.concat(chars); + }, + 0, + ); + + const resolvePosition = (index) => { + if (index < 0 || index > content.length) { + return null; + } + + for (const segment of segments) { + if (index >= segment.start && index < segment.end) { + return paragraphPos + 1 + segment.pos + (index - segment.start); + } + } + + // If index points to the end of the string, return the paragraph end + return paragraphPos + 1 + paragraph.content.size; + }; + + return { text: content, resolvePosition }; +} + +/** + * Determines whether equal paragraph nodes should still be marked as modified because their serialized structure differs. + * @param {{node: Node}} oldParagraph + * @param {{node: Node}} newParagraph + * @returns {boolean} + */ +export function shouldProcessEqualAsModification(oldParagraph, newParagraph) { + return JSON.stringify(oldParagraph.node.toJSON()) !== JSON.stringify(newParagraph.node.toJSON()); } /** * Compares two paragraphs for identity based on paraId or text content so the diff can prioritize logical matches. * This prevents the algorithm from treating the same paragraph as a deletion+insertion when the paraId or text proves * they refer to the same logical node, which in turn keeps visual diffs stable. - * @param {{node: Node, text: string}} oldParagraph - * @param {{node: Node, text: string}} newParagraph + * @param {{node: Node, fullText: string}} oldParagraph + * @param {{node: Node, fullText: string}} newParagraph * @returns {boolean} */ -function paragraphComparator(oldParagraph, newParagraph) { +export function paragraphComparator(oldParagraph, newParagraph) { const oldId = oldParagraph?.node?.attrs?.paraId; const newId = newParagraph?.node?.attrs?.paraId; if (oldId && newId && oldId === newId) { @@ -83,26 +160,30 @@ function paragraphComparator(oldParagraph, newParagraph) { /** * Builds a normalized payload describing a paragraph addition, ensuring all consumers receive the same metadata shape. - * @param {{node: Node, pos: number, text: string}} paragraph + * @param {{node: Node, pos: number, fullText: string}} paragraph + * @param {{node: Node, pos: number}} previousOldNodeInfo node/position reference used to determine insertion point * @returns {AddedParagraphDiff} */ -function buildAddedParagraphDiff(paragraph) { +export function buildAddedParagraphDiff(paragraph, previousOldNodeInfo) { + const pos = previousOldNodeInfo.pos + previousOldNodeInfo.node.nodeSize; return { action: 'added', + nodeType: paragraph.node.type.name, node: paragraph.node, text: paragraph.fullText, - pos: paragraph.pos, + pos: pos, }; } /** * Builds a normalized payload describing a paragraph deletion so diff consumers can show removals with all context. - * @param {{node: Node, pos: number}} paragraph + * @param {{node: Node, pos: number, fullText: string}} paragraph * @returns {DeletedParagraphDiff} */ -function buildDeletedParagraphDiff(paragraph) { +export function buildDeletedParagraphDiff(paragraph) { return { action: 'deleted', + nodeType: paragraph.node.type.name, node: paragraph.node, oldText: paragraph.fullText, pos: paragraph.pos, @@ -111,11 +192,11 @@ function buildDeletedParagraphDiff(paragraph) { /** * Builds the payload for a paragraph modification, including text-level diffs, so renderers can highlight edits inline. - * @param {{node: Node, pos: number, text: string, resolvePosition: Function}} oldParagraph - * @param {{node: Node, pos: number, text: string, resolvePosition: Function}} newParagraph - * @returns {ModifiedParagraphDiff} + * @param {{node: Node, pos: number, text: ParagraphContentToken[], resolvePosition: Function, fullText: string}} oldParagraph + * @param {{node: Node, pos: number, text: ParagraphContentToken[], resolvePosition: Function, fullText: string}} newParagraph + * @returns {ModifiedParagraphDiff|null} */ -function buildModifiedParagraphDiff(oldParagraph, newParagraph) { +export function buildModifiedParagraphDiff(oldParagraph, newParagraph) { const contentDiff = getInlineDiff( oldParagraph.text, newParagraph.text, @@ -130,6 +211,7 @@ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { return { action: 'modified', + nodeType: oldParagraph.node.type.name, oldText: oldParagraph.fullText, newText: newParagraph.fullText, pos: oldParagraph.pos, @@ -141,11 +223,11 @@ function buildModifiedParagraphDiff(oldParagraph, newParagraph) { /** * Decides whether a delete/insert pair should be reinterpreted as a modification to minimize noisy diff output. * This heuristic limits the number of false-positive additions/deletions, which keeps reviewers focused on real edits. - * @param {{node: Node, text: string}} oldParagraph - * @param {{node: Node, text: string}} newParagraph + * @param {{node: Node, fullText: string}} oldParagraph + * @param {{node: Node, fullText: string}} newParagraph * @returns {boolean} */ -function canTreatAsModification(oldParagraph, newParagraph) { +export function canTreatAsModification(oldParagraph, newParagraph) { if (paragraphComparator(oldParagraph, newParagraph)) { return true; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index 3429bd9066..b457e38d86 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -1,63 +1,322 @@ import { describe, it, expect } from 'vitest'; -import { diffParagraphs } from './paragraph-diffing.js'; +import { + getParagraphContent, + shouldProcessEqualAsModification, + paragraphComparator, + buildAddedParagraphDiff, + buildDeletedParagraphDiff, + buildModifiedParagraphDiff, + canTreatAsModification, +} from './paragraph-diffing.js'; -const buildTextRuns = (text, runAttrs = {}) => - text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs) })); +const buildRuns = (text, attrs = {}) => + text.split('').map((char) => ({ char, runAttrs: JSON.stringify(attrs), kind: 'text' })); -const createParagraph = (text, attrs = {}, options = {}) => { - const { pos = 0, textAttrs = {} } = options; - const textRuns = buildTextRuns(text, textAttrs); +const createParagraphNode = (overrides = {}) => ({ + type: { name: 'paragraph', ...(overrides.type || {}) }, + attrs: {}, + nodeSize: 5, + ...overrides, +}); + +const createParagraphInfo = (overrides = {}) => { + const fullText = overrides.fullText ?? 'text'; + const textTokens = overrides.text ?? buildRuns(fullText); return { - node: { attrs }, - pos, - text: textRuns, - resolvePosition: (index) => pos + 1 + index, - get fullText() { - return textRuns.map((c) => c.char).join(''); + node: createParagraphNode(overrides.node), + pos: 0, + fullText, + text: textTokens, + resolvePosition: (idx) => idx, + ...overrides, + }; +}; + +const createParagraphWithSegments = (segments, contentSize) => { + const computedSegments = segments.map((segment) => { + if (segment.inlineNode) { + return { + ...segment, + kind: 'inline', + length: segment.length ?? 1, + start: segment.start ?? 0, + attrs: segment.attrs ?? segment.inlineNode.attrs ?? {}, + inlineNode: { + typeName: segment.inlineNode.typeName ?? 'inline', + attrs: segment.inlineNode.attrs ?? {}, + isLeaf: segment.inlineNode.isLeaf ?? true, + }, + }; + } + + const segmentText = segment.text ?? segment.leafText(); + const length = segmentText.length; + return { + ...segment, + kind: segment.text != null ? 'text' : 'leaf', + length, + start: segment.start ?? 0, + attrs: segment.attrs ?? {}, + }; + }); + const size = + contentSize ?? computedSegments.reduce((max, segment) => Math.max(max, segment.start + segment.length), 0); + const attrsMap = new Map(); + computedSegments.forEach((segment) => { + const key = segment.kind === 'inline' ? segment.start : segment.start - 1; + attrsMap.set(key, segment.attrs); + }); + + return { + content: { size }, + nodesBetween: (from, to, callback) => { + computedSegments.forEach((segment) => { + if (segment.kind === 'text') { + callback({ isText: true, text: segment.text }, segment.start); + } else if (segment.kind === 'leaf') { + callback({ isLeaf: true, type: { spec: { leafText: segment.leafText } } }, segment.start); + } else { + callback( + { + isInline: true, + isLeaf: segment.inlineNode.isLeaf, + type: { name: segment.inlineNode.typeName, spec: {} }, + attrs: segment.inlineNode.attrs, + }, + segment.start, + ); + } + }); }, + nodeAt: (pos) => ({ attrs: attrsMap.get(pos) ?? {} }), }; }; -describe('diffParagraphs', () => { - it('treats similar paragraphs without IDs as modifications', () => { - const oldParagraphs = [createParagraph('Hello world from ProseMirror.')]; - const newParagraphs = [createParagraph('Hello brave new world from ProseMirror.')]; +describe('getParagraphContent', () => { + it('handles basic text nodes', () => { + const mockParagraph = createParagraphWithSegments([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); + + const result = getParagraphContent(mockParagraph); + expect(result.text).toEqual(buildRuns('Hello', { bold: true })); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(4)).toBe(5); + }); - const diffs = diffParagraphs(oldParagraphs, newParagraphs); + it('handles leaf nodes with leafText', () => { + const mockParagraph = createParagraphWithSegments( + [{ leafText: () => 'Leaf', start: 0, attrs: { type: 'leaf' } }], + 4, + ); - expect(diffs).toHaveLength(1); - expect(diffs[0].action).toBe('modified'); - expect(diffs[0].contentDiff.length).toBeGreaterThan(0); + const result = getParagraphContent(mockParagraph); + expect(result.text).toEqual(buildRuns('Leaf', { type: 'leaf' })); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(3)).toBe(4); }); - it('keeps unrelated paragraphs as deletion + addition', () => { - const oldParagraphs = [createParagraph('Alpha paragraph with some text.')]; - const newParagraphs = [createParagraph('Zephyr quickly jinxed the new passage.')]; + it('handles mixed content', () => { + const mockParagraph = createParagraphWithSegments([ + { text: 'Hello', start: 0, attrs: { bold: true } }, + { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, + ]); - const diffs = diffParagraphs(oldParagraphs, newParagraphs); + const result = getParagraphContent(mockParagraph); + expect(result.text).toEqual([...buildRuns('Hello', { bold: true }), ...buildRuns('Leaf', { italic: true })]); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(5)).toBe(6); + expect(result.resolvePosition(9)).toBe(10); + }); + + it('handles empty content', () => { + const mockParagraph = createParagraphWithSegments([], 0); - expect(diffs).toHaveLength(2); - expect(diffs[0].action).toBe('deleted'); - expect(diffs[1].action).toBe('added'); + const result = getParagraphContent(mockParagraph); + expect(result.text).toEqual([]); + expect(result.resolvePosition(0)).toBe(1); }); - it('detects modifications even when Myers emits grouped deletes and inserts', () => { - const oldParagraphs = [ - createParagraph('Original introduction paragraph that needs tweaks.'), - createParagraph('Paragraph that will be removed.'), - ]; - const newParagraphs = [ - createParagraph('Original introduction paragraph that now has tweaks.'), - createParagraph('Completely different replacement paragraph.'), - ]; + it('includes inline nodes that have no textual content', () => { + const inlineAttrs = { kind: 'tab', width: 120 }; + const mockParagraph = createParagraphWithSegments([ + { inlineNode: { typeName: 'tab', attrs: inlineAttrs }, start: 0 }, + { text: 'Text', start: 1, attrs: { bold: false } }, + ]); + + const result = getParagraphContent(mockParagraph); + expect(result.text[0]).toEqual({ + kind: 'inlineNode', + node: { + attrs: { + kind: 'tab', + width: 120, + }, + isInline: true, + isLeaf: true, + type: { + name: 'tab', + spec: {}, + }, + }, + }); + expect(result.text.slice(1)).toEqual(buildRuns('Text', { bold: false })); + expect(result.resolvePosition(0)).toBe(1); + expect(result.resolvePosition(1)).toBe(2); + }); + + it('applies paragraph position offsets to the resolver', () => { + const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); + + const result = getParagraphContent(mockParagraph, 10); + expect(result.text).toEqual(buildRuns('Nested', {})); + expect(result.resolvePosition(0)).toBe(11); + expect(result.resolvePosition(6)).toBe(17); + }); + + it('returns null when index is outside the flattened text array', () => { + const mockParagraph = createParagraphWithSegments([{ text: 'Hi', start: 0 }], 2); + const { resolvePosition } = getParagraphContent(mockParagraph); + + expect(resolvePosition(-1)).toBeNull(); + expect(resolvePosition(3)).toBeNull(); + expect(resolvePosition(2)).toBe(3); + }); +}); + +describe('shouldProcessEqualAsModification', () => { + it('returns true when node JSON differs', () => { + const baseNode = { toJSON: () => ({ attrs: { bold: true } }) }; + const modifiedNode = { toJSON: () => ({ attrs: { bold: false } }) }; + + expect(shouldProcessEqualAsModification({ node: baseNode }, { node: modifiedNode })).toBe(true); + }); + + it('returns false when serialized nodes are identical', () => { + const node = { toJSON: () => ({ attrs: { bold: true } }) }; + expect(shouldProcessEqualAsModification({ node }, { node })).toBe(false); + }); +}); - const diffs = diffParagraphs(oldParagraphs, newParagraphs); +describe('paragraphComparator', () => { + it('treats paragraphs with the same paraId as equal', () => { + const makeInfo = (id) => ({ node: { attrs: { paraId: id } } }); + expect(paragraphComparator(makeInfo('123'), makeInfo('123'))).toBe(true); + }); + + it('falls back to comparing fullText when ids differ', () => { + const makeInfo = (text) => ({ node: { attrs: {} }, fullText: text }); + expect(paragraphComparator(makeInfo('same text'), makeInfo('same text'))).toBe(true); + }); + + it('returns false for paragraphs with different identity signals', () => { + expect(paragraphComparator({ fullText: 'one' }, { fullText: 'two' })).toBe(false); + }); +}); + +describe('paragraph diff builders', () => { + it('builds added paragraph payloads with consistent metadata', () => { + const paragraph = createParagraphInfo({ + node: createParagraphNode({ type: { name: 'paragraph' } }), + fullText: 'Hello', + }); + const previousNode = { pos: 10, node: { nodeSize: 4 } }; + + expect(buildAddedParagraphDiff(paragraph, previousNode)).toEqual({ + action: 'added', + nodeType: 'paragraph', + node: paragraph.node, + text: 'Hello', + pos: 14, + }); + }); + + it('builds deletion payloads reflecting the original paragraph context', () => { + const paragraph = createParagraphInfo({ pos: 7, fullText: 'Old text' }); + + expect(buildDeletedParagraphDiff(paragraph)).toEqual({ + action: 'deleted', + nodeType: 'paragraph', + node: paragraph.node, + oldText: 'Old text', + pos: 7, + }); + }); + + it('returns a diff with inline changes when content differs', () => { + const oldParagraph = createParagraphInfo({ + pos: 5, + fullText: 'foo', + text: buildRuns('foo'), + node: createParagraphNode({ attrs: { align: 'left' } }), + }); + const newParagraph = createParagraphInfo({ + pos: 5, + fullText: 'bar', + text: buildRuns('bar'), + node: createParagraphNode({ attrs: { align: 'left' } }), + }); + + const diff = buildModifiedParagraphDiff(oldParagraph, newParagraph); + expect(diff).not.toBeNull(); + expect(diff).toMatchObject({ + action: 'modified', + nodeType: 'paragraph', + oldText: 'foo', + newText: 'bar', + pos: 5, + attrsDiff: null, + }); + expect(diff.contentDiff.length).toBeGreaterThan(0); + }); + + it('returns null when neither text nor attributes changed', () => { + const baseParagraph = createParagraphInfo({ + fullText: 'stable', + node: createParagraphNode({ attrs: { align: 'left' } }), + }); + + expect(buildModifiedParagraphDiff(baseParagraph, baseParagraph)).toBeNull(); + }); + + it('returns a diff when only the attributes change', () => { + const oldParagraph = createParagraphInfo({ + node: createParagraphNode({ attrs: { align: 'left' } }), + }); + const newParagraph = createParagraphInfo({ + node: createParagraphNode({ attrs: { align: 'right' } }), + }); + + const diff = buildModifiedParagraphDiff(oldParagraph, newParagraph); + expect(diff).not.toBeNull(); + expect(diff.contentDiff).toEqual([]); + expect(diff.attrsDiff?.modified).toHaveProperty('align'); + }); +}); + +describe('canTreatAsModification', () => { + it('returns true when paragraph comparator matches by paraId', () => { + const buildInfo = (paraId) => ({ + node: { attrs: { paraId } }, + fullText: 'abc', + }); + expect(canTreatAsModification(buildInfo('id'), buildInfo('id'))).toBe(true); + }); + + it('returns false for short paragraphs lacking identity signals', () => { + const a = { node: { attrs: {} }, fullText: 'abc' }; + const b = { node: { attrs: {} }, fullText: 'xyz' }; + expect(canTreatAsModification(a, b)).toBe(false); + }); + + it('returns true when textual similarity exceeds the threshold', () => { + const a = { node: { attrs: {} }, fullText: 'lorem' }; + const b = { node: { attrs: {} }, fullText: 'loren' }; + expect(canTreatAsModification(a, b)).toBe(true); + }); - expect(diffs).toHaveLength(3); - expect(diffs[0].action).toBe('modified'); - expect(diffs[0].contentDiff.length).toBeGreaterThan(0); - expect(diffs[1].action).toBe('deleted'); - expect(diffs[2].action).toBe('added'); + it('returns false when paragraphs are dissimilar', () => { + const a = { node: { attrs: {} }, fullText: 'lorem ipsum' }; + const b = { node: { attrs: {} }, fullText: 'dolor sit' }; + expect(canTreatAsModification(a, b)).toBe(false); }); }); diff --git a/packages/super-editor/src/extensions/diffing/utils.js b/packages/super-editor/src/extensions/diffing/utils.js deleted file mode 100644 index f476b13b6f..0000000000 --- a/packages/super-editor/src/extensions/diffing/utils.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. - * @param {Node} paragraph - Paragraph node to flatten. - * @param {number} [paragraphPos=0] - Position of the paragraph in the document. - * @returns {{text: {char: string, runAttrs: Record}[], resolvePosition: (index: number) => number|null}} Concatenated text and position resolver. - */ -export function getParagraphContent(paragraph, paragraphPos = 0) { - let content = []; - const segments = []; - - paragraph.nodesBetween( - 0, - paragraph.content.size, - (node, pos) => { - let nodeText = ''; - - if (node.isText) { - nodeText = node.text; - } else if (node.isLeaf && node.type.spec.leafText) { - nodeText = node.type.spec.leafText(node); - } else if (node.type.name !== 'run' && node.isInline) { - const start = content.length; - const end = start + 1; - content.push({ - kind: 'inlineNode', - node: node, - }); - segments.push({ start, end, pos }); - return; - } else { - return; - } - - const start = content.length; - const end = start + nodeText.length; - - const runNode = paragraph.nodeAt(pos - 1); - const runAttrs = runNode.attrs || {}; - - segments.push({ start, end, pos }); - const chars = nodeText.split('').map((char) => ({ - kind: 'text', - char, - runAttrs: JSON.stringify(runAttrs), - })); - - content = content.concat(chars); - }, - 0, - ); - - const resolvePosition = (index) => { - if (index < 0 || index > content.length) { - return null; - } - - for (const segment of segments) { - if (index >= segment.start && index < segment.end) { - return paragraphPos + 1 + segment.pos + (index - segment.start); - } - } - - // If index points to the end of the string, return the paragraph end - return paragraphPos + 1 + paragraph.content.size; - }; - - return { text: content, resolvePosition }; -} - -/** - * Collects paragraphs from a ProseMirror document and returns them by paragraph ID. - * @param {Node} pmDoc - ProseMirror document to scan. - * @returns {Array<{node: Node, pos: number, text: string, resolvePosition: Function}>} Ordered list of paragraph descriptors. - */ -export function extractParagraphs(pmDoc) { - const paragraphs = []; - pmDoc.descendants((node, pos) => { - if (node.type.name === 'paragraph') { - const { text, resolvePosition } = getParagraphContent(node, pos); - paragraphs.push({ - node, - pos, - text, - resolvePosition, - get fullText() { - return text.map((c) => c.char).join(''); - }, - }); - return false; // Do not descend further - } - }); - return paragraphs; -} diff --git a/packages/super-editor/src/extensions/diffing/utils.test.js b/packages/super-editor/src/extensions/diffing/utils.test.js deleted file mode 100644 index 06a6a54489..0000000000 --- a/packages/super-editor/src/extensions/diffing/utils.test.js +++ /dev/null @@ -1,203 +0,0 @@ -import { extractParagraphs, getParagraphContent } from './utils'; - -const buildRuns = (text, attrs = {}) => - text.split('').map((char) => ({ char, runAttrs: JSON.stringify(attrs), kind: 'text' })); - -const createParagraphNode = (text, attrs = {}) => ({ - type: { name: 'paragraph' }, - attrs, - textContent: text, - content: { size: text.length }, - nodesBetween: (from, to, callback) => { - callback({ isText: true, text }, 0); - }, - nodeAt: () => ({ attrs }), -}); - -const createParagraphWithSegments = (segments, contentSize) => { - const computedSegments = segments.map((segment) => { - if (segment.inlineNode) { - return { - ...segment, - kind: 'inline', - length: segment.length ?? 1, - start: segment.start ?? 0, - attrs: segment.attrs ?? segment.inlineNode.attrs ?? {}, - inlineNode: { - typeName: segment.inlineNode.typeName ?? 'inline', - attrs: segment.inlineNode.attrs ?? {}, - isLeaf: segment.inlineNode.isLeaf ?? true, - }, - }; - } - - const segmentText = segment.text ?? segment.leafText(); - const length = segmentText.length; - return { - ...segment, - kind: segment.text != null ? 'text' : 'leaf', - length, - start: segment.start ?? 0, - attrs: segment.attrs ?? {}, - }; - }); - const size = - contentSize ?? computedSegments.reduce((max, segment) => Math.max(max, segment.start + segment.length), 0); - const attrsMap = new Map(); - computedSegments.forEach((segment) => { - const key = segment.kind === 'inline' ? segment.start : segment.start - 1; - attrsMap.set(key, segment.attrs); - }); - - return { - content: { size }, - nodesBetween: (from, to, callback) => { - computedSegments.forEach((segment) => { - if (segment.kind === 'text') { - callback({ isText: true, text: segment.text }, segment.start); - } else if (segment.kind === 'leaf') { - callback({ isLeaf: true, type: { spec: { leafText: segment.leafText } } }, segment.start); - } else { - callback( - { - isInline: true, - isLeaf: segment.inlineNode.isLeaf, - type: { name: segment.inlineNode.typeName, spec: {} }, - attrs: segment.inlineNode.attrs, - }, - segment.start, - ); - } - }); - }, - nodeAt: (pos) => ({ attrs: attrsMap.get(pos) ?? {} }), - }; -}; - -describe('extractParagraphs', () => { - it('collects paragraph nodes in document order', () => { - const firstParagraph = createParagraphNode('First paragraph', { paraId: 'para-1' }); - const nonParagraph = { - type: { name: 'heading' }, - attrs: { paraId: 'heading-1' }, - }; - const secondParagraph = createParagraphNode('Second paragraph', { paraId: 'para-2' }); - const pmDoc = { - descendants: (callback) => { - callback(firstParagraph, 0); - callback(nonParagraph, 5); - callback(secondParagraph, 10); - }, - }; - - const paragraphs = extractParagraphs(pmDoc); - - expect(paragraphs).toHaveLength(2); - expect(paragraphs[0]).toMatchObject({ node: firstParagraph, pos: 0 }); - expect(paragraphs[0].text).toEqual(buildRuns('First paragraph', { paraId: 'para-1' })); - expect(paragraphs[0].fullText).toBe('First paragraph'); - expect(paragraphs[1]).toMatchObject({ node: secondParagraph, pos: 10 }); - expect(paragraphs[1].text).toEqual(buildRuns('Second paragraph', { paraId: 'para-2' })); - }); - - it('includes position resolvers for paragraphs with missing IDs', () => { - const firstParagraph = createParagraphNode('Anonymous first'); - const secondParagraph = createParagraphNode('Anonymous second'); - const pmDoc = { - descendants: (callback) => { - callback(firstParagraph, 2); - callback(secondParagraph, 8); - }, - }; - - const paragraphs = extractParagraphs(pmDoc); - - expect(paragraphs).toHaveLength(2); - expect(paragraphs[0].pos).toBe(2); - expect(paragraphs[1].pos).toBe(8); - expect(paragraphs[0].resolvePosition(0)).toBe(3); - expect(paragraphs[1].resolvePosition(4)).toBe(13); - }); -}); - -describe('getParagraphContent', () => { - it('handles basic text nodes', () => { - const mockParagraph = createParagraphWithSegments([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); - - const result = getParagraphContent(mockParagraph); - expect(result.text).toEqual(buildRuns('Hello', { bold: true })); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(4)).toBe(5); - }); - - it('handles leaf nodes with leafText', () => { - const mockParagraph = createParagraphWithSegments( - [{ leafText: () => 'Leaf', start: 0, attrs: { type: 'leaf' } }], - 4, - ); - - const result = getParagraphContent(mockParagraph); - expect(result.text).toEqual(buildRuns('Leaf', { type: 'leaf' })); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(3)).toBe(4); - }); - - it('handles mixed content', () => { - const mockParagraph = createParagraphWithSegments([ - { text: 'Hello', start: 0, attrs: { bold: true } }, - { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, - ]); - - const result = getParagraphContent(mockParagraph); - expect(result.text).toEqual([...buildRuns('Hello', { bold: true }), ...buildRuns('Leaf', { italic: true })]); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(5)).toBe(6); - expect(result.resolvePosition(9)).toBe(10); - }); - - it('handles empty content', () => { - const mockParagraph = createParagraphWithSegments([], 0); - - const result = getParagraphContent(mockParagraph); - expect(result.text).toEqual([]); - expect(result.resolvePosition(0)).toBe(1); - }); - - it('includes inline nodes that have no textual content', () => { - const inlineAttrs = { kind: 'tab', width: 120 }; - const mockParagraph = createParagraphWithSegments([ - { inlineNode: { typeName: 'tab', attrs: inlineAttrs }, start: 0 }, - { text: 'Text', start: 1, attrs: { bold: false } }, - ]); - - const result = getParagraphContent(mockParagraph); - debugger; - expect(result.text[0]).toEqual({ - kind: 'inlineNode', - node: { - attrs: { - kind: 'tab', - width: 120, - }, - isInline: true, - isLeaf: true, - type: { - name: 'tab', - spec: {}, - }, - }, - }); - expect(result.text.slice(1)).toEqual(buildRuns('Text', { bold: false })); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(1)).toBe(2); - }); - - it('applies paragraph position offsets to the resolver', () => { - const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); - - const result = getParagraphContent(mockParagraph, 10); - expect(result.text).toEqual(buildRuns('Nested', {})); - expect(result.resolvePosition(0)).toBe(11); - expect(result.resolvePosition(6)).toBe(17); - }); -}); From f9e1e54c60db56543a03188b6b222de58d1289ff Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 14:10:01 -0300 Subject: [PATCH 024/125] feat: use generic diffing for diff computation command --- .../src/extensions/diffing/computeDiff.js | 8 +-- .../extensions/diffing/computeDiff.test.js | 64 ++++++++++++++++++ .../src/tests/data/diff_after7.docx | Bin 0 -> 14189 bytes .../src/tests/data/diff_before7.docx | Bin 0 -> 13831 bytes 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 packages/super-editor/src/tests/data/diff_after7.docx create mode 100644 packages/super-editor/src/tests/data/diff_before7.docx diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js index 04c2fbc62f..4025597fe1 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.js @@ -1,5 +1,4 @@ -import { extractParagraphs } from './utils.js'; -import { diffParagraphs } from './algorithm/paragraph-diffing.js'; +import { diffNodes } from './algorithm/generic-diffing.js'; /** * Computes paragraph-level diffs between two ProseMirror documents, returning inserts, deletes and text modifications. @@ -8,8 +7,5 @@ import { diffParagraphs } from './algorithm/paragraph-diffing.js'; * @returns {Array} List of diff objects describing added, deleted or modified paragraphs. */ export function computeDiff(oldPmDoc, newPmDoc) { - const oldParagraphs = extractParagraphs(oldPmDoc); - const newParagraphs = extractParagraphs(newPmDoc); - - return diffParagraphs(oldParagraphs, newParagraphs); + return diffNodes(oldPmDoc, newPmDoc); } diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index 6ee9bef813..df75d6b894 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -191,4 +191,68 @@ describe('Diff', () => { expect(diff.contentDiff[2].action).toBe('added'); expect(diff.contentDiff[2].kind).toBe('text'); }); + + it('Compare a complex document with table edits and tracked formatting', async () => { + const docBefore = await getDocument('diff_before7.docx'); + const docAfter = await getDocument('diff_after7.docx'); + + const diffs = computeDiff(docBefore, docAfter); + expect(diffs).toHaveLength(9); + expect(diffs.filter((diff) => diff.action === 'modified')).toHaveLength(6); + expect(diffs.filter((diff) => diff.action === 'added')).toHaveLength(2); + expect(diffs.filter((diff) => diff.action === 'deleted')).toHaveLength(1); + + const formattingDiff = diffs.find( + (diff) => diff.action === 'modified' && diff.oldText === 'This paragraph formatting will change.', + ); + expect(formattingDiff?.contentDiff?.[0]?.runAttrsDiff?.added).toHaveProperty('runProperties.bold', true); + + const upgradedParagraph = diffs.find( + (diff) => diff.action === 'modified' && diff.oldText === 'This paragraph will have words.', + ); + expect(upgradedParagraph?.newText).toBe('This paragraph will have NEW words.'); + expect( + upgradedParagraph?.contentDiff?.some( + (change) => change.action === 'added' && typeof change.text === 'string' && change.text.includes('NEW'), + ), + ).toBe(true); + + const deletion = diffs.find( + (diff) => diff.action === 'deleted' && diff.oldText === 'This paragraph will be deleted.', + ); + expect(deletion).toBeDefined(); + + const wordRemoval = diffs.find( + (diff) => diff.action === 'modified' && diff.oldText === 'This word will be deleted.', + ); + expect(wordRemoval?.newText).toBe('This will be deleted.'); + expect(wordRemoval?.contentDiff).toHaveLength(1); + expect(wordRemoval?.contentDiff?.[0].action).toBe('deleted'); + + const tableModification = diffs.find( + (diff) => diff.action === 'modified' && diff.nodeType === 'table' && diff.oldNode, + ); + expect(tableModification).toBeUndefined(); + + const tableAddition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'table'); + expect(tableAddition?.node?.textContent?.trim()).toBe('New table'); + + const trailingParagraph = diffs.find( + (diff) => diff.action === 'added' && diff.nodeType === 'paragraph' && diff.text === '', + ); + expect(trailingParagraph).toBeDefined(); + + const thirdHeaderDiff = diffs.find( + (diff) => + diff.action === 'modified' && diff.oldText === 'Third header' && diff.newText === 'Third header modified', + ); + expect( + thirdHeaderDiff?.contentDiff?.some((change) => change.action === 'added' && change.text === ' modified'), + ).toBe(true); + + const firstCellDiff = diffs.find( + (diff) => diff.action === 'modified' && diff.oldText === 'First cell' && diff.newText === 'cell', + ); + expect(firstCellDiff?.contentDiff?.[0]?.text).toBe('First '); + }); }); diff --git a/packages/super-editor/src/tests/data/diff_after7.docx b/packages/super-editor/src/tests/data/diff_after7.docx new file mode 100644 index 0000000000000000000000000000000000000000..db208187b525fedbcdfdc556a199c2bba3ce4f1f GIT binary patch literal 14189 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diff_before7.docx b/packages/super-editor/src/tests/data/diff_before7.docx new file mode 100644 index 0000000000000000000000000000000000000000..1d9cfa5789b8484f8b97fd0e21f7aadc6c8aa3be GIT binary patch literal 13831 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 YIZ23j_xSBz5;#ETdx~Xb`R&#J0a7W Date: Mon, 29 Dec 2025 14:29:01 -0300 Subject: [PATCH 025/125] refactor: simplify grouping logic during inline diffing --- .../diffing/algorithm/inline-diffing.js | 172 ++++++++++-------- 1 file changed, 96 insertions(+), 76 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js index 2785d8ea49..24412bf8ce 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js @@ -74,7 +74,7 @@ export function getInlineDiff(oldContent, newContent, oldPositionResolver, newPo }, }); - const groupedDiffs = groupDiffs(diffs, oldPositionResolver, newPositionResolver); + const groupedDiffs = groupDiffs(diffs, oldPositionResolver); return groupedDiffs; } @@ -115,37 +115,38 @@ function shouldProcessEqualAsModification(oldToken, newToken) { * Groups raw diff operations into contiguous ranges and converts serialized run attrs back to objects. * @param {Array<{action:'added'|'deleted'|'modified', idx:number, kind:'text'|'inlineNode', text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string, nodeType?: string, node?: import('prosemirror-model').Node, oldNode?: import('prosemirror-model').Node, newNode?: import('prosemirror-model').Node}>} diffs * @param {(index: number) => number|null} oldPositionResolver - * @param {(index: number) => number|null} newPositionResolver * @returns {InlineDiffResult[]} */ -function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { +function groupDiffs(diffs, oldPositionResolver) { const grouped = []; let currentGroup = null; - const compareDiffs = (group, diff) => { - if (group.action !== diff.action) { - return false; - } - if (group.action === 'modified') { - return group.oldAttrs === diff.oldAttrs && group.newAttrs === diff.newAttrs; + /** + * Finalizes the current text group (if any) and appends it to the grouped result list. + * Resets the working group so the caller can start accumulating the next run. + */ + const pushCurrentGroup = () => { + if (!currentGroup) { + return; } - return group.runAttrs === diff.runAttrs; - }; - - const comparePositions = (group, diff) => { - if (group.action === 'added') { - return group.startPos === oldPositionResolver(diff.idx); + const result = { ...currentGroup }; + if (currentGroup.action === 'modified') { + const oldAttrs = JSON.parse(currentGroup.oldAttrs); + const newAttrs = JSON.parse(currentGroup.newAttrs); + result.runAttrsDiff = getAttributesDiff(oldAttrs, newAttrs); + delete result.oldAttrs; + delete result.newAttrs; } else { - return group.endPos + 1 === oldPositionResolver(diff.idx); + result.runAttrs = JSON.parse(currentGroup.runAttrs); } + grouped.push(result); + currentGroup = null; }; + // Iterate over raw diffs and group text changes where possible for (const diff of diffs) { if (diff.kind !== 'text') { - if (currentGroup != null) { - grouped.push(currentGroup); - currentGroup = null; - } + pushCurrentGroup(); grouped.push({ action: diff.action, kind: 'inlineNode', @@ -162,65 +163,84 @@ function groupDiffs(diffs, oldPositionResolver, newPositionResolver) { }); continue; } - if (currentGroup == null) { - currentGroup = { - action: diff.action, - startPos: oldPositionResolver(diff.idx), - endPos: oldPositionResolver(diff.idx), - kind: 'text', - }; - if (diff.action === 'modified') { - currentGroup.newText = diff.newText; - currentGroup.oldText = diff.oldText; - currentGroup.oldAttrs = diff.oldAttrs; - currentGroup.newAttrs = diff.newAttrs; - } else { - currentGroup.text = diff.text; - currentGroup.runAttrs = diff.runAttrs; - } - } else if (!compareDiffs(currentGroup, diff) || !comparePositions(currentGroup, diff)) { - grouped.push(currentGroup); - currentGroup = { - action: diff.action, - startPos: oldPositionResolver(diff.idx), - endPos: oldPositionResolver(diff.idx), - kind: 'text', - }; - if (diff.action === 'modified') { - currentGroup.newText = diff.newText; - currentGroup.oldText = diff.oldText; - currentGroup.oldAttrs = diff.oldAttrs; - currentGroup.newAttrs = diff.newAttrs; - } else { - currentGroup.text = diff.text; - currentGroup.runAttrs = diff.runAttrs; - } + + if (!currentGroup || !canExtendGroup(currentGroup, diff, oldPositionResolver)) { + pushCurrentGroup(); + currentGroup = createTextGroup(diff, oldPositionResolver); } else { - currentGroup.endPos = oldPositionResolver(diff.idx); - if (diff.action === 'modified') { - currentGroup.newText += diff.newText; - currentGroup.oldText += diff.oldText; - } else { - currentGroup.text += diff.text; - } + extendTextGroup(currentGroup, diff, oldPositionResolver); } } - if (currentGroup != null) grouped.push(currentGroup); - return grouped.map((group) => { - let ret = { ...group }; - if (group.kind === 'inlineNode') { - return ret; - } - if (group.action === 'modified') { - ret.oldAttrs = JSON.parse(group.oldAttrs); - ret.newAttrs = JSON.parse(group.newAttrs); - ret.runAttrsDiff = getAttributesDiff(ret.oldAttrs, ret.newAttrs); - delete ret.oldAttrs; - delete ret.newAttrs; - } else { - ret.runAttrs = JSON.parse(group.runAttrs); + pushCurrentGroup(); + return grouped; +} + +/** + * Builds a fresh text diff group seeded with the current diff token. + * @param {{action:'added'|'deleted'|'modified', idx:number, kind:'text', text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string}} diff + * @param {(index:number)=>number|null} positionResolver + * @returns {{action:'added'|'deleted'|'modified', kind:'text', startPos:number, endPos:number, text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string}} + */ +function createTextGroup(diff, positionResolver) { + const baseGroup = { + action: diff.action, + kind: 'text', + startPos: positionResolver(diff.idx), + endPos: positionResolver(diff.idx), + }; + if (diff.action === 'modified') { + baseGroup.newText = diff.newText; + baseGroup.oldText = diff.oldText; + baseGroup.oldAttrs = diff.oldAttrs; + baseGroup.newAttrs = diff.newAttrs; + } else { + baseGroup.text = diff.text; + baseGroup.runAttrs = diff.runAttrs; + } + return baseGroup; +} + +/** + * Expands the current text group with the incoming diff token. + * Keeps start/end positions updated while concatenating text payloads. + * @param {{action:'added'|'deleted'|'modified', kind:'text', startPos:number, endPos:number, text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string}} group + * @param {{action:'added'|'deleted'|'modified', idx:number, kind:'text', text?: string, runAttrs?: string, newText?: string, oldText?: string}} diff + * @param {(index:number)=>number|null} positionResolver + */ +function extendTextGroup(group, diff, positionResolver) { + group.endPos = positionResolver(diff.idx); + if (group.action === 'modified') { + group.newText += diff.newText; + group.oldText += diff.oldText; + } else { + group.text += diff.text; + } +} + +/** + * Determines whether a text diff token can be merged into the current group. + * Checks action, attributes, and adjacency constraints required by the grouping heuristic. + * @param {{action:'added'|'deleted'|'modified', kind:'text', startPos:number, endPos:number, runAttrs?: string, oldAttrs?: string, newAttrs?: string}} group + * @param {{action:'added'|'deleted'|'modified', idx:number, kind:'text', runAttrs?: string, oldAttrs?: string, newAttrs?: string}} diff + * @param {(index:number)=>number|null} positionResolver + * @returns {boolean} + */ +function canExtendGroup(group, diff, positionResolver) { + if (group.action !== diff.action) { + return false; + } + + if (group.action === 'modified') { + if (group.oldAttrs !== diff.oldAttrs || group.newAttrs !== diff.newAttrs) { + return false; } - return ret; - }); + } else if (group.runAttrs !== diff.runAttrs) { + return false; + } + + if (group.action === 'added') { + return group.startPos === positionResolver(diff.idx); + } + return group.endPos + 1 === positionResolver(diff.idx); } From 98c495c6346b9ec71656cede689de3f88b52dafb Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 15:32:05 -0300 Subject: [PATCH 026/125] refactor: convert modules to typescript and improve documentation --- .../algorithm/attributes-diffing.test.js | 2 +- ...butes-diffing.js => attributes-diffing.ts} | 97 +++-- .../diffing/algorithm/generic-diffing.test.js | 2 +- ...{generic-diffing.js => generic-diffing.ts} | 152 ++++--- .../diffing/algorithm/inline-diffing.js | 246 ------------ .../diffing/algorithm/inline-diffing.test.js | 6 +- .../diffing/algorithm/inline-diffing.ts | 373 ++++++++++++++++++ .../{myers-diff.js => myers-diff.ts} | 47 ++- .../diffing/algorithm/paragraph-diffing.js | 261 ------------ .../algorithm/paragraph-diffing.test.js | 2 +- .../diffing/algorithm/paragraph-diffing.ts | 288 ++++++++++++++ .../algorithm/sequence-diffing.test.js | 2 +- ...equence-diffing.js => sequence-diffing.ts} | 78 ++-- .../{similarity.js => similarity.ts} | 13 +- .../src/extensions/diffing/computeDiff.js | 11 - .../src/extensions/diffing/computeDiff.ts | 20 + .../src/extensions/diffing/diffing.js | 2 +- 17 files changed, 927 insertions(+), 675 deletions(-) rename packages/super-editor/src/extensions/diffing/algorithm/{attributes-diffing.js => attributes-diffing.ts} (60%) rename packages/super-editor/src/extensions/diffing/algorithm/{generic-diffing.js => generic-diffing.ts} (50%) delete mode 100644 packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts rename packages/super-editor/src/extensions/diffing/algorithm/{myers-diff.js => myers-diff.ts} (58%) delete mode 100644 packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts rename packages/super-editor/src/extensions/diffing/algorithm/{sequence-diffing.js => sequence-diffing.ts} (60%) rename packages/super-editor/src/extensions/diffing/algorithm/{similarity.js => similarity.ts} (71%) delete mode 100644 packages/super-editor/src/extensions/diffing/computeDiff.js create mode 100644 packages/super-editor/src/extensions/diffing/computeDiff.ts diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js index 2b9c26998c..cf80ae640a 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { getAttributesDiff } from './attributes-diffing.js'; +import { getAttributesDiff } from './attributes-diffing.ts'; describe('getAttributesDiff', () => { it('detects nested additions, deletions, and modifications', () => { diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts similarity index 60% rename from packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js rename to packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index 2346d5c28e..59f08e4598 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -1,21 +1,35 @@ +const IGNORED_ATTRIBUTE_KEYS = new Set(['sdBlockId']); + /** - * @typedef {Object} AttributesDiff - * @property {Record} added - * @property {Record} deleted - * @property {Record} modified + * Represents a single attribute change capturing the previous and next values. */ +export interface AttributeChange { + from: unknown; + to: unknown; +} + +/** + * Aggregated attribute diff broken down into added, deleted, and modified dotted paths. + */ +export interface AttributesDiff { + added: Record; + deleted: Record; + modified: Record; +} /** * Computes the attribute level diff between two arbitrary objects. * Produces a map of dotted paths to added, deleted and modified values. - * @param {Record} objectA - * @param {Record} objectB - * @returns {AttributesDiff|null} + * + * @param objectA Baseline attributes to compare. + * @param objectB Updated attributes to compare. + * @returns Structured diff or null when objects are effectively equal. */ -const IGNORED_ATTRIBUTE_KEYS = new Set(['sdBlockId']); - -export function getAttributesDiff(objectA = {}, objectB = {}) { - const diff = { +export function getAttributesDiff( + objectA: Record | null | undefined = {}, + objectB: Record | null | undefined = {}, +): AttributesDiff | null { + const diff: AttributesDiff = { added: {}, deleted: {}, modified: {}, @@ -30,12 +44,18 @@ export function getAttributesDiff(objectA = {}, objectB = {}) { /** * Recursively compares two objects and fills the diff buckets. - * @param {Record} objectA - * @param {Record} objectB - * @param {string} basePath - * @param {AttributesDiff} diff + * + * @param objectA Baseline attributes being inspected. + * @param objectB Updated attributes being inspected. + * @param basePath Dotted path prefix used for nested keys. + * @param diff Aggregated diff being mutated. */ -function diffObjects(objectA, objectB, basePath, diff) { +function diffObjects( + objectA: Record, + objectB: Record, + basePath: string, + diff: AttributesDiff, +): void { const keys = new Set([...Object.keys(objectA || {}), ...Object.keys(objectB || {})]); for (const key of keys) { @@ -71,7 +91,7 @@ function diffObjects(objectA, objectB, basePath, diff) { } } - if (valueA !== valueB) { + if (!deepEquals(valueA, valueB)) { diff.modified[path] = { from: valueA, to: valueB, @@ -82,11 +102,12 @@ function diffObjects(objectA, objectB, basePath, diff) { /** * Records a nested value as an addition, flattening objects into dotted paths. - * @param {any} value - * @param {string} path - * @param {{added: Record}} diff + * + * @param value Value being marked as added. + * @param path Dotted attribute path for the value. + * @param diff Bucket used to capture additions. */ -function recordAddedValue(value, path, diff) { +function recordAddedValue(value: unknown, path: string, diff: Pick): void { if (isPlainObject(value)) { for (const [childKey, childValue] of Object.entries(value)) { if (IGNORED_ATTRIBUTE_KEYS.has(childKey)) { @@ -101,11 +122,12 @@ function recordAddedValue(value, path, diff) { /** * Records a nested value as a deletion, flattening objects into dotted paths. - * @param {any} value - * @param {string} path - * @param {{deleted: Record}} diff + * + * @param value Value being marked as removed. + * @param path Dotted attribute path for the value. + * @param diff Bucket used to capture deletions. */ -function recordDeletedValue(value, path, diff) { +function recordDeletedValue(value: unknown, path: string, diff: Pick): void { if (isPlainObject(value)) { for (const [childKey, childValue] of Object.entries(value)) { if (IGNORED_ATTRIBUTE_KEYS.has(childKey)) { @@ -120,30 +142,33 @@ function recordDeletedValue(value, path, diff) { /** * Builds dotted attribute paths. - * @param {string} base - * @param {string} key - * @returns {string} + * + * @param base Existing path prefix. + * @param key Current key being appended. + * @returns Combined dotted path. */ -function joinPath(base, key) { +function joinPath(base: string, key: string): string { return base ? `${base}.${key}` : key; } /** * Determines if a value is a plain object (no arrays or nulls). - * @param {any} value - * @returns {value is Record} + * + * @param value Value to inspect. + * @returns True when the value is a non-null object. */ -function isPlainObject(value) { +function isPlainObject(value: unknown): value is Record { return Boolean(value) && typeof value === 'object' && !Array.isArray(value); } /** * Checks deep equality for primitives, arrays, and plain objects. - * @param {any} a - * @param {any} b - * @returns {boolean} + * + * @param a First value. + * @param b Second value. + * @returns True when both values are deeply equal. */ -function deepEquals(a, b) { +function deepEquals(a: unknown, b: unknown): boolean { if (a === b) { return true; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js index 8c5ef5b2e9..1dbabf98de 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { diffNodes } from './generic-diffing.js'; +import { diffNodes } from './generic-diffing.ts'; const createDocFromNodes = (nodes = []) => ({ descendants(callback) { diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts similarity index 50% rename from packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.js rename to packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index b5d160bebc..5c0944bf59 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -1,3 +1,4 @@ +import type { Node as PMNode } from 'prosemirror-model'; import { getParagraphContent, paragraphComparator, @@ -6,49 +7,82 @@ import { buildAddedParagraphDiff, buildDeletedParagraphDiff, buildModifiedParagraphDiff, -} from './paragraph-diffing.js'; -import { diffSequences, reorderDiffOperations } from './sequence-diffing.js'; -import { getAttributesDiff } from './attributes-diffing.js'; + type ParagraphContentToken, + type ParagraphDiff, + type ParagraphResolvedSnapshot, +} from './paragraph-diffing.ts'; +import { diffSequences, reorderDiffOperations } from './sequence-diffing.ts'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; /** - * @typedef {import('prosemirror-model').Node} PMNode + * Minimal node metadata extracted during document traversal. */ +type BaseNodeInfo = { + node: PMNode; + pos: number; +}; /** - * @typedef {Object} BaseNodeInfo - * @property {PMNode} node - * @property {number} pos + * Paragraph-specific node info enriched with textual content and resolvers. */ +type ParagraphNodeInfo = ParagraphResolvedSnapshot; +/** + * Union describing every node processed by the generic diff. + */ +type NodeInfo = BaseNodeInfo | ParagraphNodeInfo; + +/** + * Diff payload describing an inserted non-paragraph node. + */ +interface NonParagraphAddedDiff { + action: 'added'; + nodeType: string; + node: PMNode; + pos: number; +} /** - * @typedef {BaseNodeInfo & { - * text: import('./paragraph-diffing.js').ParagraphContentToken[], - * resolvePosition: (idx: number) => number|null, - * fullText: string - * }} ParagraphNodeInfo + * Diff payload describing a deleted non-paragraph node. */ +interface NonParagraphDeletedDiff { + action: 'deleted'; + nodeType: string; + node: PMNode; + pos: number; +} /** - * @typedef {BaseNodeInfo | ParagraphNodeInfo} NodeInfo + * Diff payload describing an attribute-only change on non-paragraph nodes. */ +interface NonParagraphModifiedDiff { + action: 'modified'; + nodeType: string; + oldNode: PMNode; + newNode: PMNode; + pos: number; + attrsDiff: AttributesDiff; +} + +/** + * Union of every diff type emitted by the generic diffing layer. + */ +export type NodeDiff = ParagraphDiff | NonParagraphAddedDiff | NonParagraphDeletedDiff | NonParagraphModifiedDiff; /** * Produces a sequence diff between two ProseMirror documents, flattening paragraphs for inline-aware comparisons. - * @param {PMNode} oldRoot - * @param {PMNode} newRoot - * @returns {Array} */ -export function diffNodes(oldRoot, newRoot) { +export function diffNodes(oldRoot: PMNode, newRoot: PMNode): NodeDiff[] { const oldNodes = normalizeNodes(oldRoot); const newNodes = normalizeNodes(newRoot); - const addedNodesSet = new Set(); - return diffSequences(oldNodes, newNodes, { + const addedNodesSet = new Set(); + return diffSequences(oldNodes, newNodes, { comparator: nodeComparator, reorderOperations: reorderDiffOperations, shouldProcessEqualAsModification, canTreatAsModification, - buildAdded: (nodeInfo, oldIdx, previousOldNodeInfo) => buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet), + buildAdded: (nodeInfo, _oldIdx, previousOldNodeInfo) => + buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet), buildDeleted: buildDeletedDiff, buildModified: buildModifiedDiff, }); @@ -56,58 +90,52 @@ export function diffNodes(oldRoot, newRoot) { /** * Traverses a ProseMirror document and converts paragraphs to richer node info objects. - * @param {PMNode} pmDoc - * @returns {NodeInfo[]} */ -function normalizeNodes(pmDoc) { - const nodes = []; +function normalizeNodes(pmDoc: PMNode): NodeInfo[] { + const nodes: NodeInfo[] = []; pmDoc.descendants((node, pos) => { if (node.type.name === 'paragraph') { const { text, resolvePosition } = getParagraphContent(node, pos); + const fullText = getFullText(text); nodes.push({ node, pos, text, resolvePosition, - get fullText() { - return text.map((c) => c.char).join(''); - }, + fullText, }); - return false; // Do not descend further - } else { - nodes.push({ node, pos }); + return false; } + nodes.push({ node, pos }); + return undefined; }); return nodes; } +function getFullText(tokens: ParagraphContentToken[]): string { + return tokens.map((token) => (token.kind === 'text' ? token.char : '')).join(''); +} + /** * Compares two node infos to determine if they correspond to the same logical node. * Paragraphs are compared with `paragraphComparator`, while other nodes are matched by type name. - * @param {NodeInfo} oldNodeInfo - * @param {NodeInfo} newNodeInfo - * @returns {boolean} */ -function nodeComparator(oldNodeInfo, newNodeInfo) { +function nodeComparator(oldNodeInfo: NodeInfo, newNodeInfo: NodeInfo): boolean { if (oldNodeInfo.node.type.name !== newNodeInfo.node.type.name) { return false; } - if (oldNodeInfo.node.type.name === 'paragraph') { + if (isParagraphNodeInfo(oldNodeInfo) && isParagraphNodeInfo(newNodeInfo)) { return paragraphComparator(oldNodeInfo, newNodeInfo); - } else { - return oldNodeInfo.node.type.name === newNodeInfo.node.type.name; } + return true; } /** * Decides whether nodes deemed equal by the diff should still be emitted as modifications. * Paragraph nodes leverage their specialized handler, while other nodes compare attribute JSON. - * @param {NodeInfo} oldNodeInfo - * @param {NodeInfo} newNodeInfo - * @returns {boolean} */ -function shouldProcessEqualAsModification(oldNodeInfo, newNodeInfo) { - if (oldNodeInfo.node.type.name === 'paragraph' && newNodeInfo.node.type.name === 'paragraph') { +function shouldProcessEqualAsModification(oldNodeInfo: NodeInfo, newNodeInfo: NodeInfo): boolean { + if (isParagraphNodeInfo(oldNodeInfo) && isParagraphNodeInfo(newNodeInfo)) { return shouldProcessEqualParagraphsAsModification(oldNodeInfo, newNodeInfo); } return JSON.stringify(oldNodeInfo.node.attrs) !== JSON.stringify(newNodeInfo.node.attrs); @@ -116,12 +144,9 @@ function shouldProcessEqualAsModification(oldNodeInfo, newNodeInfo) { /** * Determines whether a delete/insert pair should instead be surfaced as a modification. * Only paragraphs qualify because we can measure textual similarity; other nodes remain as-is. - * @param {NodeInfo} deletedNodeInfo - * @param {NodeInfo} insertedNodeInfo - * @returns {boolean} */ -function canTreatAsModification(deletedNodeInfo, insertedNodeInfo) { - if (deletedNodeInfo.node.type.name === 'paragraph' && insertedNodeInfo.node.type.name === 'paragraph') { +function canTreatAsModification(deletedNodeInfo: NodeInfo, insertedNodeInfo: NodeInfo): boolean { + if (isParagraphNodeInfo(deletedNodeInfo) && isParagraphNodeInfo(insertedNodeInfo)) { return canTreatParagraphDeletionInsertionAsModification(deletedNodeInfo, insertedNodeInfo); } return false; @@ -129,24 +154,26 @@ function canTreatAsModification(deletedNodeInfo, insertedNodeInfo) { /** * Builds the diff payload for an inserted node and tracks descendants to avoid duplicates. - * @param {NodeInfo} nodeInfo - * @param {NodeInfo} previousOldNodeInfo - * @param {Set} addedNodesSet - * @returns {ReturnType|{action:'added', nodeType:string, node:PMNode, pos:number}|null} */ -function buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet) { +function buildAddedDiff( + nodeInfo: NodeInfo, + previousOldNodeInfo: NodeInfo | undefined, + addedNodesSet: Set, +): NodeDiff | null { if (addedNodesSet.has(nodeInfo.node)) { return null; } addedNodesSet.add(nodeInfo.node); - if (nodeInfo.node.type.name === 'paragraph') { + if (isParagraphNodeInfo(nodeInfo)) { return buildAddedParagraphDiff(nodeInfo, previousOldNodeInfo); } nodeInfo.node.descendants((childNode) => { addedNodesSet.add(childNode); }); - const pos = previousOldNodeInfo.pos + previousOldNodeInfo.node.nodeSize; + const previousPos = previousOldNodeInfo?.pos ?? -1; + const previousSize = previousOldNodeInfo?.node.nodeSize ?? 0; + const pos = previousPos >= 0 ? previousPos + previousSize : 0; return { action: 'added', nodeType: nodeInfo.node.type.name, @@ -157,11 +184,9 @@ function buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet) { /** * Builds the diff payload for a deleted node. - * @param {NodeInfo} nodeInfo - * @returns {ReturnType|{action:'deleted', nodeType:string, node:PMNode, pos:number}} */ -function buildDeletedDiff(nodeInfo) { - if (nodeInfo.node.type.name === 'paragraph') { +function buildDeletedDiff(nodeInfo: NodeInfo): NodeDiff { + if (isParagraphNodeInfo(nodeInfo)) { return buildDeletedParagraphDiff(nodeInfo); } return { @@ -175,12 +200,9 @@ function buildDeletedDiff(nodeInfo) { /** * Builds the diff payload for a modified node. * Paragraphs delegate to their inline-aware builder, while other nodes report attribute diffs. - * @param {NodeInfo} oldNodeInfo - * @param {NodeInfo} newNodeInfo - * @returns {ReturnType|{action:'modified', nodeType:string, oldNode:PMNode, newNode:PMNode, pos:number, attrsDiff: import('./attributes-diffing.js').AttributesDiff}|null} */ -function buildModifiedDiff(oldNodeInfo, newNodeInfo) { - if (oldNodeInfo.node.type.name === 'paragraph' && newNodeInfo.node.type.name === 'paragraph') { +function buildModifiedDiff(oldNodeInfo: NodeInfo, newNodeInfo: NodeInfo): NodeDiff | null { + if (isParagraphNodeInfo(oldNodeInfo) && isParagraphNodeInfo(newNodeInfo)) { return buildModifiedParagraphDiff(oldNodeInfo, newNodeInfo); } @@ -197,3 +219,7 @@ function buildModifiedDiff(oldNodeInfo, newNodeInfo) { attrsDiff, }; } + +function isParagraphNodeInfo(nodeInfo: NodeInfo): nodeInfo is ParagraphNodeInfo { + return nodeInfo.node.type.name === 'paragraph'; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js deleted file mode 100644 index 24412bf8ce..0000000000 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.js +++ /dev/null @@ -1,246 +0,0 @@ -import { getAttributesDiff } from './attributes-diffing.js'; -import { diffSequences } from './sequence-diffing.js'; - -/** - * @typedef {{kind: 'text', char: string, runAttrs: string}} InlineTextToken - */ - -/** - * @typedef {{kind: 'inlineNode', node: import('prosemirror-model').Node, nodeType?: string}} InlineNodeToken - */ - -/** - * @typedef {InlineTextToken|InlineNodeToken} InlineDiffToken - */ - -/** - * @typedef {{action: 'added'|'deleted'|'modified', kind: 'text'|'inlineNode', startPos: number|null, endPos: number|null, text?: string, oldText?: string, newText?: string, runAttrs?: Record, runAttrsDiff?: import('./attributes-diffing.js').AttributesDiff, node?: import('prosemirror-model').Node, nodeType?: string, oldNode?: import('prosemirror-model').Node, newNode?: import('prosemirror-model').Node}} InlineDiffResult - */ - -/** - * Computes text-level additions and deletions between two sequences using the generic sequence diff, mapping back to document positions. - * @param {InlineDiffToken[]} oldContent - Source tokens. - * @param {InlineDiffToken[]} newContent - Target tokens. - * @param {(index: number) => number|null} oldPositionResolver - Maps string indexes to the original document. - * @param {(index: number) => number|null} [newPositionResolver=oldPositionResolver] - Maps string indexes to the updated document. - * @returns {InlineDiffResult[]} List of grouped inline diffs with document positions and text content. - */ -export function getInlineDiff(oldContent, newContent, oldPositionResolver, newPositionResolver = oldPositionResolver) { - const buildInlineDiff = (action, token, oldIdx) => { - if (token.kind !== 'text') { - return { - action, - idx: oldIdx, - ...token, - }; - } else { - return { - action, - idx: oldIdx, - kind: 'text', - text: token.char, - runAttrs: token.runAttrs, - }; - } - }; - let diffs = diffSequences(oldContent, newContent, { - comparator: inlineComparator, - shouldProcessEqualAsModification, - canTreatAsModification: (oldToken, newToken) => - oldToken.kind === newToken.kind && oldToken.kind !== 'text' && oldToken.node.type.type === newToken.node.type, - buildAdded: (token, oldIdx) => buildInlineDiff('added', token, oldIdx), - buildDeleted: (token, oldIdx) => buildInlineDiff('deleted', token, oldIdx), - buildModified: (oldToken, newToken, oldIdx) => { - if (oldToken.kind !== 'text') { - return { - action: 'modified', - idx: oldIdx, - kind: 'inlineNode', - oldNode: oldToken.node, - newNode: newToken.node, - nodeType: oldToken.nodeType, - }; - } else { - return { - action: 'modified', - idx: oldIdx, - kind: 'text', - newText: newToken.char, - oldText: oldToken.char, - oldAttrs: oldToken.runAttrs, - newAttrs: newToken.runAttrs, - }; - } - }, - }); - - const groupedDiffs = groupDiffs(diffs, oldPositionResolver); - return groupedDiffs; -} - -/** - * Compares two inline tokens to decide if they can be considered equal for the Myers diff. - * Text tokens compare character equality while inline nodes compare their type. - * @param {InlineDiffToken} a - * @param {InlineDiffToken} b - * @returns {boolean} - */ -function inlineComparator(a, b) { - if (a.kind !== b.kind) { - return false; - } - - if (a.kind === 'text') { - return a.char === b.char; - } else { - return a.node.type === b.node.type; - } -} - -/** - * Determines whether equal tokens should still be treated as modifications, either because run attributes changed or the node payload differs. - * @param {InlineDiffToken} oldToken - * @param {InlineDiffToken} newToken - * @returns {boolean} - */ -function shouldProcessEqualAsModification(oldToken, newToken) { - if (oldToken.kind === 'text') { - return oldToken.runAttrs !== newToken.runAttrs; - } else { - return JSON.stringify(oldToken.toJSON()) !== JSON.stringify(newToken.toJSON()); - } -} - -/** - * Groups raw diff operations into contiguous ranges and converts serialized run attrs back to objects. - * @param {Array<{action:'added'|'deleted'|'modified', idx:number, kind:'text'|'inlineNode', text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string, nodeType?: string, node?: import('prosemirror-model').Node, oldNode?: import('prosemirror-model').Node, newNode?: import('prosemirror-model').Node}>} diffs - * @param {(index: number) => number|null} oldPositionResolver - * @returns {InlineDiffResult[]} - */ -function groupDiffs(diffs, oldPositionResolver) { - const grouped = []; - let currentGroup = null; - - /** - * Finalizes the current text group (if any) and appends it to the grouped result list. - * Resets the working group so the caller can start accumulating the next run. - */ - const pushCurrentGroup = () => { - if (!currentGroup) { - return; - } - const result = { ...currentGroup }; - if (currentGroup.action === 'modified') { - const oldAttrs = JSON.parse(currentGroup.oldAttrs); - const newAttrs = JSON.parse(currentGroup.newAttrs); - result.runAttrsDiff = getAttributesDiff(oldAttrs, newAttrs); - delete result.oldAttrs; - delete result.newAttrs; - } else { - result.runAttrs = JSON.parse(currentGroup.runAttrs); - } - grouped.push(result); - currentGroup = null; - }; - - // Iterate over raw diffs and group text changes where possible - for (const diff of diffs) { - if (diff.kind !== 'text') { - pushCurrentGroup(); - grouped.push({ - action: diff.action, - kind: 'inlineNode', - startPos: oldPositionResolver(diff.idx), - endPos: oldPositionResolver(diff.idx), - nodeType: diff.nodeType, - ...(diff.action === 'modified' - ? { - oldNode: diff.oldNode, - newNode: diff.newNode, - diffNodeAttrs: getAttributesDiff(diff.oldAttrs, diff.newAttrs), - } - : { node: diff.node }), - }); - continue; - } - - if (!currentGroup || !canExtendGroup(currentGroup, diff, oldPositionResolver)) { - pushCurrentGroup(); - currentGroup = createTextGroup(diff, oldPositionResolver); - } else { - extendTextGroup(currentGroup, diff, oldPositionResolver); - } - } - - pushCurrentGroup(); - return grouped; -} - -/** - * Builds a fresh text diff group seeded with the current diff token. - * @param {{action:'added'|'deleted'|'modified', idx:number, kind:'text', text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string}} diff - * @param {(index:number)=>number|null} positionResolver - * @returns {{action:'added'|'deleted'|'modified', kind:'text', startPos:number, endPos:number, text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string}} - */ -function createTextGroup(diff, positionResolver) { - const baseGroup = { - action: diff.action, - kind: 'text', - startPos: positionResolver(diff.idx), - endPos: positionResolver(diff.idx), - }; - if (diff.action === 'modified') { - baseGroup.newText = diff.newText; - baseGroup.oldText = diff.oldText; - baseGroup.oldAttrs = diff.oldAttrs; - baseGroup.newAttrs = diff.newAttrs; - } else { - baseGroup.text = diff.text; - baseGroup.runAttrs = diff.runAttrs; - } - return baseGroup; -} - -/** - * Expands the current text group with the incoming diff token. - * Keeps start/end positions updated while concatenating text payloads. - * @param {{action:'added'|'deleted'|'modified', kind:'text', startPos:number, endPos:number, text?: string, runAttrs?: string, newText?: string, oldText?: string, oldAttrs?: string, newAttrs?: string}} group - * @param {{action:'added'|'deleted'|'modified', idx:number, kind:'text', text?: string, runAttrs?: string, newText?: string, oldText?: string}} diff - * @param {(index:number)=>number|null} positionResolver - */ -function extendTextGroup(group, diff, positionResolver) { - group.endPos = positionResolver(diff.idx); - if (group.action === 'modified') { - group.newText += diff.newText; - group.oldText += diff.oldText; - } else { - group.text += diff.text; - } -} - -/** - * Determines whether a text diff token can be merged into the current group. - * Checks action, attributes, and adjacency constraints required by the grouping heuristic. - * @param {{action:'added'|'deleted'|'modified', kind:'text', startPos:number, endPos:number, runAttrs?: string, oldAttrs?: string, newAttrs?: string}} group - * @param {{action:'added'|'deleted'|'modified', idx:number, kind:'text', runAttrs?: string, oldAttrs?: string, newAttrs?: string}} diff - * @param {(index:number)=>number|null} positionResolver - * @returns {boolean} - */ -function canExtendGroup(group, diff, positionResolver) { - if (group.action !== diff.action) { - return false; - } - - if (group.action === 'modified') { - if (group.oldAttrs !== diff.oldAttrs || group.newAttrs !== diff.newAttrs) { - return false; - } - } else if (group.runAttrs !== diff.runAttrs) { - return false; - } - - if (group.action === 'added') { - return group.startPos === positionResolver(diff.idx); - } - return group.endPos + 1 === positionResolver(diff.idx); -} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index 6a71229ac0..b373826c37 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -1,11 +1,11 @@ import { describe, it, expect, vi } from 'vitest'; -vi.mock('./myers-diff.js', async () => { - const actual = await vi.importActual('./myers-diff.js'); +vi.mock('./myers-diff.ts', async () => { + const actual = await vi.importActual('./myers-diff.ts'); return { myersDiff: vi.fn(actual.myersDiff), }; }); -import { getInlineDiff } from './inline-diffing.js'; +import { getInlineDiff } from './inline-diffing.ts'; const buildTextRuns = (text, runAttrs = {}) => text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs), kind: 'text' })); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts new file mode 100644 index 0000000000..7cddccb92f --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -0,0 +1,373 @@ +import type { Node as PMNode } from 'prosemirror-model'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; +import { diffSequences } from './sequence-diffing.ts'; + +/** + * Supported diff operations for inline changes. + */ +type InlineAction = 'added' | 'deleted' | 'modified'; + +/** + * Serialized representation of a single text character plus its run attributes. + */ +export type InlineTextToken = { + kind: 'text'; + char: string; + runAttrs: string; +}; + +/** + * Flattened inline node token treated as a single diff unit. + */ +export type InlineNodeToken = { + kind: 'inlineNode'; + node: PMNode; + nodeType?: string; + toJSON?: () => unknown; +}; + +/** + * Union of inline token kinds used as input for Myers diffing. + */ +export type InlineDiffToken = InlineTextToken | InlineNodeToken; + +/** + * Intermediate text diff emitted by `diffSequences`. + */ +type RawTextDiff = + | { + action: Exclude; + idx: number; + kind: 'text'; + text: string; + runAttrs: string; + } + | { + action: 'modified'; + idx: number; + kind: 'text'; + newText: string; + oldText: string; + oldAttrs: string; + newAttrs: string; + }; + +/** + * Intermediate inline node diff emitted by `diffSequences`. + */ +type RawInlineNodeDiff = + | { + action: Exclude; + idx: number; + kind: 'inlineNode'; + node: PMNode; + nodeType?: string; + } + | { + action: 'modified'; + idx: number; + kind: 'inlineNode'; + oldNode: PMNode; + newNode: PMNode; + nodeType?: string; + oldAttrs?: Record; + newAttrs?: Record; + }; + +/** + * Combined raw diff union for text and inline node tokens. + */ +type RawDiff = RawTextDiff | RawInlineNodeDiff; + +/** + * Maps flattened string indexes back to ProseMirror document positions. + */ +type PositionResolver = (index: number) => number | null; + +/** + * Final grouped inline diff exposed to downstream consumers. + */ +export interface InlineDiffResult { + action: InlineAction; + kind: 'text' | 'inlineNode'; + startPos: number | null; + endPos: number | null; + text?: string; + oldText?: string; + newText?: string; + runAttrs?: Record; + runAttrsDiff?: AttributesDiff | null; + node?: PMNode; + nodeType?: string; + oldNode?: PMNode; + newNode?: PMNode; + diffNodeAttrs?: AttributesDiff | null; +} + +/** + * Computes text-level additions and deletions between two sequences using the generic sequence diff, mapping back to document positions. + * + * @param oldContent Source tokens. + * @param newContent Target tokens. + * @param oldPositionResolver Maps string indexes to the original document. + * @param newPositionResolver Maps string indexes to the updated document. + * @returns List of grouped inline diffs with document positions and text content. + */ +export function getInlineDiff( + oldContent: InlineDiffToken[], + newContent: InlineDiffToken[], + oldPositionResolver: PositionResolver, + newPositionResolver: PositionResolver = oldPositionResolver, +): InlineDiffResult[] { + void newPositionResolver; + + const buildInlineDiff = (action: InlineAction, token: InlineDiffToken, oldIdx: number): RawDiff => { + if (token.kind !== 'text') { + return { + action, + idx: oldIdx, + kind: 'inlineNode', + node: token.node, + nodeType: token.nodeType, + }; + } + return { + action, + idx: oldIdx, + kind: 'text', + text: token.char, + runAttrs: token.runAttrs, + }; + }; + + const diffs = diffSequences(oldContent, newContent, { + comparator: inlineComparator, + shouldProcessEqualAsModification, + canTreatAsModification: (oldToken, newToken) => + oldToken.kind === newToken.kind && oldToken.kind !== 'text' && oldToken.node.type === newToken.node.type, + buildAdded: (token, oldIdx) => buildInlineDiff('added', token, oldIdx), + buildDeleted: (token, oldIdx) => buildInlineDiff('deleted', token, oldIdx), + buildModified: (oldToken, newToken, oldIdx) => { + if (oldToken.kind !== 'text' && newToken.kind !== 'text') { + return { + action: 'modified', + idx: oldIdx, + kind: 'inlineNode', + oldNode: oldToken.node, + newNode: newToken.node, + nodeType: oldToken.nodeType, + }; + } + if (oldToken.kind === 'text' && newToken.kind === 'text') { + return { + action: 'modified', + idx: oldIdx, + kind: 'text', + newText: newToken.char, + oldText: oldToken.char, + oldAttrs: oldToken.runAttrs, + newAttrs: newToken.runAttrs, + }; + } + return null; + }, + }); + + return groupDiffs(diffs, oldPositionResolver); +} + +/** + * Compares two inline tokens to decide if they can be considered equal for the Myers diff. + * Text tokens compare character equality while inline nodes compare their type. + */ +function inlineComparator(a: InlineDiffToken, b: InlineDiffToken): boolean { + if (a.kind !== b.kind) { + return false; + } + + if (a.kind === 'text' && b.kind === 'text') { + return a.char === b.char; + } + if (a.kind === 'inlineNode' && b.kind === 'inlineNode') { + return a.node.type === b.node.type; + } + return false; +} + +/** + * Determines whether equal tokens should still be treated as modifications, either because run attributes changed or the node payload differs. + */ +function shouldProcessEqualAsModification(oldToken: InlineDiffToken, newToken: InlineDiffToken): boolean { + if (oldToken.kind === 'text' && newToken.kind === 'text') { + return oldToken.runAttrs !== newToken.runAttrs; + } + + if (oldToken.kind === 'inlineNode' && newToken.kind === 'inlineNode') { + const oldJSON = oldToken.toJSON?.() ?? oldToken.node.toJSON(); + const newJSON = newToken.toJSON?.() ?? newToken.node.toJSON(); + return JSON.stringify(oldJSON) !== JSON.stringify(newJSON); + } + + return false; +} + +/** + * Accumulator structure used while coalescing contiguous text diffs. + */ +type TextDiffGroup = + | { + action: Exclude; + kind: 'text'; + startPos: number | null; + endPos: number | null; + text: string; + runAttrs: string; + } + | { + action: 'modified'; + kind: 'text'; + startPos: number | null; + endPos: number | null; + newText: string; + oldText: string; + oldAttrs: string; + newAttrs: string; + }; + +/** + * Groups raw diff operations into contiguous ranges and converts serialized run attrs back to objects. + * + * @param diffs Raw diff operations from the sequence diff. + * @param oldPositionResolver Maps text indexes to original document positions. + * @returns Grouped inline diffs with start/end document positions. + */ +function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): InlineDiffResult[] { + const grouped: InlineDiffResult[] = []; + let currentGroup: TextDiffGroup | null = null; + + const pushCurrentGroup = () => { + if (!currentGroup) { + return; + } + const result: InlineDiffResult = { + action: currentGroup.action, + kind: 'text', + startPos: currentGroup.startPos, + endPos: currentGroup.endPos, + }; + + if (currentGroup.action === 'modified') { + const oldAttrs = JSON.parse(currentGroup.oldAttrs); + const newAttrs = JSON.parse(currentGroup.newAttrs); + result.oldText = currentGroup.oldText; + result.newText = currentGroup.newText; + result.runAttrsDiff = getAttributesDiff(oldAttrs, newAttrs); + } else { + result.text = currentGroup.text; + result.runAttrs = JSON.parse(currentGroup.runAttrs); + } + + grouped.push(result); + currentGroup = null; + }; + + for (const diff of diffs) { + if (diff.kind !== 'text') { + pushCurrentGroup(); + grouped.push({ + action: diff.action, + kind: 'inlineNode', + startPos: oldPositionResolver(diff.idx), + endPos: oldPositionResolver(diff.idx), + nodeType: diff.nodeType, + ...(diff.action === 'modified' + ? { + oldNode: diff.oldNode, + newNode: diff.newNode, + diffNodeAttrs: getAttributesDiff(diff.oldAttrs, diff.newAttrs), + } + : { node: diff.node }), + }); + continue; + } + + if (!currentGroup || !canExtendGroup(currentGroup, diff, oldPositionResolver)) { + pushCurrentGroup(); + currentGroup = createTextGroup(diff, oldPositionResolver); + } else { + extendTextGroup(currentGroup, diff, oldPositionResolver); + } + } + + pushCurrentGroup(); + return grouped; +} + +/** + * Builds a fresh text diff group seeded with the current diff token. + */ +function createTextGroup(diff: RawTextDiff, positionResolver: PositionResolver): TextDiffGroup { + const baseGroup = + diff.action === 'modified' + ? { + action: diff.action, + kind: 'text' as const, + startPos: positionResolver(diff.idx), + endPos: positionResolver(diff.idx), + newText: diff.newText, + oldText: diff.oldText, + oldAttrs: diff.oldAttrs, + newAttrs: diff.newAttrs, + } + : { + action: diff.action, + kind: 'text' as const, + startPos: positionResolver(diff.idx), + endPos: positionResolver(diff.idx), + text: diff.text, + runAttrs: diff.runAttrs, + }; + + return baseGroup; +} + +/** + * Expands the current text group with the incoming diff token. + * Keeps start/end positions updated while concatenating text payloads. + */ +function extendTextGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolver: PositionResolver): void { + group.endPos = positionResolver(diff.idx); + if (group.action === 'modified' && diff.action === 'modified') { + group.newText += diff.newText; + group.oldText += diff.oldText; + } else if (group.action !== 'modified' && diff.action !== 'modified') { + group.text += diff.text; + } +} + +/** + * Determines whether a text diff token can be merged into the current group. + * Checks action, attributes, and adjacency constraints required by the grouping heuristic. + */ +function canExtendGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolver: PositionResolver): boolean { + if (group.action !== diff.action) { + return false; + } + + if (group.action === 'modified' && diff.action === 'modified') { + if (group.oldAttrs !== diff.oldAttrs || group.newAttrs !== diff.newAttrs) { + return false; + } + } else if (group.action !== 'modified' && diff.action !== 'modified') { + if (group.runAttrs !== diff.runAttrs) { + return false; + } + } else { + return false; + } + + if (group.action === 'added') { + return group.startPos === positionResolver(diff.idx); + } + return (group.endPos ?? 0) + 1 === positionResolver(diff.idx); +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/myers-diff.js b/packages/super-editor/src/extensions/diffing/algorithm/myers-diff.ts similarity index 58% rename from packages/super-editor/src/extensions/diffing/algorithm/myers-diff.js rename to packages/super-editor/src/extensions/diffing/algorithm/myers-diff.ts index 6704d93a56..b90e709c78 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/myers-diff.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/myers-diff.ts @@ -1,11 +1,26 @@ +/** + * A primitive Myers diff operation describing equality, insertion, or deletion. + */ +export type MyersOperation = 'equal' | 'insert' | 'delete'; + +/** + * Minimal read-only sequence abstraction required by the diff algorithm. + */ +type Sequence = ArrayLike; +/** + * Equality predicate applied while traversing sequences. + */ +type Comparator = (a: T, b: T) => boolean; + /** * Computes a Myers diff operation list for arbitrary sequences. - * @param {Array|String} oldSeq - * @param {Array|String} newSeq - * @param {(a: any, b: any) => boolean} isEqual - * @returns {Array<'equal'|'insert'|'delete'>} + * + * @param oldSeq Original sequence to compare. + * @param newSeq Updated sequence to compare. + * @param isEqual Equality predicate used to determine matching elements. + * @returns Ordered list of diff operations describing how to transform {@link oldSeq} into {@link newSeq}. */ -export function myersDiff(oldSeq, newSeq, isEqual) { +export function myersDiff(oldSeq: Sequence, newSeq: Sequence, isEqual: Comparator): MyersOperation[] { const oldLen = oldSeq.length; const newLen = newSeq.length; @@ -17,16 +32,16 @@ export function myersDiff(oldSeq, newSeq, isEqual) { const max = oldLen + newLen; const size = 2 * max + 3; const offset = max + 1; - const v = new Array(size).fill(-1); + const v = new Array(size).fill(-1); v[offset + 1] = 0; - const trace = []; + const trace: number[][] = []; let foundPath = false; for (let d = 0; d <= max && !foundPath; d += 1) { for (let k = -d; k <= d; k += 2) { const index = offset + k; - let x; + let x: number; if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { x = v[index + 1]; @@ -56,14 +71,14 @@ export function myersDiff(oldSeq, newSeq, isEqual) { /** * Reconstructs the shortest edit script by walking the previously recorded V vectors. * - * @param {Array} trace - Snapshot of diagonal furthest-reaching points per edit distance. - * @param {number} oldLen - Length of the original string. - * @param {number} newLen - Length of the target string. - * @param {number} offset - Offset applied to diagonal indexes to keep array lookups positive. - * @returns {Array<'equal'|'delete'|'insert'>} Concrete step-by-step operations. + * @param trace Snapshot of diagonal furthest-reaching points per edit distance. + * @param oldLen Length of the original sequence. + * @param newLen Length of the target sequence. + * @param offset Offset applied to diagonal indexes to keep array lookups positive. + * @returns Concrete step-by-step operations transforming {@link oldLen} chars into {@link newLen} chars. */ -function backtrackMyers(trace, oldLen, newLen, offset) { - const operations = []; +function backtrackMyers(trace: number[][], oldLen: number, newLen: number, offset: number): MyersOperation[] { + const operations: MyersOperation[] = []; let x = oldLen; let y = newLen; @@ -72,7 +87,7 @@ function backtrackMyers(trace, oldLen, newLen, offset) { const k = x - y; const index = offset + k; - let prevK; + let prevK: number; if (k === -d || (k !== d && v[index - 1] < v[index + 1])) { prevK = k + 1; } else { diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js deleted file mode 100644 index e852b01895..0000000000 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.js +++ /dev/null @@ -1,261 +0,0 @@ -import { getInlineDiff } from './inline-diffing.js'; -import { getAttributesDiff } from './attributes-diffing.js'; -import { levenshteinDistance } from './similarity.js'; - -// Heuristics that prevent unrelated paragraphs from being paired as modifications. -const SIMILARITY_THRESHOLD = 0.65; -const MIN_LENGTH_FOR_SIMILARITY = 4; - -/** - * A paragraph addition diff emitted when new content is inserted. - * @typedef {Object} AddedParagraphDiff - * @property {'added'} action - * @property {string} nodeType ProseMirror node.name for downstream handling - * @property {Node} node reference to the ProseMirror node for consumers needing schema details - * @property {string} text textual contents of the inserted paragraph - * @property {number} pos document position where the paragraph was inserted - */ - -/** - * A paragraph deletion diff emitted when content is removed. - * @typedef {Object} DeletedParagraphDiff - * @property {'deleted'} action - * @property {string} nodeType ProseMirror node.name for downstream handling - * @property {Node} node reference to the original ProseMirror node - * @property {string} oldText text that was removed - * @property {number} pos starting document position of the original paragraph - */ - -/** - * A paragraph modification diff that carries inline text-level changes. - * @typedef {Object} ModifiedParagraphDiff - * @property {'modified'} action - * @property {string} nodeType ProseMirror node.name for downstream handling - * @property {string} oldText text before the edit - * @property {string} newText text after the edit - * @property {number} pos original document position for anchoring UI - * @property {ReturnType} contentDiff granular inline diff data - * @property {import('./attributes-diffing.js').AttributesDiff|null} attrsDiff attribute-level changes between the old and new paragraph nodes - */ - -/** - * Combined type representing every diff payload produced by `diffParagraphs`. - * @typedef {AddedParagraphDiff|DeletedParagraphDiff|ModifiedParagraphDiff} ParagraphDiff - */ - -/** - * A flattened representation of a text token derived from a paragraph. - * @typedef {Object} ParagraphTextToken - * @property {'text'} kind - * @property {string} char - * @property {string} runAttrs JSON stringified run attributes originating from the parent node - */ - -/** - * A flattened representation of an inline node that is treated as a single token by the diff. - * @typedef {Object} ParagraphInlineNodeToken - * @property {'inlineNode'} kind - * @property {Node} node - */ - -/** - * @typedef {ParagraphTextToken|ParagraphInlineNodeToken} ParagraphContentToken - */ - -/** - * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. - * @param {Node} paragraph - Paragraph node to flatten. - * @param {number} [paragraphPos=0] - Position of the paragraph in the document. - * @returns {{text: ParagraphContentToken[], resolvePosition: (index: number) => number|null}} Concatenated text tokens and a resolver that maps indexes to document positions. - */ -export function getParagraphContent(paragraph, paragraphPos = 0) { - let content = []; - const segments = []; - - paragraph.nodesBetween( - 0, - paragraph.content.size, - (node, pos) => { - let nodeText = ''; - - if (node.isText) { - nodeText = node.text; - } else if (node.isLeaf && node.type.spec.leafText) { - nodeText = node.type.spec.leafText(node); - } else if (node.type.name !== 'run' && node.isInline) { - const start = content.length; - const end = start + 1; - content.push({ - kind: 'inlineNode', - node: node, - }); - segments.push({ start, end, pos }); - return; - } else { - return; - } - - const start = content.length; - const end = start + nodeText.length; - - const runNode = paragraph.nodeAt(pos - 1); - const runAttrs = runNode.attrs || {}; - - segments.push({ start, end, pos }); - const chars = nodeText.split('').map((char) => ({ - kind: 'text', - char, - runAttrs: JSON.stringify(runAttrs), - })); - - content = content.concat(chars); - }, - 0, - ); - - const resolvePosition = (index) => { - if (index < 0 || index > content.length) { - return null; - } - - for (const segment of segments) { - if (index >= segment.start && index < segment.end) { - return paragraphPos + 1 + segment.pos + (index - segment.start); - } - } - - // If index points to the end of the string, return the paragraph end - return paragraphPos + 1 + paragraph.content.size; - }; - - return { text: content, resolvePosition }; -} - -/** - * Determines whether equal paragraph nodes should still be marked as modified because their serialized structure differs. - * @param {{node: Node}} oldParagraph - * @param {{node: Node}} newParagraph - * @returns {boolean} - */ -export function shouldProcessEqualAsModification(oldParagraph, newParagraph) { - return JSON.stringify(oldParagraph.node.toJSON()) !== JSON.stringify(newParagraph.node.toJSON()); -} - -/** - * Compares two paragraphs for identity based on paraId or text content so the diff can prioritize logical matches. - * This prevents the algorithm from treating the same paragraph as a deletion+insertion when the paraId or text proves - * they refer to the same logical node, which in turn keeps visual diffs stable. - * @param {{node: Node, fullText: string}} oldParagraph - * @param {{node: Node, fullText: string}} newParagraph - * @returns {boolean} - */ -export function paragraphComparator(oldParagraph, newParagraph) { - const oldId = oldParagraph?.node?.attrs?.paraId; - const newId = newParagraph?.node?.attrs?.paraId; - if (oldId && newId && oldId === newId) { - return true; - } - return oldParagraph?.fullText === newParagraph?.fullText; -} - -/** - * Builds a normalized payload describing a paragraph addition, ensuring all consumers receive the same metadata shape. - * @param {{node: Node, pos: number, fullText: string}} paragraph - * @param {{node: Node, pos: number}} previousOldNodeInfo node/position reference used to determine insertion point - * @returns {AddedParagraphDiff} - */ -export function buildAddedParagraphDiff(paragraph, previousOldNodeInfo) { - const pos = previousOldNodeInfo.pos + previousOldNodeInfo.node.nodeSize; - return { - action: 'added', - nodeType: paragraph.node.type.name, - node: paragraph.node, - text: paragraph.fullText, - pos: pos, - }; -} - -/** - * Builds a normalized payload describing a paragraph deletion so diff consumers can show removals with all context. - * @param {{node: Node, pos: number, fullText: string}} paragraph - * @returns {DeletedParagraphDiff} - */ -export function buildDeletedParagraphDiff(paragraph) { - return { - action: 'deleted', - nodeType: paragraph.node.type.name, - node: paragraph.node, - oldText: paragraph.fullText, - pos: paragraph.pos, - }; -} - -/** - * Builds the payload for a paragraph modification, including text-level diffs, so renderers can highlight edits inline. - * @param {{node: Node, pos: number, text: ParagraphContentToken[], resolvePosition: Function, fullText: string}} oldParagraph - * @param {{node: Node, pos: number, text: ParagraphContentToken[], resolvePosition: Function, fullText: string}} newParagraph - * @returns {ModifiedParagraphDiff|null} - */ -export function buildModifiedParagraphDiff(oldParagraph, newParagraph) { - const contentDiff = getInlineDiff( - oldParagraph.text, - newParagraph.text, - oldParagraph.resolvePosition, - newParagraph.resolvePosition, - ); - - const attrsDiff = getAttributesDiff(oldParagraph.node.attrs, newParagraph.node.attrs); - if (contentDiff.length === 0 && !attrsDiff) { - return null; - } - - return { - action: 'modified', - nodeType: oldParagraph.node.type.name, - oldText: oldParagraph.fullText, - newText: newParagraph.fullText, - pos: oldParagraph.pos, - contentDiff, - attrsDiff, - }; -} - -/** - * Decides whether a delete/insert pair should be reinterpreted as a modification to minimize noisy diff output. - * This heuristic limits the number of false-positive additions/deletions, which keeps reviewers focused on real edits. - * @param {{node: Node, fullText: string}} oldParagraph - * @param {{node: Node, fullText: string}} newParagraph - * @returns {boolean} - */ -export function canTreatAsModification(oldParagraph, newParagraph) { - if (paragraphComparator(oldParagraph, newParagraph)) { - return true; - } - - const oldText = oldParagraph.fullText; - const newText = newParagraph.fullText; - const maxLength = Math.max(oldText.length, newText.length); - if (maxLength < MIN_LENGTH_FOR_SIMILARITY) { - return false; - } - - const similarity = getTextSimilarityScore(oldText, newText); - - return similarity >= SIMILARITY_THRESHOLD; -} - -/** - * Scores the similarity between two text strings so the diff can decide if they represent the same conceptual paragraph. - * @param {string} oldText - * @param {string} newText - * @returns {number} - */ -function getTextSimilarityScore(oldText, newText) { - if (!oldText && !newText) { - return 1; - } - - const distance = levenshteinDistance(oldText, newText); - const maxLength = Math.max(oldText.length, newText.length) || 1; - return 1 - distance / maxLength; -} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index b457e38d86..5f508e44ed 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -7,7 +7,7 @@ import { buildDeletedParagraphDiff, buildModifiedParagraphDiff, canTreatAsModification, -} from './paragraph-diffing.js'; +} from './paragraph-diffing.ts'; const buildRuns = (text, attrs = {}) => text.split('').map((char) => ({ char, runAttrs: JSON.stringify(attrs), kind: 'text' })); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts new file mode 100644 index 0000000000..a875381ccb --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -0,0 +1,288 @@ +import type { Node as PMNode } from 'prosemirror-model'; +import { getInlineDiff, type InlineDiffToken, type InlineDiffResult } from './inline-diffing.ts'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; +import { levenshteinDistance } from './similarity.ts'; + +// Heuristics that prevent unrelated paragraphs from being paired as modifications. +const SIMILARITY_THRESHOLD = 0.65; +const MIN_LENGTH_FOR_SIMILARITY = 4; + +/** + * Flattened token emitted from a paragraph. Delegates to inline diff tokens. + */ +export type ParagraphContentToken = InlineDiffToken; +/** + * Maps flattened indexes back to the ProseMirror document. + */ +export type PositionResolver = (index: number) => number | null; + +/** + * Internal bookkeeping entry that remembers the start/end indexes for shallow nodes. + */ +interface ParagraphSegment { + start: number; + end: number; + pos: number; +} + +/** + * Computed textual representation of a paragraph plus its index resolver. + */ +export interface ParagraphContent { + text: ParagraphContentToken[]; + resolvePosition: PositionResolver; +} + +/** + * Bare reference to a paragraph node and its document position. + */ +export interface ParagraphNodeReference { + node: PMNode; + pos: number; +} + +/** + * Snapshot of a paragraph that includes its flattened text form. + */ +export interface ParagraphSnapshot extends ParagraphNodeReference { + fullText: string; +} + +/** + * Paragraph snapshot extended with the tokenized content and resolver. + */ +export interface ParagraphResolvedSnapshot extends ParagraphSnapshot { + text: ParagraphContentToken[]; + resolvePosition: PositionResolver; +} + +/** + * Diff payload produced when a paragraph is inserted. + */ +export interface AddedParagraphDiff { + action: 'added'; + nodeType: string; + node: PMNode; + text: string; + pos: number; +} + +/** + * Diff payload produced when a paragraph is deleted. + */ +export interface DeletedParagraphDiff { + action: 'deleted'; + nodeType: string; + node: PMNode; + oldText: string; + pos: number; +} + +/** + * Diff payload emitted when a paragraph changes, including inline edits. + */ +export interface ModifiedParagraphDiff { + action: 'modified'; + nodeType: string; + oldText: string; + newText: string; + pos: number; + contentDiff: InlineDiffResult[]; + attrsDiff: AttributesDiff | null; +} + +/** + * Union of every diff variant the paragraph diffing logic can produce. + */ +export type ParagraphDiff = AddedParagraphDiff | DeletedParagraphDiff | ModifiedParagraphDiff; + +/** + * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. + * + * @param paragraph Paragraph node to flatten. + * @param paragraphPos Position of the paragraph in the document. + * @returns Concatenated text tokens and a resolver that maps indexes to document positions. + */ +export function getParagraphContent(paragraph: PMNode, paragraphPos = 0): ParagraphContent { + const content: ParagraphContentToken[] = []; + const segments: ParagraphSegment[] = []; + + paragraph.nodesBetween( + 0, + paragraph.content.size, + (node, pos) => { + let nodeText = ''; + + if (node.isText) { + nodeText = node.text ?? ''; + } else if (node.isLeaf) { + const leafTextFn = (node.type.spec as { leafText?: (node: PMNode) => string } | undefined)?.leafText; + if (leafTextFn) { + nodeText = leafTextFn(node); + } + } + + if (nodeText) { + const start = content.length; + const end = start + nodeText.length; + const runNode = paragraph.nodeAt(pos - 1); + const runAttrs = runNode?.attrs ?? {}; + segments.push({ start, end, pos }); + const chars = nodeText.split('').map((char) => ({ + kind: 'text', + char, + runAttrs: JSON.stringify(runAttrs), + })); + content.push(...(chars as ParagraphContentToken[])); + return; + } + + if (node.type.name !== 'run' && node.isInline) { + const start = content.length; + const end = start + 1; + content.push({ + kind: 'inlineNode', + node, + }); + segments.push({ start, end, pos }); + } + }, + 0, + ); + + const resolvePosition: PositionResolver = (index) => { + if (index < 0 || index > content.length) { + return null; + } + + for (const segment of segments) { + if (index >= segment.start && index < segment.end) { + return paragraphPos + 1 + segment.pos + (index - segment.start); + } + } + + return paragraphPos + 1 + paragraph.content.size; + }; + + return { text: content, resolvePosition }; +} + +/** + * Determines whether equal paragraph nodes should still be marked as modified because their serialized structure differs. + * + * @param oldParagraph Previous paragraph node reference. + * @param newParagraph Updated paragraph node reference. + * @returns True when the serialized JSON payload differs. + */ +export function shouldProcessEqualAsModification( + oldParagraph: ParagraphNodeReference, + newParagraph: ParagraphNodeReference, +): boolean { + return JSON.stringify(oldParagraph.node.toJSON()) !== JSON.stringify(newParagraph.node.toJSON()); +} + +/** + * Compares two paragraphs for identity based on paraId or text content. + */ +export function paragraphComparator(oldParagraph: ParagraphSnapshot, newParagraph: ParagraphSnapshot): boolean { + const oldId = oldParagraph?.node?.attrs?.paraId; + const newId = newParagraph?.node?.attrs?.paraId; + if (oldId && newId && oldId === newId) { + return true; + } + return oldParagraph?.fullText === newParagraph?.fullText; +} + +/** + * Builds a normalized payload describing a paragraph addition, ensuring all consumers receive the same metadata shape. + */ +export function buildAddedParagraphDiff( + paragraph: ParagraphSnapshot, + previousOldNodeInfo?: ParagraphNodeReference, +): AddedParagraphDiff { + const previousNodeSize = previousOldNodeInfo?.node.nodeSize ?? 0; + const previousPos = previousOldNodeInfo?.pos ?? -1; + const pos = previousPos >= 0 ? previousPos + previousNodeSize : 0; + return { + action: 'added', + nodeType: paragraph.node.type.name, + node: paragraph.node, + text: paragraph.fullText, + pos, + }; +} + +/** + * Builds a normalized payload describing a paragraph deletion so diff consumers can show removals with all context. + */ +export function buildDeletedParagraphDiff(paragraph: ParagraphSnapshot): DeletedParagraphDiff { + return { + action: 'deleted', + nodeType: paragraph.node.type.name, + node: paragraph.node, + oldText: paragraph.fullText, + pos: paragraph.pos, + }; +} + +/** + * Builds the payload for a paragraph modification, including text-level diffs, so renderers can highlight edits inline. + */ +export function buildModifiedParagraphDiff( + oldParagraph: ParagraphResolvedSnapshot, + newParagraph: ParagraphResolvedSnapshot, +): ModifiedParagraphDiff | null { + const contentDiff = getInlineDiff( + oldParagraph.text, + newParagraph.text, + oldParagraph.resolvePosition, + newParagraph.resolvePosition, + ); + + const attrsDiff = getAttributesDiff(oldParagraph.node.attrs, newParagraph.node.attrs); + if (contentDiff.length === 0 && !attrsDiff) { + return null; + } + + return { + action: 'modified', + nodeType: oldParagraph.node.type.name, + oldText: oldParagraph.fullText, + newText: newParagraph.fullText, + pos: oldParagraph.pos, + contentDiff, + attrsDiff, + }; +} + +/** + * Decides whether a delete/insert pair should be reinterpreted as a modification to minimize noisy diff output. + */ +export function canTreatAsModification(oldParagraph: ParagraphSnapshot, newParagraph: ParagraphSnapshot): boolean { + if (paragraphComparator(oldParagraph, newParagraph)) { + return true; + } + + const oldText = oldParagraph.fullText; + const newText = newParagraph.fullText; + const maxLength = Math.max(oldText.length, newText.length); + if (maxLength < MIN_LENGTH_FOR_SIMILARITY) { + return false; + } + + const similarity = getTextSimilarityScore(oldText, newText); + return similarity >= SIMILARITY_THRESHOLD; +} + +/** + * Scores the similarity between two text strings so the diff can decide if they represent the same conceptual paragraph. + */ +function getTextSimilarityScore(oldText: string, newText: string): number { + if (!oldText && !newText) { + return 1; + } + + const distance = levenshteinDistance(oldText, newText); + const maxLength = Math.max(oldText.length, newText.length) || 1; + return 1 - distance / maxLength; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js index 679b4cc63b..e953cb82ae 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.test.js @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { diffSequences } from './sequence-diffing.js'; +import { diffSequences } from './sequence-diffing.ts'; const buildAdded = (item) => ({ action: 'added', id: item.id }); const buildDeleted = (item) => ({ action: 'deleted', id: item.id }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts similarity index 60% rename from packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js rename to packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts index 21fceb8215..1edced7916 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts @@ -1,32 +1,52 @@ -import { myersDiff } from './myers-diff.js'; +import { myersDiff, type MyersOperation } from './myers-diff.ts'; /** - * @typedef {Object} SequenceDiffOptions - * @property {(a: any, b: any) => boolean} [comparator] equality test passed to Myers diff - * @property {(item: any, oldIdx: number, previousOldItem: any, index: number) => any} buildAdded maps newly inserted entries - * @property {(item: any, index: number) => any} buildDeleted maps removed entries - * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => any|null} buildModified maps paired entries. If it returns null/undefined, it means no modification should be recorded. - * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [shouldProcessEqualAsModification] decides if equal-aligned entries should emit a modification - * @property {(oldItem: any, newItem: any, oldIndex: number, newIndex: number) => boolean} [canTreatAsModification] determines if delete/insert pairs are modifications - * @property {(operations: Array<'equal'|'delete'|'insert'>) => Array<'equal'|'delete'|'insert'>} [reorderOperations] optional hook to normalize raw Myers operations + * Comparator used to determine whether two sequence values are equal. */ +type Comparator = (a: T, b: T) => boolean; + +/** + * Discrete operation emitted by the Myers diff before higher-level mapping. + */ +type OperationStep = + | { type: 'equal'; oldIdx: number; newIdx: number } + | { type: 'delete'; oldIdx: number; newIdx: number } + | { type: 'insert'; oldIdx: number; newIdx: number }; + +/** + * Hooks and comparators used to translate raw Myers operations into domain-specific diffs. + */ +export interface SequenceDiffOptions { + comparator?: Comparator; + buildAdded: (item: T, oldIdx: number, previousOldItem: T | undefined, newIdx: number) => Added | null | undefined; + buildDeleted: (item: T, oldIdx: number, newIdx: number) => Deleted; + buildModified: (oldItem: T, newItem: T, oldIdx: number, newIdx: number) => Modified | null | undefined; + shouldProcessEqualAsModification?: (oldItem: T, newItem: T, oldIdx: number, newIdx: number) => boolean; + canTreatAsModification?: (deletedItem: T, insertedItem: T, oldIdx: number, newIdx: number) => boolean; + reorderOperations?: (operations: MyersOperation[]) => MyersOperation[]; +} /** * Generic sequence diff helper built on top of Myers algorithm. * Allows callers to provide custom comparators and payload builders that determine how * additions, deletions, and modifications should be reported. - * @param {Array} oldSeq - * @param {Array} newSeq - * @param {SequenceDiffOptions} options - * @returns {Array} + * + * @param oldSeq Original sequence to diff from. + * @param newSeq Target sequence to diff against. + * @param options Hook bundle that controls how additions/deletions/modifications are emitted. + * @returns Sequence of mapped diff payloads produced by the caller-provided builders. */ -export function diffSequences(oldSeq, newSeq, options) { +export function diffSequences( + oldSeq: T[], + newSeq: T[], + options: SequenceDiffOptions, +): Array { if (!options) { throw new Error('diffSequences requires an options object.'); } - const comparator = options.comparator ?? ((a, b) => a === b); - const reorder = options.reorderOperations ?? ((ops) => ops); + const comparator: Comparator = options.comparator ?? ((a: T, b: T) => a === b); + const reorder = options.reorderOperations ?? ((ops: MyersOperation[]) => ops); const canTreatAsModification = options.canTreatAsModification; const shouldProcessEqualAsModification = options.shouldProcessEqualAsModification; @@ -43,7 +63,7 @@ export function diffSequences(oldSeq, newSeq, options) { const operations = reorder(myersDiff(oldSeq, newSeq, comparator)); const steps = buildOperationSteps(operations); - const diffs = []; + const diffs: Array = []; for (let i = 0; i < steps.length; i += 1) { const step = steps[i]; @@ -57,7 +77,7 @@ export function diffSequences(oldSeq, newSeq, options) { continue; } const diff = options.buildModified(oldItem, newItem, step.oldIdx, step.newIdx); - if (diff) { + if (diff != null) { diffs.push(diff); } continue; @@ -71,7 +91,7 @@ export function diffSequences(oldSeq, newSeq, options) { canTreatAsModification(oldSeq[step.oldIdx], newSeq[nextStep.newIdx], step.oldIdx, nextStep.newIdx) ) { const diff = options.buildModified(oldSeq[step.oldIdx], newSeq[nextStep.newIdx], step.oldIdx, nextStep.newIdx); - if (diff) { + if (diff != null) { diffs.push(diff); } i += 1; @@ -83,7 +103,7 @@ export function diffSequences(oldSeq, newSeq, options) { if (step.type === 'insert') { const diff = options.buildAdded(newSeq[step.newIdx], step.oldIdx, oldSeq[step.oldIdx - 1], step.newIdx); - if (diff) { + if (diff != null) { diffs.push(diff); } } @@ -94,13 +114,14 @@ export function diffSequences(oldSeq, newSeq, options) { /** * Translates the raw Myers operations into indexed steps so higher-level logic can reason about positions. - * @param {Array<'equal'|'delete'|'insert'>} operations - * @returns {Array} + * + * @param operations Myers diff operations produced for the input sequences. + * @returns Indexed steps that reference the original `oldSeq` and `newSeq` positions. */ -function buildOperationSteps(operations) { +function buildOperationSteps(operations: MyersOperation[]): OperationStep[] { let oldIdx = 0; let newIdx = 0; - const steps = []; + const steps: OperationStep[] = []; for (const op of operations) { if (op === 'equal') { @@ -121,11 +142,12 @@ function buildOperationSteps(operations) { /** * Normalizes interleaved delete/insert operations so consumers can treat replacements as paired steps. - * @param {Array<'equal'|'delete'|'insert'>} operations - * @returns {Array<'equal'|'delete'|'insert'>} + * + * @param operations Raw Myers operations. + * @returns Normalized operation sequence with deletes and inserts paired. */ -export function reorderDiffOperations(operations) { - const normalized = []; +export function reorderDiffOperations(operations: MyersOperation[]): MyersOperation[] { + const normalized: MyersOperation[] = []; for (let i = 0; i < operations.length; i += 1) { const op = operations[i]; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/similarity.js b/packages/super-editor/src/extensions/diffing/algorithm/similarity.ts similarity index 71% rename from packages/super-editor/src/extensions/diffing/algorithm/similarity.js rename to packages/super-editor/src/extensions/diffing/algorithm/similarity.ts index d0118aabda..60d9604e89 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/similarity.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/similarity.ts @@ -1,10 +1,11 @@ /** * Computes the Levenshtein edit distance between two strings. - * @param {string} a - * @param {string} b - * @returns {number} + * + * @param a First string. + * @param b Second string. + * @returns Minimum number of edits required to transform {@link a} into {@link b}. */ -export function levenshteinDistance(a, b) { +export function levenshteinDistance(a: string, b: string): number { const lenA = a.length; const lenB = b.length; @@ -15,8 +16,8 @@ export function levenshteinDistance(a, b) { return lenA; } - let previous = new Array(lenB + 1); - let current = new Array(lenB + 1); + let previous = new Array(lenB + 1); + let current = new Array(lenB + 1); for (let j = 0; j <= lenB; j += 1) { previous[j] = j; diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.js b/packages/super-editor/src/extensions/diffing/computeDiff.js deleted file mode 100644 index 4025597fe1..0000000000 --- a/packages/super-editor/src/extensions/diffing/computeDiff.js +++ /dev/null @@ -1,11 +0,0 @@ -import { diffNodes } from './algorithm/generic-diffing.js'; - -/** - * Computes paragraph-level diffs between two ProseMirror documents, returning inserts, deletes and text modifications. - * @param {Node} oldPmDoc - The previous ProseMirror document. - * @param {Node} newPmDoc - The updated ProseMirror document. - * @returns {Array} List of diff objects describing added, deleted or modified paragraphs. - */ -export function computeDiff(oldPmDoc, newPmDoc) { - return diffNodes(oldPmDoc, newPmDoc); -} diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts new file mode 100644 index 0000000000..feb84642aa --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -0,0 +1,20 @@ +import type { Node as PMNode } from 'prosemirror-model'; +import { diffNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; + +/** + * Computes structural diffs between two ProseMirror documents, emitting insert/delete/modify operations for any block + * node (paragraphs, images, tables, etc.). Paragraph mutations include inline text and inline-node diffs so consumers + * can reflect character-level and formatting changes as well. + * + * Diffs are intended to be replayed on top of the old document in reverse order: `pos` marks the cursor location + * that should be used before applying the diff at that index. For example, consecutive additions that sit between the + * same pair of old nodes will share the same `pos`, so applying them from the end of the list guarantees they appear + * in the correct order in the reconstructed document. + * + * @param oldPmDoc The previous ProseMirror document. + * @param newPmDoc The updated ProseMirror document. + * @returns List of diff objects describing added, deleted or modified nodes (with inline-level diffs for paragraphs). + */ +export function computeDiff(oldPmDoc: PMNode, newPmDoc: PMNode): NodeDiff[] { + return diffNodes(oldPmDoc, newPmDoc); +} diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 1ebfdc3b0e..f90c518219 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -1,6 +1,6 @@ // @ts-nocheck import { Extension } from '@core/Extension.js'; -import { computeDiff } from './computeDiff.js'; +import { computeDiff } from './computeDiff.ts'; export const Diffing = Extension.create({ name: 'documentDiffing', From f73460b007be8df1dab60c618906b3665b2cf947 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 16:26:05 -0300 Subject: [PATCH 027/125] fix: diffing of inline node attributes --- .../diffing/algorithm/inline-diffing.test.js | 44 +++++++++++++++++++ .../diffing/algorithm/inline-diffing.ts | 4 +- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index b373826c37..3479fce29f 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -10,6 +10,19 @@ import { getInlineDiff } from './inline-diffing.ts'; const buildTextRuns = (text, runAttrs = {}) => text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs), kind: 'text' })); +const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }) => { + const nodeAttrs = { ...attrs }; + return { + kind: 'inlineNode', + nodeType: 'link', + node: { + type, + attrs: nodeAttrs, + toJSON: () => ({ type: 'link', attrs: nodeAttrs }), + }, + }; +}; + describe('getInlineDiff', () => { it('returns an empty diff list when both strings are identical', () => { const resolver = (index) => index; @@ -107,4 +120,35 @@ describe('getInlineDiff', () => { }, ]); }); + + it('surfaces attribute diffs for inline node modifications', () => { + const resolver = (index) => index + 3; + const sharedType = { name: 'link' }; + const oldNode = buildInlineNodeToken({ href: 'https://old.example', label: 'Example' }, sharedType); + const newNode = buildInlineNodeToken({ href: 'https://new.example', label: 'Example' }, sharedType); + + const diffs = getInlineDiff([oldNode], [newNode], resolver); + + expect(diffs).toEqual([ + { + action: 'modified', + kind: 'inlineNode', + nodeType: 'link', + startPos: 3, + endPos: 3, + oldNode: oldNode.node, + newNode: newNode.node, + attrsDiff: { + added: {}, + deleted: {}, + modified: { + href: { + from: 'https://old.example', + to: 'https://new.example', + }, + }, + }, + }, + ]); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index 7cddccb92f..c5233d2c01 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -101,7 +101,7 @@ export interface InlineDiffResult { nodeType?: string; oldNode?: PMNode; newNode?: PMNode; - diffNodeAttrs?: AttributesDiff | null; + attrsDiff?: AttributesDiff | null; } /** @@ -284,7 +284,7 @@ function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): In ? { oldNode: diff.oldNode, newNode: diff.newNode, - diffNodeAttrs: getAttributesDiff(diff.oldAttrs, diff.newAttrs), + attrsDiff: getAttributesDiff(diff.oldNode.attrs, diff.newNode.attrs), } : { node: diff.node }), }); From cf828f4810c3e4cbefe6be5edec78ca7bd49fcf9 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 16:30:40 -0300 Subject: [PATCH 028/125] fix: diff positions for modified non-paragraph nodes --- .../src/extensions/diffing/algorithm/generic-diffing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 5c0944bf59..71bb0d3efd 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -215,7 +215,7 @@ function buildModifiedDiff(oldNodeInfo: NodeInfo, newNodeInfo: NodeInfo): NodeDi nodeType: oldNodeInfo.node.type.name, oldNode: oldNodeInfo.node, newNode: newNodeInfo.node, - pos: newNodeInfo.pos, + pos: oldNodeInfo.pos, attrsDiff, }; } From e59990a390e08b9a05795c9a1ba3276c381fce71 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 29 Dec 2025 17:24:51 -0300 Subject: [PATCH 029/125] feat: improve diff comparison for table rows --- .../src/extensions/diffing/algorithm/generic-diffing.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 71bb0d3efd..b8ed91a292 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -126,6 +126,13 @@ function nodeComparator(oldNodeInfo: NodeInfo, newNodeInfo: NodeInfo): boolean { } if (isParagraphNodeInfo(oldNodeInfo) && isParagraphNodeInfo(newNodeInfo)) { return paragraphComparator(oldNodeInfo, newNodeInfo); + } else if ( + oldNodeInfo.node.type.name === 'tableRow' && + newNodeInfo.node.type.name === 'tableRow' && + oldNodeInfo.node.attrs.paraId && + newNodeInfo.node.attrs.paraId + ) { + return oldNodeInfo.node.attrs.paraId === newNodeInfo.node.attrs.paraId; } return true; } From 67860b172998fab89be2445b966af9464b45719e Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 11:00:43 -0300 Subject: [PATCH 030/125] fix: emit single diff when container node is deleted --- .../diffing/algorithm/generic-diffing.test.js | 16 ++++++++++++++++ .../diffing/algorithm/generic-diffing.ts | 12 ++++++++++-- .../diffing/algorithm/sequence-diffing.ts | 7 +++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js index 1dbabf98de..e6663a880a 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js @@ -149,6 +149,22 @@ describe('diffParagraphs', () => { expect(additions[0].nodeType).toBe('figure'); }); + it('deduplicates deleted nodes and their descendants', () => { + const childNode = buildSimpleNode('image'); + const parentNode = buildSimpleNode('figure', {}, { children: [childNode] }); + const paragraph = createParagraph('Base paragraph', {}, { pos: 0 }); + const figurePos = paragraph.pos + paragraph.node.nodeSize; + + const diffs = diffNodes( + createDocFromNodes([paragraph, { node: parentNode, pos: figurePos }, { node: childNode, pos: figurePos + 1 }]), + createDocFromNodes([paragraph]), + ); + + const deletions = diffs.filter((diff) => diff.action === 'deleted'); + expect(deletions).toHaveLength(1); + expect(deletions[0].nodeType).toBe('figure'); + }); + it('computes insertion position based on the previous old node', () => { const oldParagraph = createParagraph('Hello!', {}, { pos: 0 }); const newParagraph = createParagraph('Hello!', {}, { pos: 0 }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index b8ed91a292..b2409cc71f 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -76,6 +76,7 @@ export function diffNodes(oldRoot: PMNode, newRoot: PMNode): NodeDiff[] { const newNodes = normalizeNodes(newRoot); const addedNodesSet = new Set(); + const deletedNodesSet = new Set(); return diffSequences(oldNodes, newNodes, { comparator: nodeComparator, reorderOperations: reorderDiffOperations, @@ -83,7 +84,7 @@ export function diffNodes(oldRoot: PMNode, newRoot: PMNode): NodeDiff[] { canTreatAsModification, buildAdded: (nodeInfo, _oldIdx, previousOldNodeInfo) => buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet), - buildDeleted: buildDeletedDiff, + buildDeleted: (nodeInfo) => buildDeletedDiff(nodeInfo, deletedNodesSet), buildModified: buildModifiedDiff, }); } @@ -192,10 +193,17 @@ function buildAddedDiff( /** * Builds the diff payload for a deleted node. */ -function buildDeletedDiff(nodeInfo: NodeInfo): NodeDiff { +function buildDeletedDiff(nodeInfo: NodeInfo, deletedNodesSet: Set): NodeDiff | null { + if (deletedNodesSet.has(nodeInfo.node)) { + return null; + } + deletedNodesSet.add(nodeInfo.node); if (isParagraphNodeInfo(nodeInfo)) { return buildDeletedParagraphDiff(nodeInfo); } + nodeInfo.node.descendants((childNode) => { + deletedNodesSet.add(childNode); + }); return { action: 'deleted', nodeType: nodeInfo.node.type.name, diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts index 1edced7916..136184bdc6 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts @@ -19,7 +19,7 @@ type OperationStep = export interface SequenceDiffOptions { comparator?: Comparator; buildAdded: (item: T, oldIdx: number, previousOldItem: T | undefined, newIdx: number) => Added | null | undefined; - buildDeleted: (item: T, oldIdx: number, newIdx: number) => Deleted; + buildDeleted: (item: T, oldIdx: number, newIdx: number) => Deleted | null | undefined; buildModified: (oldItem: T, newItem: T, oldIdx: number, newIdx: number) => Modified | null | undefined; shouldProcessEqualAsModification?: (oldItem: T, newItem: T, oldIdx: number, newIdx: number) => boolean; canTreatAsModification?: (deletedItem: T, insertedItem: T, oldIdx: number, newIdx: number) => boolean; @@ -96,7 +96,10 @@ export function diffSequences( } i += 1; } else { - diffs.push(options.buildDeleted(oldSeq[step.oldIdx], step.oldIdx, step.newIdx)); + const diff = options.buildDeleted(oldSeq[step.oldIdx], step.oldIdx, step.newIdx); + if (diff != null) { + diffs.push(diff); + } } continue; } From 321bf8d789d641364fc7f28eb3551a538a2c49ef Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 11:37:40 -0300 Subject: [PATCH 031/125] fix: compute correct insertion position for first child node --- .../diffing/algorithm/generic-diffing.test.js | 81 ++++++++++++++----- .../diffing/algorithm/generic-diffing.ts | 23 ++++-- .../diffing/algorithm/paragraph-diffing.ts | 12 ++- 3 files changed, 89 insertions(+), 27 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js index e6663a880a..bb2af561e0 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js @@ -1,11 +1,26 @@ import { describe, it, expect } from 'vitest'; import { diffNodes } from './generic-diffing.ts'; -const createDocFromNodes = (nodes = []) => ({ - descendants(callback) { - nodes.forEach(({ node, pos }) => callback(node, pos)); - }, -}); +const createDocFromNodes = (nodes = []) => { + const docNode = { + type: { name: 'doc', spec: {} }, + descendants(callback) { + const childIndexMap = new WeakMap(); + const depthStack = [docNode]; + for (const entry of nodes) { + const { node, pos, depth = 1 } = entry; + depthStack.length = depth; + const parentNode = depthStack[depth - 1] ?? docNode; + const currentIndex = childIndexMap.get(parentNode) ?? 0; + childIndexMap.set(parentNode, currentIndex + 1); + callback(node, pos, parentNode, currentIndex); + depthStack[depth] = node; + } + }, + }; + + return docNode; +}; const buildSimpleNode = (typeName, attrs = {}, options = {}) => { const { nodeSize = 2, children = [] } = options; @@ -27,7 +42,7 @@ const buildSimpleNode = (typeName, attrs = {}, options = {}) => { }; const createParagraph = (text, attrs = {}, options = {}) => { - const { pos = 0, textAttrs = {} } = options; + const { pos = 0, textAttrs = {}, depth = 1 } = options; const paragraphNode = { attrs, type: { name: 'paragraph', spec: {} }, @@ -54,15 +69,15 @@ const createParagraph = (text, attrs = {}, options = {}) => { }; paragraphNode.toJSON = () => ({ type: paragraphNode.type.name, attrs: paragraphNode.attrs }); - return { node: paragraphNode, pos }; + return { node: paragraphNode, pos, depth }; }; describe('diffParagraphs', () => { it('treats similar paragraphs without IDs as modifications', () => { const oldParagraphs = [createParagraph('Hello world from ProseMirror.')]; const newParagraphs = [createParagraph('Hello brave new world from ProseMirror.')]; - const oldRoot = { descendants: (cb) => oldParagraphs.forEach((p) => cb(p.node, p.pos)) }; - const newRoot = { descendants: (cb) => newParagraphs.forEach((p) => cb(p.node, p.pos)) }; + const oldRoot = createDocFromNodes(oldParagraphs); + const newRoot = createDocFromNodes(newParagraphs); const diffs = diffNodes(oldRoot, newRoot); @@ -74,8 +89,8 @@ describe('diffParagraphs', () => { it('keeps unrelated paragraphs as deletion + addition', () => { const oldParagraphs = [createParagraph('Alpha paragraph with some text.')]; const newParagraphs = [createParagraph('Zephyr quickly jinxed the new passage.')]; - const oldRoot = { descendants: (cb) => oldParagraphs.forEach((p) => cb(p.node, p.pos)) }; - const newRoot = { descendants: (cb) => newParagraphs.forEach((p) => cb(p.node, p.pos)) }; + const oldRoot = createDocFromNodes(oldParagraphs); + const newRoot = createDocFromNodes(newParagraphs); const diffs = diffNodes(oldRoot, newRoot); @@ -93,8 +108,8 @@ describe('diffParagraphs', () => { createParagraph('Original introduction paragraph that now has tweaks.'), createParagraph('Completely different replacement paragraph.'), ]; - const oldRoot = { descendants: (cb) => oldParagraphs.forEach((p) => cb(p.node, p.pos)) }; - const newRoot = { descendants: (cb) => newParagraphs.forEach((p) => cb(p.node, p.pos)) }; + const oldRoot = createDocFromNodes(oldParagraphs); + const newRoot = createDocFromNodes(newParagraphs); const diffs = diffNodes(oldRoot, newRoot); @@ -117,8 +132,8 @@ describe('diffParagraphs', () => { }); it('emits attribute diffs for non-paragraph nodes', () => { - const oldHeading = { node: buildSimpleNode('heading', { level: 1 }), pos: 0 }; - const newHeading = { node: buildSimpleNode('heading', { level: 2 }), pos: 0 }; + const oldHeading = { node: buildSimpleNode('heading', { level: 1 }), pos: 0, depth: 1 }; + const newHeading = { node: buildSimpleNode('heading', { level: 2 }), pos: 0, depth: 1 }; const diffs = diffNodes(createDocFromNodes([oldHeading]), createDocFromNodes([newHeading])); expect(diffs).toHaveLength(1); @@ -139,8 +154,8 @@ describe('diffParagraphs', () => { createDocFromNodes([oldParagraph]), createDocFromNodes([ newParagraph, - { node: parentNode, pos: insertionPos }, - { node: childNode, pos: insertionPos + 1 }, + { node: parentNode, pos: insertionPos, depth: 1 }, + { node: childNode, pos: insertionPos + 1, depth: 2 }, ]), ); @@ -156,7 +171,11 @@ describe('diffParagraphs', () => { const figurePos = paragraph.pos + paragraph.node.nodeSize; const diffs = diffNodes( - createDocFromNodes([paragraph, { node: parentNode, pos: figurePos }, { node: childNode, pos: figurePos + 1 }]), + createDocFromNodes([ + paragraph, + { node: parentNode, pos: figurePos, depth: 1 }, + { node: childNode, pos: figurePos + 1, depth: 2 }, + ]), createDocFromNodes([paragraph]), ); @@ -165,6 +184,30 @@ describe('diffParagraphs', () => { expect(deletions[0].nodeType).toBe('figure'); }); + it('computes insertion position for nodes added to the beginning of a container', () => { + const oldRow = buildSimpleNode('tableRow', { paraId: 'row-1' }, { nodeSize: 4 }); + const oldTable = buildSimpleNode('table', {}, { nodeSize: 10, children: [oldRow] }); + const oldDoc = createDocFromNodes([ + { node: oldTable, pos: 0, depth: 1 }, + { node: oldRow, pos: 1, depth: 2 }, + ]); + + const insertedRow = buildSimpleNode('tableRow', { paraId: 'row-2' }, { nodeSize: 4 }); + const persistedRow = buildSimpleNode('tableRow', { paraId: 'row-1' }, { nodeSize: 4 }); + const newTable = buildSimpleNode('table', {}, { nodeSize: 14, children: [insertedRow, persistedRow] }); + const newDoc = createDocFromNodes([ + { node: newTable, pos: 0, depth: 1 }, + { node: insertedRow, pos: 1, depth: 2 }, + { node: persistedRow, pos: 1 + insertedRow.nodeSize, depth: 2 }, + ]); + + const diffs = diffNodes(oldDoc, newDoc); + + const addition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'tableRow'); + expect(addition).toBeDefined(); + expect(addition.pos).toBe(1); + }); + it('computes insertion position based on the previous old node', () => { const oldParagraph = createParagraph('Hello!', {}, { pos: 0 }); const newParagraph = createParagraph('Hello!', {}, { pos: 0 }); @@ -173,7 +216,7 @@ describe('diffParagraphs', () => { const diffs = diffNodes( createDocFromNodes([oldParagraph]), - createDocFromNodes([newParagraph, { node: headingNode, pos: expectedPos }]), + createDocFromNodes([newParagraph, { node: headingNode, pos: expectedPos, depth: 1 }]), ); const addition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'heading'); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index b2409cc71f..9e62aec494 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -20,6 +20,7 @@ import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts' type BaseNodeInfo = { node: PMNode; pos: number; + depth: number; }; /** @@ -94,12 +95,19 @@ export function diffNodes(oldRoot: PMNode, newRoot: PMNode): NodeDiff[] { */ function normalizeNodes(pmDoc: PMNode): NodeInfo[] { const nodes: NodeInfo[] = []; - pmDoc.descendants((node, pos) => { + const depthMap = new WeakMap(); + depthMap.set(pmDoc, -1); + + pmDoc.descendants((node, pos, parent) => { + const parentDepth = parent ? (depthMap.get(parent) ?? -1) : -1; + const depth = parentDepth + 1; + depthMap.set(node, depth); if (node.type.name === 'paragraph') { const { text, resolvePosition } = getParagraphContent(node, pos); const fullText = getFullText(text); nodes.push({ node, + depth, pos, text, resolvePosition, @@ -107,7 +115,7 @@ function normalizeNodes(pmDoc: PMNode): NodeInfo[] { }); return false; } - nodes.push({ node, pos }); + nodes.push({ node, pos, depth }); return undefined; }); return nodes; @@ -179,9 +187,14 @@ function buildAddedDiff( addedNodesSet.add(childNode); }); - const previousPos = previousOldNodeInfo?.pos ?? -1; - const previousSize = previousOldNodeInfo?.node.nodeSize ?? 0; - const pos = previousPos >= 0 ? previousPos + previousSize : 0; + let pos; + if (nodeInfo.depth === previousOldNodeInfo?.depth) { + const previousPos = previousOldNodeInfo?.pos ?? -1; + const previousSize = previousOldNodeInfo?.node.nodeSize ?? 0; + pos = previousPos >= 0 ? previousPos + previousSize : 0; + } else { + pos = (previousOldNodeInfo?.pos ?? -1) + 1; + } return { action: 'added', nodeType: nodeInfo.node.type.name, diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index a875381ccb..30215c16ac 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -39,6 +39,7 @@ export interface ParagraphContent { export interface ParagraphNodeReference { node: PMNode; pos: number; + depth: number; } /** @@ -200,9 +201,14 @@ export function buildAddedParagraphDiff( paragraph: ParagraphSnapshot, previousOldNodeInfo?: ParagraphNodeReference, ): AddedParagraphDiff { - const previousNodeSize = previousOldNodeInfo?.node.nodeSize ?? 0; - const previousPos = previousOldNodeInfo?.pos ?? -1; - const pos = previousPos >= 0 ? previousPos + previousNodeSize : 0; + let pos; + if (paragraph.depth === previousOldNodeInfo?.depth) { + const previousPos = previousOldNodeInfo?.pos ?? -1; + const previousSize = previousOldNodeInfo?.node.nodeSize ?? 0; + pos = previousPos >= 0 ? previousPos + previousSize : 0; + } else { + pos = (previousOldNodeInfo?.pos ?? -1) + 1; + } return { action: 'added', nodeType: paragraph.node.type.name, From 6e64341a4ecfa4a0d71ee60539282486d3c7f9c0 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 11:45:46 -0300 Subject: [PATCH 032/125] fix: remove unused position resolver for inline diffing --- .../src/extensions/diffing/algorithm/inline-diffing.ts | 6 +----- .../src/extensions/diffing/algorithm/paragraph-diffing.ts | 7 +------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index c5233d2c01..f137051d79 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -109,18 +109,14 @@ export interface InlineDiffResult { * * @param oldContent Source tokens. * @param newContent Target tokens. - * @param oldPositionResolver Maps string indexes to the original document. - * @param newPositionResolver Maps string indexes to the updated document. + * @param oldPositionResolver Maps indexes to the original document. * @returns List of grouped inline diffs with document positions and text content. */ export function getInlineDiff( oldContent: InlineDiffToken[], newContent: InlineDiffToken[], oldPositionResolver: PositionResolver, - newPositionResolver: PositionResolver = oldPositionResolver, ): InlineDiffResult[] { - void newPositionResolver; - const buildInlineDiff = (action: InlineAction, token: InlineDiffToken, oldIdx: number): RawDiff => { if (token.kind !== 'text') { return { diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 30215c16ac..8a2e2fdbec 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -238,12 +238,7 @@ export function buildModifiedParagraphDiff( oldParagraph: ParagraphResolvedSnapshot, newParagraph: ParagraphResolvedSnapshot, ): ModifiedParagraphDiff | null { - const contentDiff = getInlineDiff( - oldParagraph.text, - newParagraph.text, - oldParagraph.resolvePosition, - newParagraph.resolvePosition, - ); + const contentDiff = getInlineDiff(oldParagraph.text, newParagraph.text, oldParagraph.resolvePosition); const attrsDiff = getAttributesDiff(oldParagraph.node.attrs, newParagraph.node.attrs); if (contentDiff.length === 0 && !attrsDiff) { From 7e6532a54a3bf3051805fd88ab25865f19b6ebb7 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 12:24:49 -0300 Subject: [PATCH 033/125] refactor: remove serialization/deserialization of run attrs during diff --- .../diffing/algorithm/inline-diffing.test.js | 2 +- .../diffing/algorithm/inline-diffing.ts | 34 ++++++++++--------- .../algorithm/paragraph-diffing.test.js | 3 +- .../diffing/algorithm/paragraph-diffing.ts | 2 +- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index 3479fce29f..df82545ab2 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -8,7 +8,7 @@ vi.mock('./myers-diff.ts', async () => { import { getInlineDiff } from './inline-diffing.ts'; const buildTextRuns = (text, runAttrs = {}) => - text.split('').map((char) => ({ char, runAttrs: JSON.stringify(runAttrs), kind: 'text' })); + text.split('').map((char) => ({ char, runAttrs: { ...runAttrs }, kind: 'text' })); const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }) => { const nodeAttrs = { ...attrs }; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index f137051d79..caac098077 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -13,7 +13,7 @@ type InlineAction = 'added' | 'deleted' | 'modified'; export type InlineTextToken = { kind: 'text'; char: string; - runAttrs: string; + runAttrs: Record; }; /** @@ -40,7 +40,7 @@ type RawTextDiff = idx: number; kind: 'text'; text: string; - runAttrs: string; + runAttrs: Record; } | { action: 'modified'; @@ -48,8 +48,8 @@ type RawTextDiff = kind: 'text'; newText: string; oldText: string; - oldAttrs: string; - newAttrs: string; + oldAttrs: Record; + newAttrs: Record; }; /** @@ -195,12 +195,12 @@ function inlineComparator(a: InlineDiffToken, b: InlineDiffToken): boolean { */ function shouldProcessEqualAsModification(oldToken: InlineDiffToken, newToken: InlineDiffToken): boolean { if (oldToken.kind === 'text' && newToken.kind === 'text') { - return oldToken.runAttrs !== newToken.runAttrs; + return Boolean(getAttributesDiff(oldToken.runAttrs, newToken.runAttrs)); } if (oldToken.kind === 'inlineNode' && newToken.kind === 'inlineNode') { - const oldJSON = oldToken.toJSON?.() ?? oldToken.node.toJSON(); - const newJSON = newToken.toJSON?.() ?? newToken.node.toJSON(); + const oldJSON = oldToken.node.toJSON(); + const newJSON = newToken.node.toJSON(); return JSON.stringify(oldJSON) !== JSON.stringify(newJSON); } @@ -217,7 +217,7 @@ type TextDiffGroup = startPos: number | null; endPos: number | null; text: string; - runAttrs: string; + runAttrs: Record; } | { action: 'modified'; @@ -226,8 +226,8 @@ type TextDiffGroup = endPos: number | null; newText: string; oldText: string; - oldAttrs: string; - newAttrs: string; + oldAttrs: Record; + newAttrs: Record; }; /** @@ -253,14 +253,12 @@ function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): In }; if (currentGroup.action === 'modified') { - const oldAttrs = JSON.parse(currentGroup.oldAttrs); - const newAttrs = JSON.parse(currentGroup.newAttrs); result.oldText = currentGroup.oldText; result.newText = currentGroup.newText; - result.runAttrsDiff = getAttributesDiff(oldAttrs, newAttrs); + result.runAttrsDiff = getAttributesDiff(currentGroup.oldAttrs, currentGroup.newAttrs); } else { result.text = currentGroup.text; - result.runAttrs = JSON.parse(currentGroup.runAttrs); + result.runAttrs = currentGroup.runAttrs; } grouped.push(result); @@ -351,11 +349,11 @@ function canExtendGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolve } if (group.action === 'modified' && diff.action === 'modified') { - if (group.oldAttrs !== diff.oldAttrs || group.newAttrs !== diff.newAttrs) { + if (!areInlineAttrsEqual(group.oldAttrs, diff.oldAttrs) || !areInlineAttrsEqual(group.newAttrs, diff.newAttrs)) { return false; } } else if (group.action !== 'modified' && diff.action !== 'modified') { - if (group.runAttrs !== diff.runAttrs) { + if (!areInlineAttrsEqual(group.runAttrs, diff.runAttrs)) { return false; } } else { @@ -367,3 +365,7 @@ function canExtendGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolve } return (group.endPos ?? 0) + 1 === positionResolver(diff.idx); } + +function areInlineAttrsEqual(a: Record | undefined, b: Record | undefined): boolean { + return !getAttributesDiff(a ?? {}, b ?? {}); +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index 5f508e44ed..b4ef6d3345 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -9,8 +9,7 @@ import { canTreatAsModification, } from './paragraph-diffing.ts'; -const buildRuns = (text, attrs = {}) => - text.split('').map((char) => ({ char, runAttrs: JSON.stringify(attrs), kind: 'text' })); +const buildRuns = (text, attrs = {}) => text.split('').map((char) => ({ char, runAttrs: attrs, kind: 'text' })); const createParagraphNode = (overrides = {}) => ({ type: { name: 'paragraph', ...(overrides.type || {}) }, diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 8a2e2fdbec..fd5508c7d4 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -132,7 +132,7 @@ export function getParagraphContent(paragraph: PMNode, paragraphPos = 0): Paragr const chars = nodeText.split('').map((char) => ({ kind: 'text', char, - runAttrs: JSON.stringify(runAttrs), + runAttrs, })); content.push(...(chars as ParagraphContentToken[])); return; From 812230963b1310b5a02781d8a0ee011b32db2b9f Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 12:30:20 -0300 Subject: [PATCH 034/125] fix: include node type when extracting content from paragraph --- .../src/extensions/diffing/algorithm/paragraph-diffing.test.js | 1 + .../src/extensions/diffing/algorithm/paragraph-diffing.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index b4ef6d3345..a243fc53c4 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -157,6 +157,7 @@ describe('getParagraphContent', () => { spec: {}, }, }, + nodeType: 'tab', }); expect(result.text.slice(1)).toEqual(buildRuns('Text', { bold: false })); expect(result.resolvePosition(0)).toBe(1); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index fd5508c7d4..84b2c11604 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -144,6 +144,7 @@ export function getParagraphContent(paragraph: PMNode, paragraphPos = 0): Paragr content.push({ kind: 'inlineNode', node, + nodeType: node.type.name, }); segments.push({ start, end, pos }); } From 850ec91b20ec6cc39b35c349df1c84b5cffd2cf1 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 12:40:10 -0300 Subject: [PATCH 035/125] refactor: include JSON nodes instead of PM nodes in diffs --- .../diffing/algorithm/generic-diffing.ts | 18 ++++--- .../diffing/algorithm/inline-diffing.test.js | 5 +- .../diffing/algorithm/inline-diffing.ts | 34 +++++++------ .../algorithm/paragraph-diffing.test.js | 50 +++++++++++-------- .../diffing/algorithm/paragraph-diffing.ts | 10 ++-- .../extensions/diffing/computeDiff.test.js | 17 ++++++- 6 files changed, 82 insertions(+), 52 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 9e62aec494..d377b956d0 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -14,6 +14,8 @@ import { import { diffSequences, reorderDiffOperations } from './sequence-diffing.ts'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; +type NodeJSON = ReturnType; + /** * Minimal node metadata extracted during document traversal. */ @@ -38,7 +40,7 @@ type NodeInfo = BaseNodeInfo | ParagraphNodeInfo; interface NonParagraphAddedDiff { action: 'added'; nodeType: string; - node: PMNode; + nodeJSON: NodeJSON; pos: number; } @@ -48,7 +50,7 @@ interface NonParagraphAddedDiff { interface NonParagraphDeletedDiff { action: 'deleted'; nodeType: string; - node: PMNode; + nodeJSON: NodeJSON; pos: number; } @@ -58,8 +60,8 @@ interface NonParagraphDeletedDiff { interface NonParagraphModifiedDiff { action: 'modified'; nodeType: string; - oldNode: PMNode; - newNode: PMNode; + oldNodeJSON: NodeJSON; + newNodeJSON: NodeJSON; pos: number; attrsDiff: AttributesDiff; } @@ -198,7 +200,7 @@ function buildAddedDiff( return { action: 'added', nodeType: nodeInfo.node.type.name, - node: nodeInfo.node, + nodeJSON: nodeInfo.node.toJSON(), pos, }; } @@ -220,7 +222,7 @@ function buildDeletedDiff(nodeInfo: NodeInfo, deletedNodesSet: Set): Nod return { action: 'deleted', nodeType: nodeInfo.node.type.name, - node: nodeInfo.node, + nodeJSON: nodeInfo.node.toJSON(), pos: nodeInfo.pos, }; } @@ -241,8 +243,8 @@ function buildModifiedDiff(oldNodeInfo: NodeInfo, newNodeInfo: NodeInfo): NodeDi return { action: 'modified', nodeType: oldNodeInfo.node.type.name, - oldNode: oldNodeInfo.node, - newNode: newNodeInfo.node, + oldNodeJSON: oldNodeInfo.node.toJSON(), + newNodeJSON: newNodeInfo.node.toJSON(), pos: oldNodeInfo.pos, attrsDiff, }; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index df82545ab2..5aa423c875 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -20,6 +20,7 @@ const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }) => { attrs: nodeAttrs, toJSON: () => ({ type: 'link', attrs: nodeAttrs }), }, + nodeJSON: { type: 'link', attrs: nodeAttrs }, }; }; @@ -136,8 +137,8 @@ describe('getInlineDiff', () => { nodeType: 'link', startPos: 3, endPos: 3, - oldNode: oldNode.node, - newNode: newNode.node, + oldNodeJSON: oldNode.nodeJSON, + newNodeJSON: newNode.nodeJSON, attrsDiff: { added: {}, deleted: {}, diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index caac098077..b479e2d48b 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -2,6 +2,8 @@ import type { Node as PMNode } from 'prosemirror-model'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; import { diffSequences } from './sequence-diffing.ts'; +type NodeJSON = ReturnType; + /** * Supported diff operations for inline changes. */ @@ -24,6 +26,7 @@ export type InlineNodeToken = { node: PMNode; nodeType?: string; toJSON?: () => unknown; + nodeJSON?: NodeJSON; }; /** @@ -60,18 +63,17 @@ type RawInlineNodeDiff = action: Exclude; idx: number; kind: 'inlineNode'; - node: PMNode; + nodeJSON: NodeJSON; nodeType?: string; } | { action: 'modified'; idx: number; kind: 'inlineNode'; - oldNode: PMNode; - newNode: PMNode; nodeType?: string; - oldAttrs?: Record; - newAttrs?: Record; + oldNodeJSON: NodeJSON; + newNodeJSON: NodeJSON; + attrsDiff: AttributesDiff | null; }; /** @@ -97,10 +99,10 @@ export interface InlineDiffResult { newText?: string; runAttrs?: Record; runAttrsDiff?: AttributesDiff | null; - node?: PMNode; nodeType?: string; - oldNode?: PMNode; - newNode?: PMNode; + nodeJSON?: NodeJSON; + oldNodeJSON?: NodeJSON; + newNodeJSON?: NodeJSON; attrsDiff?: AttributesDiff | null; } @@ -123,7 +125,7 @@ export function getInlineDiff( action, idx: oldIdx, kind: 'inlineNode', - node: token.node, + nodeJSON: token.nodeJSON ?? token.node.toJSON(), nodeType: token.nodeType, }; } @@ -145,13 +147,15 @@ export function getInlineDiff( buildDeleted: (token, oldIdx) => buildInlineDiff('deleted', token, oldIdx), buildModified: (oldToken, newToken, oldIdx) => { if (oldToken.kind !== 'text' && newToken.kind !== 'text') { + const attrsDiff = getAttributesDiff(oldToken.node.attrs, newToken.node.attrs); return { action: 'modified', idx: oldIdx, kind: 'inlineNode', - oldNode: oldToken.node, - newNode: newToken.node, + oldNodeJSON: oldToken.node.toJSON(), + newNodeJSON: newToken.node.toJSON(), nodeType: oldToken.nodeType, + attrsDiff, }; } if (oldToken.kind === 'text' && newToken.kind === 'text') { @@ -276,11 +280,11 @@ function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): In nodeType: diff.nodeType, ...(diff.action === 'modified' ? { - oldNode: diff.oldNode, - newNode: diff.newNode, - attrsDiff: getAttributesDiff(diff.oldNode.attrs, diff.newNode.attrs), + oldNodeJSON: diff.oldNodeJSON, + newNodeJSON: diff.newNodeJSON, + attrsDiff: diff.attrsDiff ?? null, } - : { node: diff.node }), + : { nodeJSON: diff.nodeJSON }), }); continue; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index a243fc53c4..c9a6b852c5 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -11,12 +11,18 @@ import { const buildRuns = (text, attrs = {}) => text.split('').map((char) => ({ char, runAttrs: attrs, kind: 'text' })); -const createParagraphNode = (overrides = {}) => ({ - type: { name: 'paragraph', ...(overrides.type || {}) }, - attrs: {}, - nodeSize: 5, - ...overrides, -}); +const createParagraphNode = (overrides = {}) => { + const node = { + type: { name: 'paragraph', ...(overrides.type || {}) }, + attrs: {}, + nodeSize: 5, + ...overrides, + }; + if (typeof node.toJSON !== 'function') { + node.toJSON = () => ({ type: node.type.name, attrs: node.attrs }); + } + return node; +}; const createParagraphInfo = (overrides = {}) => { const fullText = overrides.fullText ?? 'text'; @@ -45,6 +51,12 @@ const createParagraphWithSegments = (segments, contentSize) => { typeName: segment.inlineNode.typeName ?? 'inline', attrs: segment.inlineNode.attrs ?? {}, isLeaf: segment.inlineNode.isLeaf ?? true, + toJSON: + segment.inlineNode.toJSON ?? + (() => ({ + type: segment.inlineNode.typeName ?? 'inline', + attrs: segment.inlineNode.attrs ?? {}, + })), }, }; } @@ -82,6 +94,10 @@ const createParagraphWithSegments = (segments, contentSize) => { isLeaf: segment.inlineNode.isLeaf, type: { name: segment.inlineNode.typeName, spec: {} }, attrs: segment.inlineNode.attrs, + toJSON: () => ({ + type: segment.inlineNode.typeName, + attrs: segment.inlineNode.attrs, + }), }, segment.start, ); @@ -143,21 +159,13 @@ describe('getParagraphContent', () => { ]); const result = getParagraphContent(mockParagraph); - expect(result.text[0]).toEqual({ + expect(result.text[0]).toMatchObject({ kind: 'inlineNode', - node: { - attrs: { - kind: 'tab', - width: 120, - }, - isInline: true, - isLeaf: true, - type: { - name: 'tab', - spec: {}, - }, - }, nodeType: 'tab', + nodeJSON: { + type: 'tab', + attrs: inlineAttrs, + }, }); expect(result.text.slice(1)).toEqual(buildRuns('Text', { bold: false })); expect(result.resolvePosition(0)).toBe(1); @@ -224,7 +232,7 @@ describe('paragraph diff builders', () => { expect(buildAddedParagraphDiff(paragraph, previousNode)).toEqual({ action: 'added', nodeType: 'paragraph', - node: paragraph.node, + nodeJSON: paragraph.node.toJSON(), text: 'Hello', pos: 14, }); @@ -236,7 +244,7 @@ describe('paragraph diff builders', () => { expect(buildDeletedParagraphDiff(paragraph)).toEqual({ action: 'deleted', nodeType: 'paragraph', - node: paragraph.node, + nodeJSON: paragraph.node.toJSON(), oldText: 'Old text', pos: 7, }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 84b2c11604..fdb81100ce 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -3,6 +3,7 @@ import { getInlineDiff, type InlineDiffToken, type InlineDiffResult } from './in import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; import { levenshteinDistance } from './similarity.ts'; +type NodeJSON = ReturnType; // Heuristics that prevent unrelated paragraphs from being paired as modifications. const SIMILARITY_THRESHOLD = 0.65; const MIN_LENGTH_FOR_SIMILARITY = 4; @@ -63,7 +64,7 @@ export interface ParagraphResolvedSnapshot extends ParagraphSnapshot { export interface AddedParagraphDiff { action: 'added'; nodeType: string; - node: PMNode; + nodeJSON: NodeJSON; text: string; pos: number; } @@ -74,7 +75,7 @@ export interface AddedParagraphDiff { export interface DeletedParagraphDiff { action: 'deleted'; nodeType: string; - node: PMNode; + nodeJSON: NodeJSON; oldText: string; pos: number; } @@ -145,6 +146,7 @@ export function getParagraphContent(paragraph: PMNode, paragraphPos = 0): Paragr kind: 'inlineNode', node, nodeType: node.type.name, + nodeJSON: node.toJSON(), }); segments.push({ start, end, pos }); } @@ -213,7 +215,7 @@ export function buildAddedParagraphDiff( return { action: 'added', nodeType: paragraph.node.type.name, - node: paragraph.node, + nodeJSON: paragraph.node.toJSON(), text: paragraph.fullText, pos, }; @@ -226,7 +228,7 @@ export function buildDeletedParagraphDiff(paragraph: ParagraphSnapshot): Deleted return { action: 'deleted', nodeType: paragraph.node.type.name, - node: paragraph.node, + nodeJSON: paragraph.node.toJSON(), oldText: paragraph.fullText, pos: paragraph.pos, }; diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index df75d6b894..f8c28db8d1 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -24,6 +24,19 @@ const getDocument = async (name) => { return editor.state.doc; }; +const getNodeTextContent = (nodeJSON) => { + if (!nodeJSON) { + return ''; + } + if (typeof nodeJSON.text === 'string') { + return nodeJSON.text; + } + if (Array.isArray(nodeJSON.content)) { + return nodeJSON.content.map((child) => getNodeTextContent(child)).join(''); + } + return ''; +}; + describe('Diff', () => { it('Compares two documents and identifies added, deleted, and modified paragraphs', async () => { const docBefore = await getDocument('diff_before.docx'); @@ -230,12 +243,12 @@ describe('Diff', () => { expect(wordRemoval?.contentDiff?.[0].action).toBe('deleted'); const tableModification = diffs.find( - (diff) => diff.action === 'modified' && diff.nodeType === 'table' && diff.oldNode, + (diff) => diff.action === 'modified' && diff.nodeType === 'table' && diff.oldNodeJSON, ); expect(tableModification).toBeUndefined(); const tableAddition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'table'); - expect(tableAddition?.node?.textContent?.trim()).toBe('New table'); + expect(getNodeTextContent(tableAddition?.nodeJSON)?.trim()).toBe('New table'); const trailingParagraph = diffs.find( (diff) => diff.action === 'added' && diff.nodeType === 'paragraph' && diff.text === '', From 7bc693d3e68f99d0c9005e283acdf403019cf6ee Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 13:13:13 -0300 Subject: [PATCH 036/125] refactor: simplify typescript interfaces --- .../diffing/algorithm/generic-diffing.ts | 47 ++----- .../algorithm/paragraph-diffing.test.js | 23 ++-- .../diffing/algorithm/paragraph-diffing.ts | 123 ++++++++---------- 3 files changed, 83 insertions(+), 110 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index d377b956d0..e441b7c87b 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -1,15 +1,14 @@ import type { Node as PMNode } from 'prosemirror-model'; import { - getParagraphContent, + createParagraphSnapshot, paragraphComparator, canTreatAsModification as canTreatParagraphDeletionInsertionAsModification, shouldProcessEqualAsModification as shouldProcessEqualParagraphsAsModification, buildAddedParagraphDiff, buildDeletedParagraphDiff, buildModifiedParagraphDiff, - type ParagraphContentToken, type ParagraphDiff, - type ParagraphResolvedSnapshot, + type ParagraphNodeInfo, } from './paragraph-diffing.ts'; import { diffSequences, reorderDiffOperations } from './sequence-diffing.ts'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; @@ -25,51 +24,44 @@ type BaseNodeInfo = { depth: number; }; -/** - * Paragraph-specific node info enriched with textual content and resolvers. - */ -type ParagraphNodeInfo = ParagraphResolvedSnapshot; /** * Union describing every node processed by the generic diff. */ type NodeInfo = BaseNodeInfo | ParagraphNodeInfo; +interface NodeDiffBase { + action: Action; + nodeType: string; + pos: number; +} + /** * Diff payload describing an inserted non-paragraph node. */ -interface NonParagraphAddedDiff { - action: 'added'; - nodeType: string; +interface NodeAddedDiff extends NodeDiffBase<'added'> { nodeJSON: NodeJSON; - pos: number; } /** * Diff payload describing a deleted non-paragraph node. */ -interface NonParagraphDeletedDiff { - action: 'deleted'; - nodeType: string; +interface NodeDeletedDiff extends NodeDiffBase<'deleted'> { nodeJSON: NodeJSON; - pos: number; } /** * Diff payload describing an attribute-only change on non-paragraph nodes. */ -interface NonParagraphModifiedDiff { - action: 'modified'; - nodeType: string; +interface NodeModifiedDiff extends NodeDiffBase<'modified'> { oldNodeJSON: NodeJSON; newNodeJSON: NodeJSON; - pos: number; attrsDiff: AttributesDiff; } /** * Union of every diff type emitted by the generic diffing layer. */ -export type NodeDiff = ParagraphDiff | NonParagraphAddedDiff | NonParagraphDeletedDiff | NonParagraphModifiedDiff; +export type NodeDiff = ParagraphDiff | NodeAddedDiff | NodeDeletedDiff | NodeModifiedDiff; /** * Produces a sequence diff between two ProseMirror documents, flattening paragraphs for inline-aware comparisons. @@ -105,16 +97,7 @@ function normalizeNodes(pmDoc: PMNode): NodeInfo[] { const depth = parentDepth + 1; depthMap.set(node, depth); if (node.type.name === 'paragraph') { - const { text, resolvePosition } = getParagraphContent(node, pos); - const fullText = getFullText(text); - nodes.push({ - node, - depth, - pos, - text, - resolvePosition, - fullText, - }); + nodes.push(createParagraphSnapshot(node, pos, depth)); return false; } nodes.push({ node, pos, depth }); @@ -123,10 +106,6 @@ function normalizeNodes(pmDoc: PMNode): NodeInfo[] { return nodes; } -function getFullText(tokens: ParagraphContentToken[]): string { - return tokens.map((token) => (token.kind === 'text' ? token.char : '')).join(''); -} - /** * Compares two node infos to determine if they correspond to the same logical node. * Paragraphs are compared with `paragraphComparator`, while other nodes are matched by type name. diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index c9a6b852c5..f460f8f6f9 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import { - getParagraphContent, + createParagraphSnapshot, shouldProcessEqualAsModification, paragraphComparator, buildAddedParagraphDiff, @@ -31,6 +31,7 @@ const createParagraphInfo = (overrides = {}) => { return { node: createParagraphNode(overrides.node), pos: 0, + depth: 0, fullText, text: textTokens, resolvePosition: (idx) => idx, @@ -108,11 +109,11 @@ const createParagraphWithSegments = (segments, contentSize) => { }; }; -describe('getParagraphContent', () => { +describe('createParagraphSnapshot', () => { it('handles basic text nodes', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); - const result = getParagraphContent(mockParagraph); + const result = createParagraphSnapshot(mockParagraph, 0, 0); expect(result.text).toEqual(buildRuns('Hello', { bold: true })); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(4)).toBe(5); @@ -124,7 +125,7 @@ describe('getParagraphContent', () => { 4, ); - const result = getParagraphContent(mockParagraph); + const result = createParagraphSnapshot(mockParagraph, 0, 0); expect(result.text).toEqual(buildRuns('Leaf', { type: 'leaf' })); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(3)).toBe(4); @@ -136,7 +137,7 @@ describe('getParagraphContent', () => { { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, ]); - const result = getParagraphContent(mockParagraph); + const result = createParagraphSnapshot(mockParagraph, 0, 0); expect(result.text).toEqual([...buildRuns('Hello', { bold: true }), ...buildRuns('Leaf', { italic: true })]); expect(result.resolvePosition(0)).toBe(1); expect(result.resolvePosition(5)).toBe(6); @@ -146,7 +147,7 @@ describe('getParagraphContent', () => { it('handles empty content', () => { const mockParagraph = createParagraphWithSegments([], 0); - const result = getParagraphContent(mockParagraph); + const result = createParagraphSnapshot(mockParagraph, 0, 0); expect(result.text).toEqual([]); expect(result.resolvePosition(0)).toBe(1); }); @@ -158,7 +159,7 @@ describe('getParagraphContent', () => { { text: 'Text', start: 1, attrs: { bold: false } }, ]); - const result = getParagraphContent(mockParagraph); + const result = createParagraphSnapshot(mockParagraph, 0, 0); expect(result.text[0]).toMatchObject({ kind: 'inlineNode', nodeType: 'tab', @@ -175,7 +176,7 @@ describe('getParagraphContent', () => { it('applies paragraph position offsets to the resolver', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); - const result = getParagraphContent(mockParagraph, 10); + const result = createParagraphSnapshot(mockParagraph, 10, 0); expect(result.text).toEqual(buildRuns('Nested', {})); expect(result.resolvePosition(0)).toBe(11); expect(result.resolvePosition(6)).toBe(17); @@ -183,7 +184,7 @@ describe('getParagraphContent', () => { it('returns null when index is outside the flattened text array', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Hi', start: 0 }], 2); - const { resolvePosition } = getParagraphContent(mockParagraph); + const { resolvePosition } = createParagraphSnapshot(mockParagraph, 0, 0); expect(resolvePosition(-1)).toBeNull(); expect(resolvePosition(3)).toBeNull(); @@ -227,7 +228,7 @@ describe('paragraph diff builders', () => { node: createParagraphNode({ type: { name: 'paragraph' } }), fullText: 'Hello', }); - const previousNode = { pos: 10, node: { nodeSize: 4 } }; + const previousNode = { pos: 10, depth: 0, node: { nodeSize: 4 } }; expect(buildAddedParagraphDiff(paragraph, previousNode)).toEqual({ action: 'added', @@ -269,6 +270,7 @@ describe('paragraph diff builders', () => { expect(diff).toMatchObject({ action: 'modified', nodeType: 'paragraph', + nodeJSON: oldParagraph.node.toJSON(), oldText: 'foo', newText: 'bar', pos: 5, @@ -298,6 +300,7 @@ describe('paragraph diff builders', () => { expect(diff).not.toBeNull(); expect(diff.contentDiff).toEqual([]); expect(diff.attrsDiff?.modified).toHaveProperty('align'); + expect(diff.nodeJSON).toEqual(oldParagraph.node.toJSON()); }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index fdb81100ce..4fc1a543f1 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -3,95 +3,62 @@ import { getInlineDiff, type InlineDiffToken, type InlineDiffResult } from './in import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; import { levenshteinDistance } from './similarity.ts'; -type NodeJSON = ReturnType; // Heuristics that prevent unrelated paragraphs from being paired as modifications. const SIMILARITY_THRESHOLD = 0.65; const MIN_LENGTH_FOR_SIMILARITY = 4; -/** - * Flattened token emitted from a paragraph. Delegates to inline diff tokens. - */ -export type ParagraphContentToken = InlineDiffToken; +type NodeJSON = ReturnType; + /** * Maps flattened indexes back to the ProseMirror document. */ export type PositionResolver = (index: number) => number | null; /** - * Internal bookkeeping entry that remembers the start/end indexes for shallow nodes. + * Rich snapshot of a paragraph node with flattened content and helpers. */ -interface ParagraphSegment { - start: number; - end: number; - pos: number; -} - -/** - * Computed textual representation of a paragraph plus its index resolver. - */ -export interface ParagraphContent { - text: ParagraphContentToken[]; - resolvePosition: PositionResolver; -} - -/** - * Bare reference to a paragraph node and its document position. - */ -export interface ParagraphNodeReference { +export interface ParagraphNodeInfo { node: PMNode; pos: number; depth: number; -} - -/** - * Snapshot of a paragraph that includes its flattened text form. - */ -export interface ParagraphSnapshot extends ParagraphNodeReference { + text: InlineDiffToken[]; + resolvePosition: PositionResolver; fullText: string; } /** - * Paragraph snapshot extended with the tokenized content and resolver. + * Base shape shared by every paragraph diff payload. */ -export interface ParagraphResolvedSnapshot extends ParagraphSnapshot { - text: ParagraphContentToken[]; - resolvePosition: PositionResolver; +interface ParagraphDiffBase { + action: Action; + nodeType: string; + nodeJSON: NodeJSON; + pos: number; } /** * Diff payload produced when a paragraph is inserted. */ -export interface AddedParagraphDiff { - action: 'added'; - nodeType: string; - nodeJSON: NodeJSON; +export type AddedParagraphDiff = ParagraphDiffBase<'added'> & { text: string; - pos: number; -} +}; /** * Diff payload produced when a paragraph is deleted. */ -export interface DeletedParagraphDiff { - action: 'deleted'; - nodeType: string; - nodeJSON: NodeJSON; +export type DeletedParagraphDiff = ParagraphDiffBase<'deleted'> & { oldText: string; - pos: number; -} +}; /** * Diff payload emitted when a paragraph changes, including inline edits. */ -export interface ModifiedParagraphDiff { - action: 'modified'; - nodeType: string; +export type ModifiedParagraphDiff = ParagraphDiffBase<'modified'> & { oldText: string; newText: string; - pos: number; contentDiff: InlineDiffResult[]; attrsDiff: AttributesDiff | null; -} +}; /** * Union of every diff variant the paragraph diffing logic can produce. @@ -99,15 +66,38 @@ export interface ModifiedParagraphDiff { export type ParagraphDiff = AddedParagraphDiff | DeletedParagraphDiff | ModifiedParagraphDiff; /** - * Flattens a paragraph node into text and provides a resolver to map string indices back to document positions. + * Creates a reusable snapshot that stores flattened paragraph content plus position metadata. * * @param paragraph Paragraph node to flatten. * @param paragraphPos Position of the paragraph in the document. - * @returns Concatenated text tokens and a resolver that maps indexes to document positions. + * @param depth Depth of the paragraph within the document tree. + * @returns Snapshot containing tokens, resolver, and derived metadata. + */ +export function createParagraphSnapshot(paragraph: PMNode, paragraphPos: number, depth: number): ParagraphNodeInfo { + const { text, resolvePosition } = buildParagraphContent(paragraph, paragraphPos); + return { + node: paragraph, + pos: paragraphPos, + depth, + text, + resolvePosition, + fullText: text.map((token) => (token.kind === 'text' ? token.char : '')).join(''), + }; +} + +/** + * Flattens a paragraph node into inline diff tokens and a resolver that tracks document positions. + * + * @param paragraph Paragraph node being tokenized. + * @param paragraphPos Absolute document position for the paragraph; used to offset resolver results. + * @returns Flattened tokens plus a resolver that maps token indexes back to document positions. */ -export function getParagraphContent(paragraph: PMNode, paragraphPos = 0): ParagraphContent { - const content: ParagraphContentToken[] = []; - const segments: ParagraphSegment[] = []; +function buildParagraphContent( + paragraph: PMNode, + paragraphPos = 0, +): { text: InlineDiffToken[]; resolvePosition: PositionResolver } { + const content: InlineDiffToken[] = []; + const segments: Array<{ start: number; end: number; pos: number }> = []; paragraph.nodesBetween( 0, @@ -135,7 +125,7 @@ export function getParagraphContent(paragraph: PMNode, paragraphPos = 0): Paragr char, runAttrs, })); - content.push(...(chars as ParagraphContentToken[])); + content.push(...(chars as InlineDiffToken[])); return; } @@ -179,8 +169,8 @@ export function getParagraphContent(paragraph: PMNode, paragraphPos = 0): Paragr * @returns True when the serialized JSON payload differs. */ export function shouldProcessEqualAsModification( - oldParagraph: ParagraphNodeReference, - newParagraph: ParagraphNodeReference, + oldParagraph: ParagraphNodeInfo, + newParagraph: ParagraphNodeInfo, ): boolean { return JSON.stringify(oldParagraph.node.toJSON()) !== JSON.stringify(newParagraph.node.toJSON()); } @@ -188,7 +178,7 @@ export function shouldProcessEqualAsModification( /** * Compares two paragraphs for identity based on paraId or text content. */ -export function paragraphComparator(oldParagraph: ParagraphSnapshot, newParagraph: ParagraphSnapshot): boolean { +export function paragraphComparator(oldParagraph: ParagraphNodeInfo, newParagraph: ParagraphNodeInfo): boolean { const oldId = oldParagraph?.node?.attrs?.paraId; const newId = newParagraph?.node?.attrs?.paraId; if (oldId && newId && oldId === newId) { @@ -201,8 +191,8 @@ export function paragraphComparator(oldParagraph: ParagraphSnapshot, newParagrap * Builds a normalized payload describing a paragraph addition, ensuring all consumers receive the same metadata shape. */ export function buildAddedParagraphDiff( - paragraph: ParagraphSnapshot, - previousOldNodeInfo?: ParagraphNodeReference, + paragraph: ParagraphNodeInfo, + previousOldNodeInfo?: Pick, ): AddedParagraphDiff { let pos; if (paragraph.depth === previousOldNodeInfo?.depth) { @@ -224,7 +214,7 @@ export function buildAddedParagraphDiff( /** * Builds a normalized payload describing a paragraph deletion so diff consumers can show removals with all context. */ -export function buildDeletedParagraphDiff(paragraph: ParagraphSnapshot): DeletedParagraphDiff { +export function buildDeletedParagraphDiff(paragraph: ParagraphNodeInfo): DeletedParagraphDiff { return { action: 'deleted', nodeType: paragraph.node.type.name, @@ -238,8 +228,8 @@ export function buildDeletedParagraphDiff(paragraph: ParagraphSnapshot): Deleted * Builds the payload for a paragraph modification, including text-level diffs, so renderers can highlight edits inline. */ export function buildModifiedParagraphDiff( - oldParagraph: ParagraphResolvedSnapshot, - newParagraph: ParagraphResolvedSnapshot, + oldParagraph: ParagraphNodeInfo, + newParagraph: ParagraphNodeInfo, ): ModifiedParagraphDiff | null { const contentDiff = getInlineDiff(oldParagraph.text, newParagraph.text, oldParagraph.resolvePosition); @@ -251,6 +241,7 @@ export function buildModifiedParagraphDiff( return { action: 'modified', nodeType: oldParagraph.node.type.name, + nodeJSON: oldParagraph.node.toJSON(), oldText: oldParagraph.fullText, newText: newParagraph.fullText, pos: oldParagraph.pos, @@ -262,7 +253,7 @@ export function buildModifiedParagraphDiff( /** * Decides whether a delete/insert pair should be reinterpreted as a modification to minimize noisy diff output. */ -export function canTreatAsModification(oldParagraph: ParagraphSnapshot, newParagraph: ParagraphSnapshot): boolean { +export function canTreatAsModification(oldParagraph: ParagraphNodeInfo, newParagraph: ParagraphNodeInfo): boolean { if (paragraphComparator(oldParagraph, newParagraph)) { return true; } From 7c3a48c27f64e9ed362d3a1f961471d255347977 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 13:30:40 -0300 Subject: [PATCH 037/125] refactor: extract insertion position calculation logic into helper --- .../diffing/algorithm/diff-utils.test.ts | 29 +++++++++++++++++++ .../diffing/algorithm/diff-utils.ts | 27 +++++++++++++++++ .../diffing/algorithm/generic-diffing.ts | 11 ++----- .../diffing/algorithm/paragraph-diffing.ts | 11 ++----- 4 files changed, 60 insertions(+), 18 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts diff --git a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts new file mode 100644 index 0000000000..63ef88bc21 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts @@ -0,0 +1,29 @@ +import { describe, it, expect } from 'vitest'; +import { getInsertionPos } from './diff-utils.ts'; + +const createNodeInfo = ({ pos = 0, depth = 0, nodeSize = 1 } = {}) => ({ + pos, + depth, + node: { nodeSize }, +}); + +describe('getInsertionPos', () => { + it('positions after previous node when depth matches', () => { + const previous = createNodeInfo({ pos: 10, depth: 2, nodeSize: 5 }); + expect(getInsertionPos(2, previous)).toBe(15); + }); + + it('falls back to previous position plus one when depth differs', () => { + const previous = createNodeInfo({ pos: 10, depth: 1, nodeSize: 3 }); + expect(getInsertionPos(2, previous)).toBe(11); + }); + + it('returns zero when there is no previous node info', () => { + expect(getInsertionPos(0, undefined)).toBe(0); + }); + + it('handles previous nodes lacking nodeSize safely', () => { + const previous = { pos: 5, depth: 1, node: {} } as any; + expect(getInsertionPos(1, previous)).toBe(5); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts new file mode 100644 index 0000000000..3d92e934f1 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts @@ -0,0 +1,27 @@ +import type { Node as PMNode } from 'prosemirror-model'; + +interface NodePositionInfo { + node: PMNode; + pos: number; + depth: number; +} + +/** + * Computes the insertion point for a node relative to the previous node in the old document tree. + * + * When the previous node shares the same depth, the insertion + * is placed right after the previous node's position. Otherwise, the insertion + * is placed just after the previous node's opening position. + * + * @param currentDepth Depth of the node being inserted. + * @param previousNode Optional info about the preceding node from the old document. + * @returns Absolute document position where the new node should be inserted. + */ +export function getInsertionPos(currentDepth: number, previousNode?: NodePositionInfo): number { + if (currentDepth === previousNode?.depth) { + const previousPos = previousNode?.pos ?? -1; + const previousSize = previousNode?.node.nodeSize ?? 0; + return previousPos >= 0 ? previousPos + previousSize : 0; + } + return (previousNode?.pos ?? -1) + 1; +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index e441b7c87b..415193d788 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -12,6 +12,7 @@ import { } from './paragraph-diffing.ts'; import { diffSequences, reorderDiffOperations } from './sequence-diffing.ts'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; +import { getInsertionPos } from './diff-utils.ts'; type NodeJSON = ReturnType; @@ -168,19 +169,11 @@ function buildAddedDiff( addedNodesSet.add(childNode); }); - let pos; - if (nodeInfo.depth === previousOldNodeInfo?.depth) { - const previousPos = previousOldNodeInfo?.pos ?? -1; - const previousSize = previousOldNodeInfo?.node.nodeSize ?? 0; - pos = previousPos >= 0 ? previousPos + previousSize : 0; - } else { - pos = (previousOldNodeInfo?.pos ?? -1) + 1; - } return { action: 'added', nodeType: nodeInfo.node.type.name, nodeJSON: nodeInfo.node.toJSON(), - pos, + pos: getInsertionPos(nodeInfo.depth, previousOldNodeInfo), }; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 4fc1a543f1..0f15e1c6ba 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -1,6 +1,7 @@ import type { Node as PMNode } from 'prosemirror-model'; import { getInlineDiff, type InlineDiffToken, type InlineDiffResult } from './inline-diffing.ts'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; +import { getInsertionPos } from './diff-utils.ts'; import { levenshteinDistance } from './similarity.ts'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. @@ -194,20 +195,12 @@ export function buildAddedParagraphDiff( paragraph: ParagraphNodeInfo, previousOldNodeInfo?: Pick, ): AddedParagraphDiff { - let pos; - if (paragraph.depth === previousOldNodeInfo?.depth) { - const previousPos = previousOldNodeInfo?.pos ?? -1; - const previousSize = previousOldNodeInfo?.node.nodeSize ?? 0; - pos = previousPos >= 0 ? previousPos + previousSize : 0; - } else { - pos = (previousOldNodeInfo?.pos ?? -1) + 1; - } return { action: 'added', nodeType: paragraph.node.type.name, nodeJSON: paragraph.node.toJSON(), text: paragraph.fullText, - pos, + pos: getInsertionPos(paragraph.depth, previousOldNodeInfo), }; } From 9101539c6029e7fd4e9c466c973f8803dc8d5ade Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 13:43:21 -0300 Subject: [PATCH 038/125] refactor: simplify resolution of inline node positions --- .../diffing/algorithm/inline-diffing.test.js | 54 +++++----- .../diffing/algorithm/inline-diffing.ts | 98 ++++++++++++++----- .../algorithm/paragraph-diffing.test.js | 72 +++++++++----- .../diffing/algorithm/paragraph-diffing.ts | 69 ++++--------- 4 files changed, 168 insertions(+), 125 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index 5aa423c875..5287e0b5e5 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -7,10 +7,15 @@ vi.mock('./myers-diff.ts', async () => { }); import { getInlineDiff } from './inline-diffing.ts'; -const buildTextRuns = (text, runAttrs = {}) => - text.split('').map((char) => ({ char, runAttrs: { ...runAttrs }, kind: 'text' })); - -const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }) => { +const buildTextRuns = (text, runAttrs = {}, offsetStart = 0) => + text.split('').map((char, index) => ({ + char, + runAttrs: { ...runAttrs }, + kind: 'text', + offset: offsetStart + index, + })); + +const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }, pos = 0) => { const nodeAttrs = { ...attrs }; return { kind: 'inlineNode', @@ -21,22 +26,22 @@ const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }) => { toJSON: () => ({ type: 'link', attrs: nodeAttrs }), }, nodeJSON: { type: 'link', attrs: nodeAttrs }, + pos, }; }; describe('getInlineDiff', () => { it('returns an empty diff list when both strings are identical', () => { - const resolver = (index) => index; - const diffs = getInlineDiff(buildTextRuns('unchanged'), buildTextRuns('unchanged'), resolver); + const oldRuns = buildTextRuns('unchanged'); + const diffs = getInlineDiff(oldRuns, buildTextRuns('unchanged'), oldRuns.length); expect(diffs).toEqual([]); }); it('detects text insertions and maps them to resolver positions', () => { - const oldResolver = (index) => index + 10; - const newResolver = (index) => index + 100; - - const diffs = getInlineDiff(buildTextRuns('abc'), buildTextRuns('abXc'), oldResolver, newResolver); + const startOffset = 10; + const oldRuns = buildTextRuns('abc', {}, startOffset); + const diffs = getInlineDiff(oldRuns, buildTextRuns('abXc', {}, startOffset), startOffset + oldRuns.length); expect(diffs).toEqual([ { @@ -51,10 +56,9 @@ describe('getInlineDiff', () => { }); it('detects deletions and additions in the same diff sequence', () => { - const oldResolver = (index) => index + 5; - const newResolver = (index) => index + 20; - - const diffs = getInlineDiff(buildTextRuns('abcd'), buildTextRuns('abXYd'), oldResolver, newResolver); + const startOffset = 5; + const oldRuns = buildTextRuns('abcd', {}, startOffset); + const diffs = getInlineDiff(oldRuns, buildTextRuns('abXYd', {}, startOffset), startOffset + oldRuns.length); expect(diffs).toEqual([ { @@ -77,9 +81,8 @@ describe('getInlineDiff', () => { }); it('marks attribute-only changes as modifications and surfaces attribute diffs', () => { - const resolver = (index) => index; - - const diffs = getInlineDiff(buildTextRuns('a', { bold: true }), buildTextRuns('a', { italic: true }), resolver); + const oldRuns = buildTextRuns('a', { bold: true }, 0); + const diffs = getInlineDiff(oldRuns, buildTextRuns('a', { italic: true }), oldRuns.length); expect(diffs).toEqual([ { @@ -99,9 +102,13 @@ describe('getInlineDiff', () => { }); it('merges contiguous attribute edits that share the same diff metadata', () => { - const resolver = (index) => index + 5; - - const diffs = getInlineDiff(buildTextRuns('ab', { bold: true }), buildTextRuns('ab', { bold: false }), resolver); + const startOffset = 5; + const oldRuns = buildTextRuns('ab', { bold: true }, startOffset); + const diffs = getInlineDiff( + oldRuns, + buildTextRuns('ab', { bold: false }, startOffset), + startOffset + oldRuns.length, + ); expect(diffs).toEqual([ { @@ -123,12 +130,11 @@ describe('getInlineDiff', () => { }); it('surfaces attribute diffs for inline node modifications', () => { - const resolver = (index) => index + 3; const sharedType = { name: 'link' }; - const oldNode = buildInlineNodeToken({ href: 'https://old.example', label: 'Example' }, sharedType); - const newNode = buildInlineNodeToken({ href: 'https://new.example', label: 'Example' }, sharedType); + const oldNode = buildInlineNodeToken({ href: 'https://old.example', label: 'Example' }, sharedType, 3); + const newNode = buildInlineNodeToken({ href: 'https://new.example', label: 'Example' }, sharedType, 3); - const diffs = getInlineDiff([oldNode], [newNode], resolver); + const diffs = getInlineDiff([oldNode], [newNode], 4); expect(diffs).toEqual([ { diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index b479e2d48b..65ea43b513 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -16,6 +16,7 @@ export type InlineTextToken = { kind: 'text'; char: string; runAttrs: Record; + offset?: number | null; }; /** @@ -27,6 +28,7 @@ export type InlineNodeToken = { nodeType?: string; toJSON?: () => unknown; nodeJSON?: NodeJSON; + pos?: number | null; }; /** @@ -81,11 +83,6 @@ type RawInlineNodeDiff = */ type RawDiff = RawTextDiff | RawInlineNodeDiff; -/** - * Maps flattened string indexes back to ProseMirror document positions. - */ -type PositionResolver = (index: number) => number | null; - /** * Final grouped inline diff exposed to downstream consumers. */ @@ -109,15 +106,15 @@ export interface InlineDiffResult { /** * Computes text-level additions and deletions between two sequences using the generic sequence diff, mapping back to document positions. * - * @param oldContent Source tokens. + * @param oldContent Source tokens enriched with document offsets. * @param newContent Target tokens. - * @param oldPositionResolver Maps indexes to the original document. + * @param oldParagraphEndPos Absolute document position at the end of the old paragraph (used for trailing inserts). * @returns List of grouped inline diffs with document positions and text content. */ export function getInlineDiff( oldContent: InlineDiffToken[], newContent: InlineDiffToken[], - oldPositionResolver: PositionResolver, + oldParagraphEndPos: number, ): InlineDiffResult[] { const buildInlineDiff = (action: InlineAction, token: InlineDiffToken, oldIdx: number): RawDiff => { if (token.kind !== 'text') { @@ -173,7 +170,7 @@ export function getInlineDiff( }, }); - return groupDiffs(diffs, oldPositionResolver); + return groupDiffs(diffs, oldContent, oldParagraphEndPos); } /** @@ -235,13 +232,14 @@ type TextDiffGroup = }; /** - * Groups raw diff operations into contiguous ranges and converts serialized run attrs back to objects. + * Groups raw diff operations into contiguous ranges. * * @param diffs Raw diff operations from the sequence diff. - * @param oldPositionResolver Maps text indexes to original document positions. + * @param oldTokens Flattened tokens from the old paragraph, used to derive document positions. + * @param oldParagraphEndPos Absolute document position marking the paragraph boundary. * @returns Grouped inline diffs with start/end document positions. */ -function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): InlineDiffResult[] { +function groupDiffs(diffs: RawDiff[], oldTokens: InlineDiffToken[], oldParagraphEndPos: number): InlineDiffResult[] { const grouped: InlineDiffResult[] = []; let currentGroup: TextDiffGroup | null = null; @@ -275,8 +273,8 @@ function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): In grouped.push({ action: diff.action, kind: 'inlineNode', - startPos: oldPositionResolver(diff.idx), - endPos: oldPositionResolver(diff.idx), + startPos: resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos), + endPos: resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos), nodeType: diff.nodeType, ...(diff.action === 'modified' ? { @@ -289,11 +287,11 @@ function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): In continue; } - if (!currentGroup || !canExtendGroup(currentGroup, diff, oldPositionResolver)) { + if (!currentGroup || !canExtendGroup(currentGroup, diff, oldTokens, oldParagraphEndPos)) { pushCurrentGroup(); - currentGroup = createTextGroup(diff, oldPositionResolver); + currentGroup = createTextGroup(diff, oldTokens, oldParagraphEndPos); } else { - extendTextGroup(currentGroup, diff, oldPositionResolver); + extendTextGroup(currentGroup, diff, oldTokens, oldParagraphEndPos); } } @@ -304,14 +302,14 @@ function groupDiffs(diffs: RawDiff[], oldPositionResolver: PositionResolver): In /** * Builds a fresh text diff group seeded with the current diff token. */ -function createTextGroup(diff: RawTextDiff, positionResolver: PositionResolver): TextDiffGroup { +function createTextGroup(diff: RawTextDiff, oldTokens: InlineDiffToken[], oldParagraphEndPos: number): TextDiffGroup { const baseGroup = diff.action === 'modified' ? { action: diff.action, kind: 'text' as const, - startPos: positionResolver(diff.idx), - endPos: positionResolver(diff.idx), + startPos: resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos), + endPos: resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos), newText: diff.newText, oldText: diff.oldText, oldAttrs: diff.oldAttrs, @@ -320,8 +318,8 @@ function createTextGroup(diff: RawTextDiff, positionResolver: PositionResolver): : { action: diff.action, kind: 'text' as const, - startPos: positionResolver(diff.idx), - endPos: positionResolver(diff.idx), + startPos: resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos), + endPos: resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos), text: diff.text, runAttrs: diff.runAttrs, }; @@ -333,8 +331,13 @@ function createTextGroup(diff: RawTextDiff, positionResolver: PositionResolver): * Expands the current text group with the incoming diff token. * Keeps start/end positions updated while concatenating text payloads. */ -function extendTextGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolver: PositionResolver): void { - group.endPos = positionResolver(diff.idx); +function extendTextGroup( + group: TextDiffGroup, + diff: RawTextDiff, + oldTokens: InlineDiffToken[], + oldParagraphEndPos: number, +): void { + group.endPos = resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos); if (group.action === 'modified' && diff.action === 'modified') { group.newText += diff.newText; group.oldText += diff.oldText; @@ -347,7 +350,12 @@ function extendTextGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolv * Determines whether a text diff token can be merged into the current group. * Checks action, attributes, and adjacency constraints required by the grouping heuristic. */ -function canExtendGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolver: PositionResolver): boolean { +function canExtendGroup( + group: TextDiffGroup, + diff: RawTextDiff, + oldTokens: InlineDiffToken[], + oldParagraphEndPos: number, +): boolean { if (group.action !== diff.action) { return false; } @@ -364,12 +372,48 @@ function canExtendGroup(group: TextDiffGroup, diff: RawTextDiff, positionResolve return false; } + const diffPos = resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos); if (group.action === 'added') { - return group.startPos === positionResolver(diff.idx); + return group.startPos === diffPos; + } + if (diffPos == null || group.endPos == null) { + return false; } - return (group.endPos ?? 0) + 1 === positionResolver(diff.idx); + return group.endPos + 1 === diffPos; } +/** + * Maps a raw diff index back to an absolute document position using the original token offsets. + * + * @param tokens Flattened tokens from the old paragraph. + * @param idx Index provided by the Myers diff output. + * @param paragraphEndPos Absolute document position marking the paragraph boundary; used when idx equals the token length. + * @returns Document position or null when the index is outside the known ranges. + */ +function resolveTokenPosition(tokens: InlineDiffToken[], idx: number, paragraphEndPos: number): number | null { + if (idx < 0) { + return null; + } + const token = tokens[idx]; + if (token) { + if (token.kind === 'text') { + return token.offset ?? null; + } + return token.pos ?? null; + } + if (idx === tokens.length) { + return paragraphEndPos; + } + return null; +} + +/** + * Compares two sets of inline attributes and determines if they are equal. + * + * @param a - The first set of attributes to compare. + * @param b - The second set of attributes to compare. + * @returns `true` if the attributes are equal, `false` otherwise. + */ function areInlineAttrsEqual(a: Record | undefined, b: Record | undefined): boolean { return !getAttributesDiff(a ?? {}, b ?? {}); } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index f460f8f6f9..56f97bb126 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -26,15 +26,30 @@ const createParagraphNode = (overrides = {}) => { const createParagraphInfo = (overrides = {}) => { const fullText = overrides.fullText ?? 'text'; - const textTokens = overrides.text ?? buildRuns(fullText); + const paragraphPos = overrides.pos ?? 0; + const baseTokens = + overrides.text ?? + buildRuns(fullText).map((token, index) => ({ + ...token, + offset: paragraphPos + 1 + index, + })); + const textTokens = baseTokens.map((token, index) => { + if (token.kind === 'text' && token.offset == null) { + return { ...token, offset: paragraphPos + 1 + index }; + } + if (token.kind === 'inlineNode' && token.pos == null) { + return { ...token, pos: paragraphPos + 1 + index }; + } + return token; + }); return { node: createParagraphNode(overrides.node), - pos: 0, + pos: paragraphPos, depth: 0, fullText, text: textTokens, - resolvePosition: (idx) => idx, + endPos: overrides.endPos ?? paragraphPos + 1 + fullText.length, ...overrides, }; }; @@ -109,14 +124,19 @@ const createParagraphWithSegments = (segments, contentSize) => { }; }; +const stripOffsets = (tokens) => + tokens.map((token) => + token.kind === 'text' ? { kind: token.kind, char: token.char, runAttrs: token.runAttrs } : token, + ); + describe('createParagraphSnapshot', () => { it('handles basic text nodes', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(result.text).toEqual(buildRuns('Hello', { bold: true })); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(4)).toBe(5); + expect(stripOffsets(result.text)).toEqual(buildRuns('Hello', { bold: true })); + expect(result.text[0]?.offset).toBe(1); + expect(result.text[4]?.offset).toBe(5); }); it('handles leaf nodes with leafText', () => { @@ -126,9 +146,9 @@ describe('createParagraphSnapshot', () => { ); const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(result.text).toEqual(buildRuns('Leaf', { type: 'leaf' })); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(3)).toBe(4); + expect(stripOffsets(result.text)).toEqual(buildRuns('Leaf', { type: 'leaf' })); + expect(result.text[0]?.offset).toBe(1); + expect(result.text[3]?.offset).toBe(4); }); it('handles mixed content', () => { @@ -138,10 +158,14 @@ describe('createParagraphSnapshot', () => { ]); const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(result.text).toEqual([...buildRuns('Hello', { bold: true }), ...buildRuns('Leaf', { italic: true })]); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(5)).toBe(6); - expect(result.resolvePosition(9)).toBe(10); + expect(stripOffsets(result.text)).toEqual([ + ...buildRuns('Hello', { bold: true }), + ...buildRuns('Leaf', { italic: true }), + ]); + expect(result.text[0]?.offset).toBe(1); + expect(result.text[5]?.offset).toBe(6); + expect(result.text[result.text.length - 1]?.offset).toBe(9); + expect(result.endPos).toBe(10); }); it('handles empty content', () => { @@ -149,7 +173,7 @@ describe('createParagraphSnapshot', () => { const result = createParagraphSnapshot(mockParagraph, 0, 0); expect(result.text).toEqual([]); - expect(result.resolvePosition(0)).toBe(1); + expect(result.endPos).toBe(1); }); it('includes inline nodes that have no textual content', () => { @@ -167,28 +191,26 @@ describe('createParagraphSnapshot', () => { type: 'tab', attrs: inlineAttrs, }, + pos: 1, }); - expect(result.text.slice(1)).toEqual(buildRuns('Text', { bold: false })); - expect(result.resolvePosition(0)).toBe(1); - expect(result.resolvePosition(1)).toBe(2); + expect(stripOffsets(result.text.slice(1))).toEqual(buildRuns('Text', { bold: false })); + expect(result.text[1]?.offset).toBe(2); }); it('applies paragraph position offsets to the resolver', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); const result = createParagraphSnapshot(mockParagraph, 10, 0); - expect(result.text).toEqual(buildRuns('Nested', {})); - expect(result.resolvePosition(0)).toBe(11); - expect(result.resolvePosition(6)).toBe(17); + expect(stripOffsets(result.text)).toEqual(buildRuns('Nested', {})); + expect(result.text[0]?.offset).toBe(11); + expect(result.text[5]?.offset).toBe(16); + expect(result.endPos).toBe(17); }); it('returns null when index is outside the flattened text array', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Hi', start: 0 }], 2); - const { resolvePosition } = createParagraphSnapshot(mockParagraph, 0, 0); - - expect(resolvePosition(-1)).toBeNull(); - expect(resolvePosition(3)).toBeNull(); - expect(resolvePosition(2)).toBe(3); + const result = createParagraphSnapshot(mockParagraph, 0, 0); + expect(result.endPos).toBe(3); }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 0f15e1c6ba..688deada9e 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -10,20 +10,12 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; type NodeJSON = ReturnType; -/** - * Maps flattened indexes back to the ProseMirror document. - */ -export type PositionResolver = (index: number) => number | null; - -/** - * Rich snapshot of a paragraph node with flattened content and helpers. - */ export interface ParagraphNodeInfo { node: PMNode; pos: number; depth: number; text: InlineDiffToken[]; - resolvePosition: PositionResolver; + endPos: number; fullText: string; } @@ -72,34 +64,30 @@ export type ParagraphDiff = AddedParagraphDiff | DeletedParagraphDiff | Modified * @param paragraph Paragraph node to flatten. * @param paragraphPos Position of the paragraph in the document. * @param depth Depth of the paragraph within the document tree. - * @returns Snapshot containing tokens, resolver, and derived metadata. + * @returns Snapshot containing tokens (with offsets) and derived metadata. */ export function createParagraphSnapshot(paragraph: PMNode, paragraphPos: number, depth: number): ParagraphNodeInfo { - const { text, resolvePosition } = buildParagraphContent(paragraph, paragraphPos); + const text = buildParagraphContent(paragraph, paragraphPos); return { node: paragraph, pos: paragraphPos, depth, text, - resolvePosition, + endPos: paragraphPos + 1 + paragraph.content.size, fullText: text.map((token) => (token.kind === 'text' ? token.char : '')).join(''), }; } /** - * Flattens a paragraph node into inline diff tokens and a resolver that tracks document positions. + * Flattens a paragraph node into inline diff tokens, embedding absolute document offsets. * * @param paragraph Paragraph node being tokenized. * @param paragraphPos Absolute document position for the paragraph; used to offset resolver results. - * @returns Flattened tokens plus a resolver that maps token indexes back to document positions. + * @returns Flattened tokens enriched with document offsets. */ -function buildParagraphContent( - paragraph: PMNode, - paragraphPos = 0, -): { text: InlineDiffToken[]; resolvePosition: PositionResolver } { +function buildParagraphContent(paragraph: PMNode, paragraphPos = 0): InlineDiffToken[] { const content: InlineDiffToken[] = []; - const segments: Array<{ start: number; end: number; pos: number }> = []; - + const paragraphOffset = paragraphPos + 1; paragraph.nodesBetween( 0, paragraph.content.size, @@ -116,50 +104,33 @@ function buildParagraphContent( } if (nodeText) { - const start = content.length; - const end = start + nodeText.length; const runNode = paragraph.nodeAt(pos - 1); const runAttrs = runNode?.attrs ?? {}; - segments.push({ start, end, pos }); - const chars = nodeText.split('').map((char) => ({ - kind: 'text', - char, - runAttrs, - })); - content.push(...(chars as InlineDiffToken[])); + const baseOffset = paragraphOffset + pos; + for (let i = 0; i < nodeText.length; i += 1) { + content.push({ + kind: 'text', + char: nodeText[i] ?? '', + runAttrs, + offset: baseOffset + i, + }); + } return; } if (node.type.name !== 'run' && node.isInline) { - const start = content.length; - const end = start + 1; content.push({ kind: 'inlineNode', node, nodeType: node.type.name, nodeJSON: node.toJSON(), + pos: paragraphOffset + pos, }); - segments.push({ start, end, pos }); } }, 0, ); - - const resolvePosition: PositionResolver = (index) => { - if (index < 0 || index > content.length) { - return null; - } - - for (const segment of segments) { - if (index >= segment.start && index < segment.end) { - return paragraphPos + 1 + segment.pos + (index - segment.start); - } - } - - return paragraphPos + 1 + paragraph.content.size; - }; - - return { text: content, resolvePosition }; + return content; } /** @@ -224,7 +195,7 @@ export function buildModifiedParagraphDiff( oldParagraph: ParagraphNodeInfo, newParagraph: ParagraphNodeInfo, ): ModifiedParagraphDiff | null { - const contentDiff = getInlineDiff(oldParagraph.text, newParagraph.text, oldParagraph.resolvePosition); + const contentDiff = getInlineDiff(oldParagraph.text, newParagraph.text, oldParagraph.endPos); const attrsDiff = getAttributesDiff(oldParagraph.node.attrs, newParagraph.node.attrs); if (contentDiff.length === 0 && !attrsDiff) { From 2689cb96144c8e77d243bcc106f7dca140003dc3 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 13:48:22 -0300 Subject: [PATCH 039/125] refactor: remove unecessary exports --- .../src/extensions/diffing/algorithm/paragraph-diffing.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 688deada9e..b205aa760b 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -32,21 +32,21 @@ interface ParagraphDiffBase { /** * Diff payload produced when a paragraph is inserted. */ -export type AddedParagraphDiff = ParagraphDiffBase<'added'> & { +type AddedParagraphDiff = ParagraphDiffBase<'added'> & { text: string; }; /** * Diff payload produced when a paragraph is deleted. */ -export type DeletedParagraphDiff = ParagraphDiffBase<'deleted'> & { +type DeletedParagraphDiff = ParagraphDiffBase<'deleted'> & { oldText: string; }; /** * Diff payload emitted when a paragraph changes, including inline edits. */ -export type ModifiedParagraphDiff = ParagraphDiffBase<'modified'> & { +type ModifiedParagraphDiff = ParagraphDiffBase<'modified'> & { oldText: string; newText: string; contentDiff: InlineDiffResult[]; From ab843eff4513e5e0005328aad5f132a0941f1a53 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 15:09:50 -0300 Subject: [PATCH 040/125] refactor: standardize diff attribute names for modifications --- .../diffing/algorithm/paragraph-diffing.test.js | 6 ++++-- .../src/extensions/diffing/algorithm/paragraph-diffing.ts | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index 56f97bb126..b0c558521c 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -292,7 +292,8 @@ describe('paragraph diff builders', () => { expect(diff).toMatchObject({ action: 'modified', nodeType: 'paragraph', - nodeJSON: oldParagraph.node.toJSON(), + oldNodeJSON: oldParagraph.node.toJSON(), + newNodeJSON: newParagraph.node.toJSON(), oldText: 'foo', newText: 'bar', pos: 5, @@ -322,7 +323,8 @@ describe('paragraph diff builders', () => { expect(diff).not.toBeNull(); expect(diff.contentDiff).toEqual([]); expect(diff.attrsDiff?.modified).toHaveProperty('align'); - expect(diff.nodeJSON).toEqual(oldParagraph.node.toJSON()); + expect(diff.oldNodeJSON).toEqual(oldParagraph.node.toJSON()); + expect(diff.newNodeJSON).toEqual(newParagraph.node.toJSON()); }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index b205aa760b..efe245e27e 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -25,7 +25,6 @@ export interface ParagraphNodeInfo { interface ParagraphDiffBase { action: Action; nodeType: string; - nodeJSON: NodeJSON; pos: number; } @@ -33,6 +32,7 @@ interface ParagraphDiffBase { * Diff payload produced when a paragraph is inserted. */ type AddedParagraphDiff = ParagraphDiffBase<'added'> & { + nodeJSON: NodeJSON; text: string; }; @@ -40,6 +40,7 @@ type AddedParagraphDiff = ParagraphDiffBase<'added'> & { * Diff payload produced when a paragraph is deleted. */ type DeletedParagraphDiff = ParagraphDiffBase<'deleted'> & { + nodeJSON: NodeJSON; oldText: string; }; @@ -47,6 +48,8 @@ type DeletedParagraphDiff = ParagraphDiffBase<'deleted'> & { * Diff payload emitted when a paragraph changes, including inline edits. */ type ModifiedParagraphDiff = ParagraphDiffBase<'modified'> & { + oldNodeJSON: NodeJSON; + newNodeJSON: NodeJSON; oldText: string; newText: string; contentDiff: InlineDiffResult[]; @@ -205,7 +208,8 @@ export function buildModifiedParagraphDiff( return { action: 'modified', nodeType: oldParagraph.node.type.name, - nodeJSON: oldParagraph.node.toJSON(), + oldNodeJSON: oldParagraph.node.toJSON(), + newNodeJSON: newParagraph.node.toJSON(), oldText: oldParagraph.fullText, newText: newParagraph.fullText, pos: oldParagraph.pos, From 9158b75221a190437d95d8a41e5efdafdef51eb5 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 30 Dec 2025 15:16:11 -0300 Subject: [PATCH 041/125] docs: add JSDoc to compareDocuments command --- .../super-editor/src/extensions/diffing/diffing.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index f90c518219..7765a38c75 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -7,6 +7,17 @@ export const Diffing = Extension.create({ addCommands() { return { + /** + * Compares the current document against `updatedDocument` and returns the diffs required to + * transform the former into the latter. + * + * These diffs are intended to be replayed on-top of the old document, so apply the + * returned list in reverse (last entry first) to keep insertions that share the same + * `pos` anchor in the correct order. + * + * @param {import('prosemirror-model').Node} updatedDocument + * @returns {import('./computeDiff.ts').NodeDiff[]} + */ compareDocuments: (updatedDocument) => ({ state }) => { From 90216ef5526435066e4b37a58bb0b7d393e47420 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 10:57:09 -0300 Subject: [PATCH 042/125] feat: add function for diffing marks --- .../diffing/algorithm/attributes-diffing.ts | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index 59f08e4598..26b8286157 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -17,6 +17,15 @@ export interface AttributesDiff { modified: Record; } +/** + * Aggregated marks diff broken down into added, deleted, and modified marks. + */ +export interface MarksDiff { + added: { name: string; attrs: Record }[]; + deleted: { name: string; attrs: Record }[]; + modified: { name: string; oldAttrs: Record; newAttrs: Record }[]; +} + /** * Computes the attribute level diff between two arbitrary objects. * Produces a map of dotted paths to added, deleted and modified values. @@ -42,6 +51,74 @@ export function getAttributesDiff( return hasChanges ? diff : null; } +/** + * Computes the attribute level diff between two sets of ProseMirror marks. + * Produces a map of dotted paths to added, deleted and modified values. + * + * @param marksA Baseline marks to compare. + * @param marksB Updated marks to compare. + * @returns Structured diff or null when marks are effectively equal. + * + */ +export function getMarksDiff( + marksA: Array<{ type: string; attrs?: Record }> | null = [], + marksB: Array<{ type: string; attrs?: Record }> | null = [], +): MarksDiff | null { + marksA = marksA || []; + marksB = marksB || []; + + const normalizeMarkAttrs = (attrs?: Record): Record => { + if (!attrs) { + return {}; + } + const normalized: Record = {}; + for (const [key, value] of Object.entries(attrs)) { + if (IGNORED_ATTRIBUTE_KEYS.has(key)) { + continue; + } + normalized[key] = value; + } + return normalized; + }; + const marksDiff: MarksDiff = { + added: [], + deleted: [], + modified: [], + }; + const marksMapA = new Map>(); + const marksMapB = new Map>(); + + for (const mark of marksA) { + marksMapA.set(mark.type, normalizeMarkAttrs(mark.attrs)); + } + for (const mark of marksB) { + marksMapB.set(mark.type, normalizeMarkAttrs(mark.attrs)); + } + + const markNames = new Set([...marksMapA.keys(), ...marksMapB.keys()]); + for (const name of markNames) { + const attrsA = marksMapA.get(name); + const attrsB = marksMapB.get(name); + + if (attrsA && !attrsB) { + marksDiff.deleted.push({ name, attrs: attrsA }); + continue; + } + + if (!attrsA && attrsB) { + marksDiff.added.push({ name, attrs: attrsB }); + continue; + } + + if (attrsA && attrsB && !deepEquals(attrsA, attrsB)) { + marksDiff.modified.push({ name, oldAttrs: attrsA, newAttrs: attrsB }); + } + } + + const hasChanges = marksDiff.added.length > 0 || marksDiff.deleted.length > 0 || marksDiff.modified.length > 0; + return hasChanges ? marksDiff : null; +} + /** * Recursively compares two objects and fills the diff buckets. * From 629bdaa6b3cf57dc1f99e2248aced7dc77ced0f1 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 10:58:32 -0300 Subject: [PATCH 043/125] feat: take marks into account during diff computation --- .../diffing/algorithm/inline-diffing.test.js | 35 +++++++++++ .../diffing/algorithm/inline-diffing.ts | 49 ++++++++++++++- .../algorithm/paragraph-diffing.test.js | 59 ++++++++++++++++++- .../diffing/algorithm/paragraph-diffing.ts | 1 + 4 files changed, 140 insertions(+), 4 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index 5287e0b5e5..96584ba140 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -15,6 +15,15 @@ const buildTextRuns = (text, runAttrs = {}, offsetStart = 0) => offset: offsetStart + index, })); +const buildMarkedTextRuns = (text, marks, runAttrs = {}, offsetStart = 0) => + text.split('').map((char, index) => ({ + char, + runAttrs: { ...runAttrs }, + kind: 'text', + offset: offsetStart + index, + marks, + })); + const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }, pos = 0) => { const nodeAttrs = { ...attrs }; return { @@ -97,6 +106,7 @@ describe('getInlineDiff', () => { deleted: { bold: true }, modified: {}, }, + marksDiff: null, }, ]); }); @@ -125,6 +135,31 @@ describe('getInlineDiff', () => { bold: { from: true, to: false }, }, }, + marksDiff: null, + }, + ]); + }); + + it('treats mark-only changes as modifications and surfaces marks diffs', () => { + const oldRuns = buildMarkedTextRuns('a', [{ type: 'bold', attrs: { level: 1 } }]); + const newRuns = buildMarkedTextRuns('a', [{ type: 'italic', attrs: {} }]); + + const diffs = getInlineDiff(oldRuns, newRuns, oldRuns.length); + + expect(diffs).toEqual([ + { + action: 'modified', + kind: 'text', + startPos: 0, + endPos: 0, + oldText: 'a', + newText: 'a', + runAttrsDiff: null, + marksDiff: { + added: [{ name: 'italic', attrs: {} }], + deleted: [{ name: 'bold', attrs: { level: 1 } }], + modified: [], + }, }, ]); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index 65ea43b513..0579e7d553 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -1,8 +1,9 @@ import type { Node as PMNode } from 'prosemirror-model'; -import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; +import { getAttributesDiff, getMarksDiff, type AttributesDiff, type MarksDiff } from './attributes-diffing.ts'; import { diffSequences } from './sequence-diffing.ts'; type NodeJSON = ReturnType; +type MarkJSON = { type: string; attrs?: Record }; /** * Supported diff operations for inline changes. @@ -16,6 +17,7 @@ export type InlineTextToken = { kind: 'text'; char: string; runAttrs: Record; + marks: MarkJSON[]; offset?: number | null; }; @@ -46,6 +48,7 @@ type RawTextDiff = kind: 'text'; text: string; runAttrs: Record; + marks: MarkJSON[]; } | { action: 'modified'; @@ -55,6 +58,8 @@ type RawTextDiff = oldText: string; oldAttrs: Record; newAttrs: Record; + oldMarks: MarkJSON[]; + newMarks: MarkJSON[]; }; /** @@ -96,6 +101,8 @@ export interface InlineDiffResult { newText?: string; runAttrs?: Record; runAttrsDiff?: AttributesDiff | null; + marks?: Record[]; + marksDiff?: MarksDiff | null; nodeType?: string; nodeJSON?: NodeJSON; oldNodeJSON?: NodeJSON; @@ -116,7 +123,11 @@ export function getInlineDiff( newContent: InlineDiffToken[], oldParagraphEndPos: number, ): InlineDiffResult[] { - const buildInlineDiff = (action: InlineAction, token: InlineDiffToken, oldIdx: number): RawDiff => { + const buildInlineDiff = ( + action: Exclude, + token: InlineDiffToken, + oldIdx: number, + ): RawDiff => { if (token.kind !== 'text') { return { action, @@ -132,6 +143,7 @@ export function getInlineDiff( kind: 'text', text: token.char, runAttrs: token.runAttrs, + marks: token.marks, }; }; @@ -164,6 +176,8 @@ export function getInlineDiff( oldText: oldToken.char, oldAttrs: oldToken.runAttrs, newAttrs: newToken.runAttrs, + oldMarks: oldToken.marks, + newMarks: newToken.marks, }; } return null; @@ -196,7 +210,11 @@ function inlineComparator(a: InlineDiffToken, b: InlineDiffToken): boolean { */ function shouldProcessEqualAsModification(oldToken: InlineDiffToken, newToken: InlineDiffToken): boolean { if (oldToken.kind === 'text' && newToken.kind === 'text') { - return Boolean(getAttributesDiff(oldToken.runAttrs, newToken.runAttrs)); + return ( + Boolean(getAttributesDiff(oldToken.runAttrs, newToken.runAttrs)) || + oldToken.marks?.length !== newToken.marks?.length || + Boolean(getMarksDiff(oldToken.marks, newToken.marks)) + ); } if (oldToken.kind === 'inlineNode' && newToken.kind === 'inlineNode') { @@ -219,6 +237,7 @@ type TextDiffGroup = endPos: number | null; text: string; runAttrs: Record; + marks: MarkJSON[]; } | { action: 'modified'; @@ -229,6 +248,8 @@ type TextDiffGroup = oldText: string; oldAttrs: Record; newAttrs: Record; + oldMarks: MarkJSON[]; + newMarks: MarkJSON[]; }; /** @@ -258,9 +279,11 @@ function groupDiffs(diffs: RawDiff[], oldTokens: InlineDiffToken[], oldParagraph result.oldText = currentGroup.oldText; result.newText = currentGroup.newText; result.runAttrsDiff = getAttributesDiff(currentGroup.oldAttrs, currentGroup.newAttrs); + result.marksDiff = getMarksDiff(currentGroup.oldMarks, currentGroup.newMarks); } else { result.text = currentGroup.text; result.runAttrs = currentGroup.runAttrs; + result.marks = currentGroup.marks; } grouped.push(result); @@ -314,6 +337,8 @@ function createTextGroup(diff: RawTextDiff, oldTokens: InlineDiffToken[], oldPar oldText: diff.oldText, oldAttrs: diff.oldAttrs, newAttrs: diff.newAttrs, + oldMarks: diff.oldMarks, + newMarks: diff.newMarks, } : { action: diff.action, @@ -322,6 +347,7 @@ function createTextGroup(diff: RawTextDiff, oldTokens: InlineDiffToken[], oldPar endPos: resolveTokenPosition(oldTokens, diff.idx, oldParagraphEndPos), text: diff.text, runAttrs: diff.runAttrs, + marks: diff.marks, }; return baseGroup; @@ -364,10 +390,16 @@ function canExtendGroup( if (!areInlineAttrsEqual(group.oldAttrs, diff.oldAttrs) || !areInlineAttrsEqual(group.newAttrs, diff.newAttrs)) { return false; } + if (!areInlineMarksEqual(group.oldMarks, diff.oldMarks) || !areInlineMarksEqual(group.newMarks, diff.newMarks)) { + return false; + } } else if (group.action !== 'modified' && diff.action !== 'modified') { if (!areInlineAttrsEqual(group.runAttrs, diff.runAttrs)) { return false; } + if (!areInlineMarksEqual(group.marks, diff.marks)) { + return false; + } } else { return false; } @@ -417,3 +449,14 @@ function resolveTokenPosition(tokens: InlineDiffToken[], idx: number, paragraphE function areInlineAttrsEqual(a: Record | undefined, b: Record | undefined): boolean { return !getAttributesDiff(a ?? {}, b ?? {}); } + +/** + * Compares two sets of inline marks and determines if they are equal. + * + * @param a - The first set of marks to compare. + * @param b - The second set of marks to compare. + * @returns `true` if the marks are equal, `false` otherwise. + */ +function areInlineMarksEqual(a: MarkJSON[] | undefined, b: MarkJSON[] | undefined): boolean { + return !getMarksDiff(a ?? [], b ?? []); +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index b0c558521c..e7ed1cb5c5 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -11,6 +11,15 @@ import { const buildRuns = (text, attrs = {}) => text.split('').map((char) => ({ char, runAttrs: attrs, kind: 'text' })); +const buildMarkedRuns = (text, marks, attrs = {}, offsetStart = 0) => + text.split('').map((char, index) => ({ + char, + runAttrs: attrs, + kind: 'text', + marks, + offset: offsetStart + index, + })); + const createParagraphNode = (overrides = {}) => { const node = { type: { name: 'paragraph', ...(overrides.type || {}) }, @@ -100,7 +109,7 @@ const createParagraphWithSegments = (segments, contentSize) => { nodesBetween: (from, to, callback) => { computedSegments.forEach((segment) => { if (segment.kind === 'text') { - callback({ isText: true, text: segment.text }, segment.start); + callback({ isText: true, text: segment.text, marks: segment.marks ?? [] }, segment.start); } else if (segment.kind === 'leaf') { callback({ isLeaf: true, type: { spec: { leafText: segment.leafText } } }, segment.start); } else { @@ -197,6 +206,15 @@ describe('createParagraphSnapshot', () => { expect(result.text[1]?.offset).toBe(2); }); + it('captures marks from text nodes in the snapshot', () => { + const boldMark = { toJSON: () => ({ type: 'bold', attrs: { level: 2 } }) }; + const mockParagraph = createParagraphWithSegments([{ text: 'Hi', start: 0, marks: [boldMark] }], 2); + + const result = createParagraphSnapshot(mockParagraph, 0, 0); + expect(result.text[0]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); + expect(result.text[1]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); + }); + it('applies paragraph position offsets to the resolver', () => { const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); @@ -302,6 +320,45 @@ describe('paragraph diff builders', () => { expect(diff.contentDiff.length).toBeGreaterThan(0); }); + it('returns a diff when only inline marks change', () => { + const oldParagraph = createParagraphInfo({ + fullText: 'a', + text: buildMarkedRuns('a', [{ type: 'bold', attrs: { level: 1 } }], {}, 1), + node: createParagraphNode({ attrs: { align: 'left' } }), + }); + const newParagraph = createParagraphInfo({ + fullText: 'a', + text: buildMarkedRuns('a', [{ type: 'bold', attrs: { level: 2 } }], {}, 1), + node: createParagraphNode({ attrs: { align: 'left' } }), + }); + + const diff = buildModifiedParagraphDiff(oldParagraph, newParagraph); + expect(diff).not.toBeNull(); + expect(diff?.attrsDiff).toBeNull(); + expect(diff?.contentDiff).toEqual([ + { + action: 'modified', + kind: 'text', + startPos: 1, + endPos: 1, + oldText: 'a', + newText: 'a', + runAttrsDiff: null, + marksDiff: { + added: [], + deleted: [], + modified: [ + { + name: 'bold', + oldAttrs: { level: 1 }, + newAttrs: { level: 2 }, + }, + ], + }, + }, + ]); + }); + it('returns null when neither text nor attributes changed', () => { const baseParagraph = createParagraphInfo({ fullText: 'stable', diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index efe245e27e..ab5064f1b5 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -116,6 +116,7 @@ function buildParagraphContent(paragraph: PMNode, paragraphPos = 0): InlineDiffT char: nodeText[i] ?? '', runAttrs, offset: baseOffset + i, + marks: node.marks?.map((mark) => mark.toJSON()) ?? [], }); } return; From b6181ac4d31ed1af425f77837fee69e0081e1409 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 12:10:14 -0300 Subject: [PATCH 044/125] refactor: modify computeDiff signature to account for comments diffing --- .../extensions/diffing/computeDiff.test.js | 65 +++++++++++++------ .../src/extensions/diffing/computeDiff.ts | 28 ++++++-- .../src/extensions/diffing/diffing.js | 4 +- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index f8c28db8d1..512c12ec5f 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -5,6 +5,12 @@ import { Editor } from '@core/Editor.js'; import { getStarterExtensions } from '@extensions/index.js'; import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers.js'; +/** + * Loads a DOCX fixture and returns the ProseMirror document and schema. + * + * @param {string} name DOCX fixture filename. + * @returns {Promise<{ doc: import('prosemirror-model').Node; schema: import('prosemirror-model').Schema }>} + */ const getDocument = async (name) => { const buffer = await getTestDataAsBuffer(name); const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); @@ -21,9 +27,15 @@ const getDocument = async (name) => { annotations: true, }); - return editor.state.doc; + return { doc: editor.state.doc, schema: editor.schema }; }; +/** + * Flattens a ProseMirror JSON node to its text content. + * + * @param {import('prosemirror-model').Node | import('prosemirror-model').Node['toJSON'] | null | undefined} nodeJSON + * @returns {string} + */ const getNodeTextContent = (nodeJSON) => { if (!nodeJSON) { return ''; @@ -39,10 +51,11 @@ const getNodeTextContent = (nodeJSON) => { describe('Diff', () => { it('Compares two documents and identifies added, deleted, and modified paragraphs', async () => { - const docBefore = await getDocument('diff_before.docx'); - const docAfter = await getDocument('diff_after.docx'); + const { doc: docBefore, schema } = await getDocument('diff_before.docx'); + const { doc: docAfter } = await getDocument('diff_after.docx'); - const diffs = computeDiff(docBefore, docAfter); + const { docDiffs } = computeDiff(docBefore, docAfter, schema); + const diffs = docDiffs; const getDiff = (action, predicate) => diffs.find((diff) => diff.action === action && predicate(diff)); const modifiedDiffs = diffs.filter((diff) => diff.action === 'modified'); @@ -139,10 +152,11 @@ describe('Diff', () => { }); it('Compare two documents with simple changes', async () => { - const docBefore = await getDocument('diff_before2.docx'); - const docAfter = await getDocument('diff_after2.docx'); + const { doc: docBefore, schema } = await getDocument('diff_before2.docx'); + const { doc: docAfter } = await getDocument('diff_after2.docx'); - const diffs = computeDiff(docBefore, docAfter); + const { docDiffs } = computeDiff(docBefore, docAfter, schema); + const diffs = docDiffs; expect(diffs).toHaveLength(4); let diff = diffs.find((diff) => diff.action === 'modified' && diff.oldText === 'Here’s some text.'); @@ -167,10 +181,11 @@ describe('Diff', () => { }); it('Compare another set of two documents with only formatting changes', async () => { - const docBefore = await getDocument('diff_before4.docx'); - const docAfter = await getDocument('diff_after4.docx'); + const { doc: docBefore, schema } = await getDocument('diff_before4.docx'); + const { doc: docAfter } = await getDocument('diff_after4.docx'); - const diffs = computeDiff(docBefore, docAfter); + const { docDiffs } = computeDiff(docBefore, docAfter, schema); + const diffs = docDiffs; expect(diffs).toHaveLength(1); const diff = diffs[0]; @@ -178,10 +193,11 @@ describe('Diff', () => { }); it('Compare another set of two documents with only formatting changes', async () => { - const docBefore = await getDocument('diff_before5.docx'); - const docAfter = await getDocument('diff_after5.docx'); + const { doc: docBefore, schema } = await getDocument('diff_before5.docx'); + const { doc: docAfter } = await getDocument('diff_after5.docx'); - const diffs = computeDiff(docBefore, docAfter); + const { docDiffs } = computeDiff(docBefore, docAfter, schema); + const diffs = docDiffs; expect(diffs).toHaveLength(1); const diff = diffs[0]; @@ -189,10 +205,11 @@ describe('Diff', () => { }); it('Compare another set of two documents where an image was added', async () => { - const docBefore = await getDocument('diff_before6.docx'); - const docAfter = await getDocument('diff_after6.docx'); + const { doc: docBefore, schema } = await getDocument('diff_before6.docx'); + const { doc: docAfter } = await getDocument('diff_after6.docx'); - const diffs = computeDiff(docBefore, docAfter); + const { docDiffs } = computeDiff(docBefore, docAfter, schema); + const diffs = docDiffs; expect(diffs).toHaveLength(1); const diff = diffs[0]; expect(diff.action).toBe('modified'); @@ -206,10 +223,11 @@ describe('Diff', () => { }); it('Compare a complex document with table edits and tracked formatting', async () => { - const docBefore = await getDocument('diff_before7.docx'); - const docAfter = await getDocument('diff_after7.docx'); + const { doc: docBefore, schema } = await getDocument('diff_before7.docx'); + const { doc: docAfter } = await getDocument('diff_after7.docx'); - const diffs = computeDiff(docBefore, docAfter); + const { docDiffs } = computeDiff(docBefore, docAfter, schema); + const diffs = docDiffs; expect(diffs).toHaveLength(9); expect(diffs.filter((diff) => diff.action === 'modified')).toHaveLength(6); expect(diffs.filter((diff) => diff.action === 'added')).toHaveLength(2); @@ -268,4 +286,13 @@ describe('Diff', () => { ); expect(firstCellDiff?.contentDiff?.[0]?.text).toBe('First '); }); + + it('Compare a complex document with table edits and tracked formatting', async () => { + const { doc: docBefore, schema } = await getDocument('diff_before8.docx'); + const { doc: docAfter } = await getDocument('diff_after8.docx'); + + const { docDiffs } = computeDiff(docBefore, docAfter, schema); + const diffs = docDiffs; + console.log(JSON.stringify(diffs, null, 2)); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts index feb84642aa..5c5ebc17e0 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.ts +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -1,6 +1,21 @@ -import type { Node as PMNode } from 'prosemirror-model'; +import type { Node as PMNode, Schema } from 'prosemirror-model'; import { diffNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; +/** + * Placeholder type for comment diffs until comment diffing is implemented. + */ +export type CommentDiff = Record; + +/** + * Result payload for document diffing. + */ +export interface DiffResult { + /** Diffs computed from the ProseMirror document structure. */ + docDiffs: NodeDiff[]; + /** Diffs computed from comment content and metadata. */ + commentDiffs: CommentDiff[]; +} + /** * Computes structural diffs between two ProseMirror documents, emitting insert/delete/modify operations for any block * node (paragraphs, images, tables, etc.). Paragraph mutations include inline text and inline-node diffs so consumers @@ -13,8 +28,13 @@ import { diffNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; * * @param oldPmDoc The previous ProseMirror document. * @param newPmDoc The updated ProseMirror document. - * @returns List of diff objects describing added, deleted or modified nodes (with inline-level diffs for paragraphs). + * @param schema The schema used to interpret document nodes (unused for now). + * @returns Object containing document and comment diffs. */ -export function computeDiff(oldPmDoc: PMNode, newPmDoc: PMNode): NodeDiff[] { - return diffNodes(oldPmDoc, newPmDoc); +export function computeDiff(oldPmDoc: PMNode, newPmDoc: PMNode, schema: Schema): DiffResult { + void schema; + return { + docDiffs: diffNodes(oldPmDoc, newPmDoc), + commentDiffs: [], + }; } diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 7765a38c75..30815e0582 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -16,12 +16,12 @@ export const Diffing = Extension.create({ * `pos` anchor in the correct order. * * @param {import('prosemirror-model').Node} updatedDocument - * @returns {import('./computeDiff.ts').NodeDiff[]} + * @returns {import('./computeDiff.ts').DiffResult} */ compareDocuments: (updatedDocument) => ({ state }) => { - const diffs = computeDiff(state.doc, updatedDocument); + const diffs = computeDiff(state.doc, updatedDocument, state.schema); return diffs; }, }; From dbb8604ab698f7b1874e99eb6a6226783669e047 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 12:18:19 -0300 Subject: [PATCH 045/125] feat: add generic inline content tokenization function --- .../diffing/algorithm/inline-diffing.test.js | 225 +++++++++++++++++- .../diffing/algorithm/inline-diffing.ts | 55 +++++ .../algorithm/paragraph-diffing.test.js | 198 +++------------ 3 files changed, 307 insertions(+), 171 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index 96584ba140..2a5c2bcc93 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -5,8 +5,16 @@ vi.mock('./myers-diff.ts', async () => { myersDiff: vi.fn(actual.myersDiff), }; }); -import { getInlineDiff } from './inline-diffing.ts'; +import { getInlineDiff, tokenizeInlineContent } from './inline-diffing.ts'; +/** + * Builds text tokens with offsets for inline diff tests. + * + * @param {string} text Text content to tokenize. + * @param {Record} runAttrs Run attributes to attach. + * @param {number} offsetStart Offset base for the first token. + * @returns {import('./inline-diffing.ts').InlineTextToken[]} + */ const buildTextRuns = (text, runAttrs = {}, offsetStart = 0) => text.split('').map((char, index) => ({ char, @@ -15,6 +23,15 @@ const buildTextRuns = (text, runAttrs = {}, offsetStart = 0) => offset: offsetStart + index, })); +/** + * Builds marked text tokens with offsets for inline diff tests. + * + * @param {string} text Text content to tokenize. + * @param {Array>} marks Marks to attach. + * @param {Record} runAttrs Run attributes to attach. + * @param {number} offsetStart Offset base for the first token. + * @returns {import('./inline-diffing.ts').InlineTextToken[]} + */ const buildMarkedTextRuns = (text, marks, runAttrs = {}, offsetStart = 0) => text.split('').map((char, index) => ({ char, @@ -24,6 +41,14 @@ const buildMarkedTextRuns = (text, marks, runAttrs = {}, offsetStart = 0) => marks, })); +/** + * Builds a mock inline-node token for diff tests. + * + * @param {Record} attrs Node attributes. + * @param {{ name: string }} type Node type descriptor. + * @param {number} pos Position offset for the inline node. + * @returns {import('./inline-diffing.ts').InlineNodeToken} + */ const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }, pos = 0) => { const nodeAttrs = { ...attrs }; return { @@ -39,6 +64,122 @@ const buildInlineNodeToken = (attrs = {}, type = { name: 'link' }, pos = 0) => { }; }; +/** + * Builds text tokens without offsets for tokenizer assertions. + * + * @param {string} text Text content to tokenize. + * @param {Record} runAttrs Run attributes to attach. + * @param {Array>} marks Marks to attach. + * @returns {import('./inline-diffing.ts').InlineTextToken[]} + */ +const buildTextTokens = (text, runAttrs = {}, marks = []) => + text.split('').map((char) => ({ + char, + runAttrs, + kind: 'text', + marks, + })); + +/** + * Creates a mock inline container with configurable segments for tokenizer tests. + * + * @param {Array>} segments Inline segments to emit. + * @param {number | null} contentSize Optional content size override. + * @returns {import('prosemirror-model').Node} + */ +const createInlineContainer = (segments, contentSize) => { + const computedSegments = segments.map((segment) => { + if (segment.inlineNode) { + return { + ...segment, + kind: 'inline', + length: segment.length ?? 1, + start: segment.start ?? 0, + attrs: segment.attrs ?? segment.inlineNode.attrs ?? {}, + inlineNode: { + typeName: segment.inlineNode.typeName ?? 'inline', + attrs: segment.inlineNode.attrs ?? {}, + isLeaf: segment.inlineNode.isLeaf ?? true, + toJSON: + segment.inlineNode.toJSON ?? + (() => ({ + type: segment.inlineNode.typeName ?? 'inline', + attrs: segment.inlineNode.attrs ?? {}, + })), + }, + }; + } + + const segmentText = segment.text ?? segment.leafText(); + const length = segmentText.length; + return { + ...segment, + kind: segment.text != null ? 'text' : 'leaf', + length, + start: segment.start ?? 0, + attrs: segment.attrs ?? {}, + }; + }); + const size = + contentSize ?? computedSegments.reduce((max, segment) => Math.max(max, segment.start + segment.length), 0); + const attrsMap = new Map(); + computedSegments.forEach((segment) => { + const key = segment.kind === 'inline' ? segment.start : segment.start - 1; + attrsMap.set(key, segment.attrs); + }); + + return { + content: { size }, + nodesBetween: (from, to, callback) => { + computedSegments.forEach((segment) => { + if (segment.kind === 'text') { + callback({ isText: true, text: segment.text, marks: segment.marks ?? [] }, segment.start); + } else if (segment.kind === 'leaf') { + callback({ isLeaf: true, type: { spec: { leafText: segment.leafText } } }, segment.start); + } else { + callback( + { + isInline: true, + isLeaf: segment.inlineNode.isLeaf, + type: { name: segment.inlineNode.typeName, spec: {} }, + attrs: segment.inlineNode.attrs, + toJSON: () => ({ + type: segment.inlineNode.typeName, + attrs: segment.inlineNode.attrs, + }), + }, + segment.start, + ); + } + }); + }, + nodeAt: (pos) => ({ attrs: attrsMap.get(pos) ?? {} }), + }; +}; + +/** + * Strips positional fields from tokens for assertions. + * + * @param {import('./inline-diffing.ts').InlineDiffToken[]} tokens Tokens to normalize. + * @returns {Array>} + */ +const stripTokenOffsets = (tokens) => + tokens.map((token) => { + if (token.kind === 'text') { + return { + kind: token.kind, + char: token.char, + runAttrs: token.runAttrs, + marks: token.marks, + }; + } + return { + kind: token.kind, + nodeType: token.nodeType, + nodeJSON: token.nodeJSON, + }; + }); + describe('getInlineDiff', () => { it('returns an empty diff list when both strings are identical', () => { const oldRuns = buildTextRuns('unchanged'); @@ -194,3 +335,85 @@ describe('getInlineDiff', () => { ]); }); }); + +describe('tokenizeInlineContent', () => { + it('handles basic text nodes', () => { + const mockParagraph = createInlineContainer([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); + + const tokens = tokenizeInlineContent(mockParagraph, 1); + expect(stripTokenOffsets(tokens)).toEqual(buildTextTokens('Hello', { bold: true }, [])); + expect(tokens[0]?.offset).toBe(1); + expect(tokens[4]?.offset).toBe(5); + }); + + it('handles leaf nodes with leafText', () => { + const mockParagraph = createInlineContainer([{ leafText: () => 'Leaf', start: 0, attrs: { type: 'leaf' } }], 4); + + const tokens = tokenizeInlineContent(mockParagraph, 1); + expect(stripTokenOffsets(tokens)).toEqual(buildTextTokens('Leaf', { type: 'leaf' }, [])); + expect(tokens[0]?.offset).toBe(1); + expect(tokens[3]?.offset).toBe(4); + }); + + it('handles mixed content', () => { + const mockParagraph = createInlineContainer([ + { text: 'Hello', start: 0, attrs: { bold: true } }, + { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, + ]); + + const tokens = tokenizeInlineContent(mockParagraph, 1); + expect(stripTokenOffsets(tokens)).toEqual([ + ...buildTextTokens('Hello', { bold: true }, []), + ...buildTextTokens('Leaf', { italic: true }, []), + ]); + expect(tokens[0]?.offset).toBe(1); + expect(tokens[5]?.offset).toBe(6); + expect(tokens[tokens.length - 1]?.offset).toBe(9); + }); + + it('handles empty content', () => { + const mockParagraph = createInlineContainer([], 0); + + const tokens = tokenizeInlineContent(mockParagraph, 1); + expect(tokens).toEqual([]); + }); + + it('includes inline nodes that have no textual content', () => { + const inlineAttrs = { kind: 'tab', width: 120 }; + const mockParagraph = createInlineContainer([ + { inlineNode: { typeName: 'tab', attrs: inlineAttrs }, start: 0 }, + { text: 'Text', start: 1, attrs: { bold: false } }, + ]); + + const tokens = tokenizeInlineContent(mockParagraph, 1); + expect(tokens[0]).toMatchObject({ + kind: 'inlineNode', + nodeType: 'tab', + nodeJSON: { + type: 'tab', + attrs: inlineAttrs, + }, + pos: 1, + }); + expect(stripTokenOffsets(tokens.slice(1))).toEqual(buildTextTokens('Text', { bold: false }, [])); + expect(tokens[1]?.offset).toBe(2); + }); + + it('captures marks from text nodes', () => { + const boldMark = { toJSON: () => ({ type: 'bold', attrs: { level: 2 } }) }; + const mockParagraph = createInlineContainer([{ text: 'Hi', start: 0, marks: [boldMark] }], 2); + + const tokens = tokenizeInlineContent(mockParagraph, 1); + expect(tokens[0]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); + expect(tokens[1]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); + }); + + it('applies the base offset to token positions', () => { + const mockParagraph = createInlineContainer([{ text: 'Nested', start: 0 }], 6); + + const tokens = tokenizeInlineContent(mockParagraph, 11); + expect(stripTokenOffsets(tokens)).toEqual(buildTextTokens('Nested', {}, [])); + expect(tokens[0]?.offset).toBe(11); + expect(tokens[5]?.offset).toBe(16); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index 0579e7d553..c52cffeeb8 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -110,6 +110,61 @@ export interface InlineDiffResult { attrsDiff?: AttributesDiff | null; } +/** + * Tokenizes inline content into diffable text and inline-node tokens. + * + * @param pmNode ProseMirror node containing inline content. + * @param baseOffset Offset applied to every token position (default: 0). + * @returns Flattened inline tokens with offsets relative to the base offset. + */ +export function tokenizeInlineContent(pmNode: PMNode, baseOffset = 0): InlineDiffToken[] { + const content: InlineDiffToken[] = []; + pmNode.nodesBetween( + 0, + pmNode.content.size, + (node, pos) => { + let nodeText = ''; + + if (node.isText) { + nodeText = node.text ?? ''; + } else if (node.isLeaf) { + const leafTextFn = (node.type.spec as { leafText?: (node: PMNode) => string } | undefined)?.leafText; + if (leafTextFn) { + nodeText = leafTextFn(node); + } + } + + if (nodeText) { + const runNode = pmNode.nodeAt(pos - 1); + const runAttrs = runNode?.attrs ?? {}; + const tokenOffset = baseOffset + pos; + for (let i = 0; i < nodeText.length; i += 1) { + content.push({ + kind: 'text', + char: nodeText[i] ?? '', + runAttrs, + offset: tokenOffset + i, + marks: node.marks?.map((mark) => mark.toJSON()) ?? [], + }); + } + return; + } + + if (node.type.name !== 'run' && node.isInline) { + content.push({ + kind: 'inlineNode', + node, + nodeType: node.type.name, + nodeJSON: node.toJSON(), + pos: baseOffset + pos, + }); + } + }, + 0, + ); + return content; +} + /** * Computes text-level additions and deletions between two sequences using the generic sequence diff, mapping back to document positions. * diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index e7ed1cb5c5..20db466b7e 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest'; import { - createParagraphSnapshot, shouldProcessEqualAsModification, paragraphComparator, buildAddedParagraphDiff, @@ -9,8 +8,24 @@ import { canTreatAsModification, } from './paragraph-diffing.ts'; +/** + * Builds text tokens without offsets for paragraph diff tests. + * + * @param {string} text Text content to tokenize. + * @param {Record} attrs Run attributes to attach. + * @returns {Array>} + */ const buildRuns = (text, attrs = {}) => text.split('').map((char) => ({ char, runAttrs: attrs, kind: 'text' })); +/** + * Builds marked text tokens with offsets for paragraph diff tests. + * + * @param {string} text Text content to tokenize. + * @param {Array>} marks Marks to attach. + * @param {Record} attrs Run attributes to attach. + * @param {number} offsetStart Offset base for the first token. + * @returns {Array>} + */ const buildMarkedRuns = (text, marks, attrs = {}, offsetStart = 0) => text.split('').map((char, index) => ({ char, @@ -20,6 +35,12 @@ const buildMarkedRuns = (text, marks, attrs = {}, offsetStart = 0) => offset: offsetStart + index, })); +/** + * Creates a mock paragraph node with default attributes. + * + * @param {Record} overrides Overrides for the mock node. + * @returns {Record} + */ const createParagraphNode = (overrides = {}) => { const node = { type: { name: 'paragraph', ...(overrides.type || {}) }, @@ -33,6 +54,12 @@ const createParagraphNode = (overrides = {}) => { return node; }; +/** + * Creates a paragraph snapshot stub for diff builder tests. + * + * @param {Record} overrides Overrides for the snapshot. + * @returns {Record} + */ const createParagraphInfo = (overrides = {}) => { const fullText = overrides.fullText ?? 'text'; const paragraphPos = overrides.pos ?? 0; @@ -63,175 +90,6 @@ const createParagraphInfo = (overrides = {}) => { }; }; -const createParagraphWithSegments = (segments, contentSize) => { - const computedSegments = segments.map((segment) => { - if (segment.inlineNode) { - return { - ...segment, - kind: 'inline', - length: segment.length ?? 1, - start: segment.start ?? 0, - attrs: segment.attrs ?? segment.inlineNode.attrs ?? {}, - inlineNode: { - typeName: segment.inlineNode.typeName ?? 'inline', - attrs: segment.inlineNode.attrs ?? {}, - isLeaf: segment.inlineNode.isLeaf ?? true, - toJSON: - segment.inlineNode.toJSON ?? - (() => ({ - type: segment.inlineNode.typeName ?? 'inline', - attrs: segment.inlineNode.attrs ?? {}, - })), - }, - }; - } - - const segmentText = segment.text ?? segment.leafText(); - const length = segmentText.length; - return { - ...segment, - kind: segment.text != null ? 'text' : 'leaf', - length, - start: segment.start ?? 0, - attrs: segment.attrs ?? {}, - }; - }); - const size = - contentSize ?? computedSegments.reduce((max, segment) => Math.max(max, segment.start + segment.length), 0); - const attrsMap = new Map(); - computedSegments.forEach((segment) => { - const key = segment.kind === 'inline' ? segment.start : segment.start - 1; - attrsMap.set(key, segment.attrs); - }); - - return { - content: { size }, - nodesBetween: (from, to, callback) => { - computedSegments.forEach((segment) => { - if (segment.kind === 'text') { - callback({ isText: true, text: segment.text, marks: segment.marks ?? [] }, segment.start); - } else if (segment.kind === 'leaf') { - callback({ isLeaf: true, type: { spec: { leafText: segment.leafText } } }, segment.start); - } else { - callback( - { - isInline: true, - isLeaf: segment.inlineNode.isLeaf, - type: { name: segment.inlineNode.typeName, spec: {} }, - attrs: segment.inlineNode.attrs, - toJSON: () => ({ - type: segment.inlineNode.typeName, - attrs: segment.inlineNode.attrs, - }), - }, - segment.start, - ); - } - }); - }, - nodeAt: (pos) => ({ attrs: attrsMap.get(pos) ?? {} }), - }; -}; - -const stripOffsets = (tokens) => - tokens.map((token) => - token.kind === 'text' ? { kind: token.kind, char: token.char, runAttrs: token.runAttrs } : token, - ); - -describe('createParagraphSnapshot', () => { - it('handles basic text nodes', () => { - const mockParagraph = createParagraphWithSegments([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); - - const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(stripOffsets(result.text)).toEqual(buildRuns('Hello', { bold: true })); - expect(result.text[0]?.offset).toBe(1); - expect(result.text[4]?.offset).toBe(5); - }); - - it('handles leaf nodes with leafText', () => { - const mockParagraph = createParagraphWithSegments( - [{ leafText: () => 'Leaf', start: 0, attrs: { type: 'leaf' } }], - 4, - ); - - const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(stripOffsets(result.text)).toEqual(buildRuns('Leaf', { type: 'leaf' })); - expect(result.text[0]?.offset).toBe(1); - expect(result.text[3]?.offset).toBe(4); - }); - - it('handles mixed content', () => { - const mockParagraph = createParagraphWithSegments([ - { text: 'Hello', start: 0, attrs: { bold: true } }, - { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, - ]); - - const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(stripOffsets(result.text)).toEqual([ - ...buildRuns('Hello', { bold: true }), - ...buildRuns('Leaf', { italic: true }), - ]); - expect(result.text[0]?.offset).toBe(1); - expect(result.text[5]?.offset).toBe(6); - expect(result.text[result.text.length - 1]?.offset).toBe(9); - expect(result.endPos).toBe(10); - }); - - it('handles empty content', () => { - const mockParagraph = createParagraphWithSegments([], 0); - - const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(result.text).toEqual([]); - expect(result.endPos).toBe(1); - }); - - it('includes inline nodes that have no textual content', () => { - const inlineAttrs = { kind: 'tab', width: 120 }; - const mockParagraph = createParagraphWithSegments([ - { inlineNode: { typeName: 'tab', attrs: inlineAttrs }, start: 0 }, - { text: 'Text', start: 1, attrs: { bold: false } }, - ]); - - const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(result.text[0]).toMatchObject({ - kind: 'inlineNode', - nodeType: 'tab', - nodeJSON: { - type: 'tab', - attrs: inlineAttrs, - }, - pos: 1, - }); - expect(stripOffsets(result.text.slice(1))).toEqual(buildRuns('Text', { bold: false })); - expect(result.text[1]?.offset).toBe(2); - }); - - it('captures marks from text nodes in the snapshot', () => { - const boldMark = { toJSON: () => ({ type: 'bold', attrs: { level: 2 } }) }; - const mockParagraph = createParagraphWithSegments([{ text: 'Hi', start: 0, marks: [boldMark] }], 2); - - const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(result.text[0]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); - expect(result.text[1]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); - }); - - it('applies paragraph position offsets to the resolver', () => { - const mockParagraph = createParagraphWithSegments([{ text: 'Nested', start: 0 }], 6); - - const result = createParagraphSnapshot(mockParagraph, 10, 0); - expect(stripOffsets(result.text)).toEqual(buildRuns('Nested', {})); - expect(result.text[0]?.offset).toBe(11); - expect(result.text[5]?.offset).toBe(16); - expect(result.endPos).toBe(17); - }); - - it('returns null when index is outside the flattened text array', () => { - const mockParagraph = createParagraphWithSegments([{ text: 'Hi', start: 0 }], 2); - const result = createParagraphSnapshot(mockParagraph, 0, 0); - expect(result.endPos).toBe(3); - }); -}); - describe('shouldProcessEqualAsModification', () => { it('returns true when node JSON differs', () => { const baseNode = { toJSON: () => ({ attrs: { bold: true } }) }; From e5d876b08b4cf2d6bbee563fb832219a6437ba26 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 12:21:13 -0300 Subject: [PATCH 046/125] refactor: use inline content tokenization function for paragraphs --- .../diffing/algorithm/paragraph-diffing.ts | 60 +------------------ 1 file changed, 2 insertions(+), 58 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index ab5064f1b5..2b15154de7 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -1,5 +1,5 @@ import type { Node as PMNode } from 'prosemirror-model'; -import { getInlineDiff, type InlineDiffToken, type InlineDiffResult } from './inline-diffing.ts'; +import { getInlineDiff, tokenizeInlineContent, type InlineDiffToken, type InlineDiffResult } from './inline-diffing.ts'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; import { getInsertionPos } from './diff-utils.ts'; import { levenshteinDistance } from './similarity.ts'; @@ -70,7 +70,7 @@ export type ParagraphDiff = AddedParagraphDiff | DeletedParagraphDiff | Modified * @returns Snapshot containing tokens (with offsets) and derived metadata. */ export function createParagraphSnapshot(paragraph: PMNode, paragraphPos: number, depth: number): ParagraphNodeInfo { - const text = buildParagraphContent(paragraph, paragraphPos); + const text = tokenizeInlineContent(paragraph, paragraphPos + 1); return { node: paragraph, pos: paragraphPos, @@ -81,62 +81,6 @@ export function createParagraphSnapshot(paragraph: PMNode, paragraphPos: number, }; } -/** - * Flattens a paragraph node into inline diff tokens, embedding absolute document offsets. - * - * @param paragraph Paragraph node being tokenized. - * @param paragraphPos Absolute document position for the paragraph; used to offset resolver results. - * @returns Flattened tokens enriched with document offsets. - */ -function buildParagraphContent(paragraph: PMNode, paragraphPos = 0): InlineDiffToken[] { - const content: InlineDiffToken[] = []; - const paragraphOffset = paragraphPos + 1; - paragraph.nodesBetween( - 0, - paragraph.content.size, - (node, pos) => { - let nodeText = ''; - - if (node.isText) { - nodeText = node.text ?? ''; - } else if (node.isLeaf) { - const leafTextFn = (node.type.spec as { leafText?: (node: PMNode) => string } | undefined)?.leafText; - if (leafTextFn) { - nodeText = leafTextFn(node); - } - } - - if (nodeText) { - const runNode = paragraph.nodeAt(pos - 1); - const runAttrs = runNode?.attrs ?? {}; - const baseOffset = paragraphOffset + pos; - for (let i = 0; i < nodeText.length; i += 1) { - content.push({ - kind: 'text', - char: nodeText[i] ?? '', - runAttrs, - offset: baseOffset + i, - marks: node.marks?.map((mark) => mark.toJSON()) ?? [], - }); - } - return; - } - - if (node.type.name !== 'run' && node.isInline) { - content.push({ - kind: 'inlineNode', - node, - nodeType: node.type.name, - nodeJSON: node.toJSON(), - pos: paragraphOffset + pos, - }); - } - }, - 0, - ); - return content; -} - /** * Determines whether equal paragraph nodes should still be marked as modified because their serialized structure differs. * From 96bf85c3a92e4f931627159d05b27e6f629b556a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 13:53:53 -0300 Subject: [PATCH 047/125] feat: implement tokenization of comment data --- .../diffing/algorithm/comment-diffing.test.ts | 97 +++++++++++++++++++ .../diffing/algorithm/comment-diffing.ts | 89 +++++++++++++++++ .../diffing/algorithm/generic-diffing.ts | 4 +- .../diffing/algorithm/inline-diffing.test.js | 30 +++--- .../diffing/algorithm/inline-diffing.ts | 2 +- 5 files changed, 204 insertions(+), 18 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts new file mode 100644 index 0000000000..9d0be9e342 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts @@ -0,0 +1,97 @@ +import { describe, expect, it } from 'vitest'; +import { Schema } from 'prosemirror-model'; +import { buildCommentTokens } from './comment-diffing.ts'; + +/** + * Builds a minimal schema suitable for comment text tokenization. + * + * @returns {Schema} + */ +const createSchema = () => + new Schema({ + nodes: { + doc: { content: 'block+' }, + paragraph: { content: 'inline*', group: 'block' }, + text: { group: 'inline' }, + }, + marks: {}, + }); + +/** + * Builds a basic comment body JSON payload. + * + * @param {string} text Comment text content. + * @returns {Record} + */ +const buildCommentTextJson = (text) => ({ + type: 'paragraph', + content: [{ type: 'text', text }], +}); + +describe('buildCommentTokens', () => { + it('builds tokens and text for comments with commentId', () => { + const schema = createSchema(); + const comment = { + commentId: 'c-1', + textJson: buildCommentTextJson('Hello'), + isInternal: true, + }; + + const tokens = buildCommentTokens([comment], schema); + expect(tokens).toHaveLength(1); + expect(tokens[0]?.commentId).toBe('c-1'); + expect(tokens[0]?.content?.fullText).toBe('Hello'); + expect(tokens[0]?.content?.text).toHaveLength(5); + expect(tokens[0]?.commentJSON).toBe(comment); + }); + + it('falls back to importedId when commentId is missing', () => { + const schema = createSchema(); + const comment = { + importedId: 'import-1', + textJson: buildCommentTextJson('Import'), + }; + + const tokens = buildCommentTokens([comment], schema); + expect(tokens).toHaveLength(1); + expect(tokens[0]?.commentId).toBe('import-1'); + }); + + it('returns empty text when textJson is missing', () => { + const schema = createSchema(); + const comment = { + commentId: 'c-2', + textJson: null, + }; + + const tokens = buildCommentTokens([comment], schema); + expect(tokens).toHaveLength(1); + expect(tokens[0]?.content).toBeNull(); + }); + + it('returns a base node info when the root node is not a paragraph', () => { + const schema = createSchema(); + const comment = { + commentId: 'c-3', + textJson: { type: 'text', text: 'Inline' }, + }; + + const tokens = buildCommentTokens([comment], schema); + expect(tokens).toHaveLength(1); + expect(tokens[0]?.content).toMatchObject({ + pos: 0, + depth: 0, + }); + expect(tokens[0]?.content?.node?.type?.name).toBe('text'); + }); + + it('skips comments without a resolvable id', () => { + const schema = createSchema(); + const comment = { + textJson: buildCommentTextJson('No id'), + }; + + const tokens = buildCommentTokens([comment], schema); + expect(tokens).toEqual([]); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts new file mode 100644 index 0000000000..02e8f52212 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts @@ -0,0 +1,89 @@ +import type { Schema } from 'prosemirror-model'; +import type { NodeInfo } from './generic-diffing.ts'; +import { createParagraphSnapshot } from './paragraph-diffing.ts'; + +/** + * Raw comment data used for diffing comment content and metadata. + */ +export interface CommentInput { + /** Primary comment identifier when available. */ + commentId?: string; + /** Imported comment identifier used as a fallback. */ + importedId?: string; + /** Alternate identifier used by some integrations. */ + id?: string; + /** ProseMirror-compatible JSON for the comment body (expected to be a paragraph node). */ + textJson?: unknown; + /** Additional comment metadata fields. */ + [key: string]: unknown; +} + +/** + * Normalized token representation for a single comment. + */ +export interface CommentToken { + /** Resolved identifier for the comment. */ + commentId: string; + /** Original comment payload. */ + commentJSON: CommentInput; + /** Parsed comment body content when available. */ + content: NodeInfo | null; +} + +/** + * Builds normalized tokens for diffing comment content. + * + * @param comments Comment payloads to normalize. + * @param schema Schema used to build ProseMirror nodes from comment JSON. + * @returns Normalized comment tokens. + */ +export function buildCommentTokens(comments: CommentInput[], schema: Schema): CommentToken[] { + return comments + .map((comment) => { + const commentId = resolveCommentId(comment); + if (!commentId) { + return null; + } + const content = tokenizeCommentText(comment, schema); + return { + commentId, + commentJSON: comment, + content, + }; + }) + .filter((token): token is CommentToken => token !== null); +} + +/** + * Resolves a stable comment identifier from a comment payload. + * + * @param comment Comment payload to inspect. + * @returns Resolved comment id or null when unavailable. + */ +function resolveCommentId(comment: CommentInput): string | null { + return comment.importedId ?? comment.id ?? comment.commentId ?? null; +} + +/** + * Tokenizes a comment body into inline tokens and a flattened text string. + * + * @param comment Comment payload containing `textJson`. + * @param schema Schema used to build ProseMirror nodes. + * @returns Tokenization output for the comment body. + */ +function tokenizeCommentText(comment: CommentInput, schema: Schema): NodeInfo | null { + if (!comment.textJson) { + return null; + } + + const node = schema.nodeFromJSON(comment.textJson as Record); + if (node.type.name !== 'paragraph') { + return { + node, + pos: 0, + depth: 0, + }; + } + + return createParagraphSnapshot(node, 0, 0); +} diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 415193d788..1b1942a437 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -19,7 +19,7 @@ type NodeJSON = ReturnType; /** * Minimal node metadata extracted during document traversal. */ -type BaseNodeInfo = { +export type BaseNodeInfo = { node: PMNode; pos: number; depth: number; @@ -28,7 +28,7 @@ type BaseNodeInfo = { /** * Union describing every node processed by the generic diff. */ -type NodeInfo = BaseNodeInfo | ParagraphNodeInfo; +export type NodeInfo = BaseNodeInfo | ParagraphNodeInfo; interface NodeDiffBase { action: Action; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index 2a5c2bcc93..e237fc99e9 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -338,18 +338,18 @@ describe('getInlineDiff', () => { describe('tokenizeInlineContent', () => { it('handles basic text nodes', () => { - const mockParagraph = createInlineContainer([{ text: 'Hello', start: 0, attrs: { bold: true } }], 5); + const mockParagraph = createInlineContainer([{ text: 'Hello', start: 1, attrs: { bold: true } }], 6); - const tokens = tokenizeInlineContent(mockParagraph, 1); + const tokens = tokenizeInlineContent(mockParagraph, 0); expect(stripTokenOffsets(tokens)).toEqual(buildTextTokens('Hello', { bold: true }, [])); expect(tokens[0]?.offset).toBe(1); expect(tokens[4]?.offset).toBe(5); }); it('handles leaf nodes with leafText', () => { - const mockParagraph = createInlineContainer([{ leafText: () => 'Leaf', start: 0, attrs: { type: 'leaf' } }], 4); + const mockParagraph = createInlineContainer([{ leafText: () => 'Leaf', start: 1, attrs: { type: 'leaf' } }], 5); - const tokens = tokenizeInlineContent(mockParagraph, 1); + const tokens = tokenizeInlineContent(mockParagraph, 0); expect(stripTokenOffsets(tokens)).toEqual(buildTextTokens('Leaf', { type: 'leaf' }, [])); expect(tokens[0]?.offset).toBe(1); expect(tokens[3]?.offset).toBe(4); @@ -357,11 +357,11 @@ describe('tokenizeInlineContent', () => { it('handles mixed content', () => { const mockParagraph = createInlineContainer([ - { text: 'Hello', start: 0, attrs: { bold: true } }, - { leafText: () => 'Leaf', start: 5, attrs: { italic: true } }, + { text: 'Hello', start: 1, attrs: { bold: true } }, + { leafText: () => 'Leaf', start: 6, attrs: { italic: true } }, ]); - const tokens = tokenizeInlineContent(mockParagraph, 1); + const tokens = tokenizeInlineContent(mockParagraph, 0); expect(stripTokenOffsets(tokens)).toEqual([ ...buildTextTokens('Hello', { bold: true }, []), ...buildTextTokens('Leaf', { italic: true }, []), @@ -374,18 +374,18 @@ describe('tokenizeInlineContent', () => { it('handles empty content', () => { const mockParagraph = createInlineContainer([], 0); - const tokens = tokenizeInlineContent(mockParagraph, 1); + const tokens = tokenizeInlineContent(mockParagraph, 0); expect(tokens).toEqual([]); }); it('includes inline nodes that have no textual content', () => { const inlineAttrs = { kind: 'tab', width: 120 }; const mockParagraph = createInlineContainer([ - { inlineNode: { typeName: 'tab', attrs: inlineAttrs }, start: 0 }, - { text: 'Text', start: 1, attrs: { bold: false } }, + { inlineNode: { typeName: 'tab', attrs: inlineAttrs }, start: 1 }, + { text: 'Text', start: 2, attrs: { bold: false } }, ]); - const tokens = tokenizeInlineContent(mockParagraph, 1); + const tokens = tokenizeInlineContent(mockParagraph, 0); expect(tokens[0]).toMatchObject({ kind: 'inlineNode', nodeType: 'tab', @@ -401,17 +401,17 @@ describe('tokenizeInlineContent', () => { it('captures marks from text nodes', () => { const boldMark = { toJSON: () => ({ type: 'bold', attrs: { level: 2 } }) }; - const mockParagraph = createInlineContainer([{ text: 'Hi', start: 0, marks: [boldMark] }], 2); + const mockParagraph = createInlineContainer([{ text: 'Hi', start: 1, marks: [boldMark] }], 3); - const tokens = tokenizeInlineContent(mockParagraph, 1); + const tokens = tokenizeInlineContent(mockParagraph, 0); expect(tokens[0]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); expect(tokens[1]?.marks).toEqual([{ type: 'bold', attrs: { level: 2 } }]); }); it('applies the base offset to token positions', () => { - const mockParagraph = createInlineContainer([{ text: 'Nested', start: 0 }], 6); + const mockParagraph = createInlineContainer([{ text: 'Nested', start: 1 }], 7); - const tokens = tokenizeInlineContent(mockParagraph, 11); + const tokens = tokenizeInlineContent(mockParagraph, 10); expect(stripTokenOffsets(tokens)).toEqual(buildTextTokens('Nested', {}, [])); expect(tokens[0]?.offset).toBe(11); expect(tokens[5]?.offset).toBe(16); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index c52cffeeb8..acde7820b1 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -135,7 +135,7 @@ export function tokenizeInlineContent(pmNode: PMNode, baseOffset = 0): InlineDif } if (nodeText) { - const runNode = pmNode.nodeAt(pos - 1); + const runNode = pos > 0 ? pmNode.nodeAt(pos - 1) : null; const runAttrs = runNode?.attrs ?? {}; const tokenOffset = baseOffset + pos; for (let i = 0; i < nodeText.length; i += 1) { From ea3e4c8e86ba12e7bd65ed3a5ced46b823954b62 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 14:23:17 -0300 Subject: [PATCH 048/125] refactor: change diffNodes signature to facilitate reuse --- .../diffing/algorithm/generic-diffing.test.js | 52 +++++++++++-------- .../diffing/algorithm/generic-diffing.ts | 13 ++--- .../src/extensions/diffing/computeDiff.ts | 4 +- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js index bb2af561e0..f57bd11d9d 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { diffNodes } from './generic-diffing.ts'; +import { diffNodes, normalizeNodes } from './generic-diffing.ts'; const createDocFromNodes = (nodes = []) => { const docNode = { @@ -79,7 +79,7 @@ describe('diffParagraphs', () => { const oldRoot = createDocFromNodes(oldParagraphs); const newRoot = createDocFromNodes(newParagraphs); - const diffs = diffNodes(oldRoot, newRoot); + const diffs = diffNodes(normalizeNodes(oldRoot), normalizeNodes(newRoot)); expect(diffs).toHaveLength(1); expect(diffs[0].action).toBe('modified'); @@ -92,7 +92,7 @@ describe('diffParagraphs', () => { const oldRoot = createDocFromNodes(oldParagraphs); const newRoot = createDocFromNodes(newParagraphs); - const diffs = diffNodes(oldRoot, newRoot); + const diffs = diffNodes(normalizeNodes(oldRoot), normalizeNodes(newRoot)); expect(diffs).toHaveLength(2); expect(diffs[0].action).toBe('deleted'); @@ -111,7 +111,7 @@ describe('diffParagraphs', () => { const oldRoot = createDocFromNodes(oldParagraphs); const newRoot = createDocFromNodes(newParagraphs); - const diffs = diffNodes(oldRoot, newRoot); + const diffs = diffNodes(normalizeNodes(oldRoot), normalizeNodes(newRoot)); expect(diffs).toHaveLength(3); expect(diffs[0].action).toBe('modified'); @@ -123,7 +123,10 @@ describe('diffParagraphs', () => { it('treats paragraph attribute-only changes as modifications', () => { const oldParagraph = createParagraph('Consistent text', { align: 'left' }); const newParagraph = createParagraph('Consistent text', { align: 'right' }); - const diffs = diffNodes(createDocFromNodes([oldParagraph]), createDocFromNodes([newParagraph])); + const diffs = diffNodes( + normalizeNodes(createDocFromNodes([oldParagraph])), + normalizeNodes(createDocFromNodes([newParagraph])), + ); expect(diffs).toHaveLength(1); expect(diffs[0].action).toBe('modified'); @@ -134,7 +137,10 @@ describe('diffParagraphs', () => { it('emits attribute diffs for non-paragraph nodes', () => { const oldHeading = { node: buildSimpleNode('heading', { level: 1 }), pos: 0, depth: 1 }; const newHeading = { node: buildSimpleNode('heading', { level: 2 }), pos: 0, depth: 1 }; - const diffs = diffNodes(createDocFromNodes([oldHeading]), createDocFromNodes([newHeading])); + const diffs = diffNodes( + normalizeNodes(createDocFromNodes([oldHeading])), + normalizeNodes(createDocFromNodes([newHeading])), + ); expect(diffs).toHaveLength(1); expect(diffs[0]).toMatchObject({ @@ -151,12 +157,14 @@ describe('diffParagraphs', () => { const newParagraph = createParagraph('Base paragraph', {}, { pos: 0 }); const insertionPos = oldParagraph.pos + oldParagraph.node.nodeSize; const diffs = diffNodes( - createDocFromNodes([oldParagraph]), - createDocFromNodes([ - newParagraph, - { node: parentNode, pos: insertionPos, depth: 1 }, - { node: childNode, pos: insertionPos + 1, depth: 2 }, - ]), + normalizeNodes(createDocFromNodes([oldParagraph])), + normalizeNodes( + createDocFromNodes([ + newParagraph, + { node: parentNode, pos: insertionPos, depth: 1 }, + { node: childNode, pos: insertionPos + 1, depth: 2 }, + ]), + ), ); const additions = diffs.filter((diff) => diff.action === 'added'); @@ -171,12 +179,14 @@ describe('diffParagraphs', () => { const figurePos = paragraph.pos + paragraph.node.nodeSize; const diffs = diffNodes( - createDocFromNodes([ - paragraph, - { node: parentNode, pos: figurePos, depth: 1 }, - { node: childNode, pos: figurePos + 1, depth: 2 }, - ]), - createDocFromNodes([paragraph]), + normalizeNodes( + createDocFromNodes([ + paragraph, + { node: parentNode, pos: figurePos, depth: 1 }, + { node: childNode, pos: figurePos + 1, depth: 2 }, + ]), + ), + normalizeNodes(createDocFromNodes([paragraph])), ); const deletions = diffs.filter((diff) => diff.action === 'deleted'); @@ -201,7 +211,7 @@ describe('diffParagraphs', () => { { node: persistedRow, pos: 1 + insertedRow.nodeSize, depth: 2 }, ]); - const diffs = diffNodes(oldDoc, newDoc); + const diffs = diffNodes(normalizeNodes(oldDoc), normalizeNodes(newDoc)); const addition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'tableRow'); expect(addition).toBeDefined(); @@ -215,8 +225,8 @@ describe('diffParagraphs', () => { const expectedPos = oldParagraph.pos + oldParagraph.node.nodeSize; const diffs = diffNodes( - createDocFromNodes([oldParagraph]), - createDocFromNodes([newParagraph, { node: headingNode, pos: expectedPos, depth: 1 }]), + normalizeNodes(createDocFromNodes([oldParagraph])), + normalizeNodes(createDocFromNodes([newParagraph, { node: headingNode, pos: expectedPos, depth: 1 }])), ); const addition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'heading'); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 1b1942a437..1c7f4b1aa7 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -65,12 +65,13 @@ interface NodeModifiedDiff extends NodeDiffBase<'modified'> { export type NodeDiff = ParagraphDiff | NodeAddedDiff | NodeDeletedDiff | NodeModifiedDiff; /** - * Produces a sequence diff between two ProseMirror documents, flattening paragraphs for inline-aware comparisons. + * Produces a sequence diff between two normalized node lists. + * + * @param oldNodes Normalized nodes from the old document. + * @param newNodes Normalized nodes from the new document. + * @returns List of node diffs describing the changes. */ -export function diffNodes(oldRoot: PMNode, newRoot: PMNode): NodeDiff[] { - const oldNodes = normalizeNodes(oldRoot); - const newNodes = normalizeNodes(newRoot); - +export function diffNodes(oldNodes: NodeInfo[], newNodes: NodeInfo[]): NodeDiff[] { const addedNodesSet = new Set(); const deletedNodesSet = new Set(); return diffSequences(oldNodes, newNodes, { @@ -88,7 +89,7 @@ export function diffNodes(oldRoot: PMNode, newRoot: PMNode): NodeDiff[] { /** * Traverses a ProseMirror document and converts paragraphs to richer node info objects. */ -function normalizeNodes(pmDoc: PMNode): NodeInfo[] { +export function normalizeNodes(pmDoc: PMNode): NodeInfo[] { const nodes: NodeInfo[] = []; const depthMap = new WeakMap(); depthMap.set(pmDoc, -1); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts index 5c5ebc17e0..fadb897ca0 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.ts +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -1,5 +1,5 @@ import type { Node as PMNode, Schema } from 'prosemirror-model'; -import { diffNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; +import { diffNodes, normalizeNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; /** * Placeholder type for comment diffs until comment diffing is implemented. @@ -34,7 +34,7 @@ export interface DiffResult { export function computeDiff(oldPmDoc: PMNode, newPmDoc: PMNode, schema: Schema): DiffResult { void schema; return { - docDiffs: diffNodes(oldPmDoc, newPmDoc), + docDiffs: diffNodes(normalizeNodes(oldPmDoc), normalizeNodes(newPmDoc)), commentDiffs: [], }; } From e552d6c80192f9c24c23f7ed5fb8d886c22b925a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 14:39:11 -0300 Subject: [PATCH 049/125] feat: allow specifying keys to be ignored when diffing attributes --- .../diffing/algorithm/attributes-diffing.ts | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index 26b8286157..7eaf74074a 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -32,11 +32,13 @@ export interface MarksDiff { * * @param objectA Baseline attributes to compare. * @param objectB Updated attributes to compare. + * @param ignoreKeys Additional attribute keys to ignore. * @returns Structured diff or null when objects are effectively equal. */ export function getAttributesDiff( objectA: Record | null | undefined = {}, objectB: Record | null | undefined = {}, + ignoreKeys: string[] = [], ): AttributesDiff | null { const diff: AttributesDiff = { added: {}, @@ -44,7 +46,8 @@ export function getAttributesDiff( modified: {}, }; - diffObjects(objectA ?? {}, objectB ?? {}, '', diff); + const ignored = new Set([...IGNORED_ATTRIBUTE_KEYS, ...ignoreKeys]); + diffObjects(objectA ?? {}, objectB ?? {}, '', diff, ignored); const hasChanges = Object.keys(diff.added).length > 0 || Object.keys(diff.deleted).length > 0 || Object.keys(diff.modified).length > 0; @@ -126,17 +129,19 @@ export function getMarksDiff( * @param objectB Updated attributes being inspected. * @param basePath Dotted path prefix used for nested keys. * @param diff Aggregated diff being mutated. + * @param ignoreKeys Set of attribute keys to ignore. */ function diffObjects( objectA: Record, objectB: Record, basePath: string, diff: AttributesDiff, + ignoreKeys: Set, ): void { const keys = new Set([...Object.keys(objectA || {}), ...Object.keys(objectB || {})]); for (const key of keys) { - if (IGNORED_ATTRIBUTE_KEYS.has(key)) { + if (ignoreKeys.has(key)) { continue; } @@ -145,12 +150,12 @@ function diffObjects( const hasB = Object.prototype.hasOwnProperty.call(objectB, key); if (hasA && !hasB) { - recordDeletedValue(objectA[key], path, diff); + recordDeletedValue(objectA[key], path, diff, ignoreKeys); continue; } if (!hasA && hasB) { - recordAddedValue(objectB[key], path, diff); + recordAddedValue(objectB[key], path, diff, ignoreKeys); continue; } @@ -158,7 +163,7 @@ function diffObjects( const valueB = objectB[key]; if (isPlainObject(valueA) && isPlainObject(valueB)) { - diffObjects(valueA, valueB, path, diff); + diffObjects(valueA, valueB, path, diff, ignoreKeys); continue; } @@ -183,14 +188,20 @@ function diffObjects( * @param value Value being marked as added. * @param path Dotted attribute path for the value. * @param diff Bucket used to capture additions. + * @param ignoreKeys Set of attribute keys to ignore. */ -function recordAddedValue(value: unknown, path: string, diff: Pick): void { +function recordAddedValue( + value: unknown, + path: string, + diff: Pick, + ignoreKeys: Set, +): void { if (isPlainObject(value)) { for (const [childKey, childValue] of Object.entries(value)) { - if (IGNORED_ATTRIBUTE_KEYS.has(childKey)) { + if (ignoreKeys.has(childKey)) { continue; } - recordAddedValue(childValue, joinPath(path, childKey), diff); + recordAddedValue(childValue, joinPath(path, childKey), diff, ignoreKeys); } return; } @@ -203,14 +214,20 @@ function recordAddedValue(value: unknown, path: string, diff: Pick): void { +function recordDeletedValue( + value: unknown, + path: string, + diff: Pick, + ignoreKeys: Set, +): void { if (isPlainObject(value)) { for (const [childKey, childValue] of Object.entries(value)) { - if (IGNORED_ATTRIBUTE_KEYS.has(childKey)) { + if (ignoreKeys.has(childKey)) { continue; } - recordDeletedValue(childValue, joinPath(path, childKey), diff); + recordDeletedValue(childValue, joinPath(path, childKey), diff, ignoreKeys); } return; } From fb6bbfd10e2d3f14c34cfe74af14e4837703fc39 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 14:43:43 -0300 Subject: [PATCH 050/125] feat: implement comments diffing hooks --- .../diffing/algorithm/comment-diffing.test.ts | 178 ++++++++++++++++- .../diffing/algorithm/comment-diffing.ts | 189 +++++++++++++++++- 2 files changed, 364 insertions(+), 3 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts index 9d0be9e342..6dc000f312 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts @@ -1,6 +1,15 @@ import { describe, expect, it } from 'vitest'; import { Schema } from 'prosemirror-model'; -import { buildCommentTokens } from './comment-diffing.ts'; +import { + buildAddedCommentDiff, + buildCommentTokens, + buildDeletedCommentDiff, + buildModifiedCommentDiff, + canTreatAsModification, + commentComparator, + diffComments, + shouldProcessEqualAsModification, +} from './comment-diffing.ts'; /** * Builds a minimal schema suitable for comment text tokenization. @@ -28,6 +37,14 @@ const buildCommentTextJson = (text) => ({ content: [{ type: 'text', text }], }); +/** + * Returns the first token for convenience in tests. + * + * @param {Array} tokens + * @returns {import('./comment-diffing.ts').CommentToken} + */ +const getFirstToken = (tokens) => tokens[0]; + describe('buildCommentTokens', () => { it('builds tokens and text for comments with commentId', () => { const schema = createSchema(); @@ -95,3 +112,162 @@ describe('buildCommentTokens', () => { expect(tokens).toEqual([]); }); }); + +describe('comment diff helpers', () => { + it('matches comments by id', () => { + const schema = createSchema(); + const oldToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('A') }], schema), + ); + const newToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('B') }], schema), + ); + + expect(commentComparator(oldToken, newToken)).toBe(true); + }); + + it('treats metadata changes as modifications', () => { + const schema = createSchema(); + const oldToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Text'), isDone: false }], schema), + ); + const newToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Text'), isDone: true }], schema), + ); + + expect(shouldProcessEqualAsModification(oldToken, newToken)).toBe(true); + }); + + it('treats content changes as modifications', () => { + const schema = createSchema(); + const oldToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Old') }], schema), + ); + const newToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('New') }], schema), + ); + + expect(shouldProcessEqualAsModification(oldToken, newToken)).toBe(true); + }); + + it('returns false for identical comments', () => { + const schema = createSchema(); + const oldToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Same') }], schema), + ); + const newToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Same') }], schema), + ); + + expect(shouldProcessEqualAsModification(oldToken, newToken)).toBe(false); + }); + + it('does not treat insert/delete pairs as modifications', () => { + expect(canTreatAsModification()).toBe(false); + }); + + it('builds added comment diffs with text', () => { + const schema = createSchema(); + const token = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Added') }], schema), + ); + + expect(buildAddedCommentDiff(token)).toEqual({ + action: 'added', + nodeType: 'comment', + commentId: 'c-1', + commentJSON: token.commentJSON, + text: 'Added', + }); + }); + + it('builds deleted comment diffs with old text', () => { + const schema = createSchema(); + const token = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Deleted') }], schema), + ); + + expect(buildDeletedCommentDiff(token)).toEqual({ + action: 'deleted', + nodeType: 'comment', + commentId: 'c-1', + commentJSON: token.commentJSON, + oldText: 'Deleted', + }); + }); + + it('builds modified comment diffs when content changes', () => { + const schema = createSchema(); + const oldToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('Old') }], schema), + ); + const newToken = getFirstToken( + buildCommentTokens([{ commentId: 'c-1', textJson: buildCommentTextJson('New') }], schema), + ); + + const diff = buildModifiedCommentDiff(oldToken, newToken); + expect(diff).toMatchObject({ + action: 'modified', + nodeType: 'comment', + commentId: 'c-1', + oldText: 'Old', + newText: 'New', + }); + expect(diff?.contentDiff).not.toEqual([]); + expect(diff?.attrsDiff).toBeNull(); + }); +}); + +describe('diffComments', () => { + it('returns added comment diffs for new comments', () => { + const schema = createSchema(); + const diffs = diffComments([], [{ commentId: 'c-1', textJson: buildCommentTextJson('Added') }], schema); + + expect(diffs).toHaveLength(1); + expect(diffs[0]).toMatchObject({ + action: 'added', + nodeType: 'comment', + commentId: 'c-1', + }); + }); + + it('returns deleted comment diffs for removed comments', () => { + const schema = createSchema(); + const diffs = diffComments([{ commentId: 'c-1', textJson: buildCommentTextJson('Removed') }], [], schema); + + expect(diffs).toHaveLength(1); + expect(diffs[0]).toMatchObject({ + action: 'deleted', + nodeType: 'comment', + commentId: 'c-1', + }); + }); + + it('returns modified comment diffs for content changes', () => { + const schema = createSchema(); + const diffs = diffComments( + [{ commentId: 'c-1', textJson: buildCommentTextJson('Old') }], + [{ commentId: 'c-1', textJson: buildCommentTextJson('New') }], + schema, + ); + + expect(diffs).toHaveLength(1); + expect(diffs[0]).toMatchObject({ + action: 'modified', + nodeType: 'comment', + commentId: 'c-1', + }); + expect(diffs[0].contentDiff).not.toEqual([]); + }); + + it('returns empty diffs for identical comments', () => { + const schema = createSchema(); + const diffs = diffComments( + [{ commentId: 'c-1', textJson: buildCommentTextJson('Same') }], + [{ commentId: 'c-1', textJson: buildCommentTextJson('Same') }], + schema, + ); + + expect(diffs).toEqual([]); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts index 02e8f52212..4f1314f147 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts @@ -1,6 +1,8 @@ import type { Schema } from 'prosemirror-model'; -import type { NodeInfo } from './generic-diffing.ts'; -import { createParagraphSnapshot } from './paragraph-diffing.ts'; +import { diffNodes, type NodeDiff, type NodeInfo } from './generic-diffing.ts'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; +import { createParagraphSnapshot, type ParagraphNodeInfo } from './paragraph-diffing.ts'; +import { diffSequences } from './sequence-diffing.ts'; /** * Raw comment data used for diffing comment content and metadata. @@ -30,6 +32,48 @@ export interface CommentToken { content: NodeInfo | null; } +/** + * Base shape shared by every comment diff payload. + */ +export interface CommentDiffBase { + action: Action; + nodeType: 'comment'; + commentId: string; +} + +/** + * Diff payload describing an added comment. + */ +export type CommentAddedDiff = CommentDiffBase<'added'> & { + commentJSON: CommentInput; + text: string; +}; + +/** + * Diff payload describing a deleted comment. + */ +export type CommentDeletedDiff = CommentDiffBase<'deleted'> & { + commentJSON: CommentInput; + oldText: string; +}; + +/** + * Diff payload describing a modified comment. + */ +export type CommentModifiedDiff = CommentDiffBase<'modified'> & { + oldCommentJSON: CommentInput; + newCommentJSON: CommentInput; + oldText: string; + newText: string; + contentDiff: NodeDiff[]; + attrsDiff: AttributesDiff | null; +}; + +/** + * Union of every diff variant the comment diffing logic can produce. + */ +export type CommentDiff = CommentAddedDiff | CommentDeletedDiff | CommentModifiedDiff; + /** * Builds normalized tokens for diffing comment content. * @@ -54,6 +98,130 @@ export function buildCommentTokens(comments: CommentInput[], schema: Schema): Co .filter((token): token is CommentToken => token !== null); } +/** + * Computes diffs between two comment lists. + * + * @param oldComments Previous comment list. + * @param newComments Updated comment list. + * @param schema Schema used to parse comment bodies. + * @returns Comment diff payloads. + */ +export function diffComments(oldComments: CommentInput[], newComments: CommentInput[], schema: Schema): CommentDiff[] { + const oldTokens = buildCommentTokens(oldComments, schema); + const newTokens = buildCommentTokens(newComments, schema); + + return diffSequences(oldTokens, newTokens, { + comparator: commentComparator, + shouldProcessEqualAsModification, + canTreatAsModification: () => false, + buildAdded: (token) => buildAddedCommentDiff(token), + buildDeleted: (token) => buildDeletedCommentDiff(token), + buildModified: (oldToken, newToken) => buildModifiedCommentDiff(oldToken, newToken), + }); +} + +/** + * Compares two comment tokens to determine if they represent the same comment. + * + * @param oldToken Comment token from the old list. + * @param newToken Comment token from the new list. + * @returns True when comment ids match. + */ +export function commentComparator(oldToken: CommentToken, newToken: CommentToken): boolean { + return oldToken.commentId === newToken.commentId; +} + +/** + * Determines whether equal comment tokens should still be treated as modified. + * + * @param oldToken Comment token from the old list. + * @param newToken Comment token from the new list. + * @returns True when content or metadata differs. + */ +export function shouldProcessEqualAsModification(oldToken: CommentToken, newToken: CommentToken): boolean { + const attrsDiff = getAttributesDiff(oldToken.commentJSON, newToken.commentJSON, ['textJson', 'commentId']); + if (attrsDiff) { + return true; + } + + const oldSignature = oldToken.content ? JSON.stringify(oldToken.content.node.toJSON()) : ''; + const newSignature = newToken.content ? JSON.stringify(newToken.content.node.toJSON()) : ''; + return oldSignature !== newSignature; +} + +/** + * Determines whether delete/insert pairs should be treated as modifications. + * + * @returns False because comment ids are treated as stable identities. + */ +export function canTreatAsModification(): boolean { + return false; +} + +/** + * Builds a normalized payload describing a comment addition. + * + * @param comment Comment token being added. + * @returns Diff payload for the added comment. + */ +export function buildAddedCommentDiff(comment: CommentToken): CommentAddedDiff { + return { + action: 'added', + nodeType: 'comment', + commentId: comment.commentId, + commentJSON: comment.commentJSON, + text: getCommentText(comment.content), + }; +} + +/** + * Builds a normalized payload describing a comment deletion. + * + * @param comment Comment token being deleted. + * @returns Diff payload for the deleted comment. + */ +export function buildDeletedCommentDiff(comment: CommentToken): CommentDeletedDiff { + return { + action: 'deleted', + nodeType: 'comment', + commentId: comment.commentId, + commentJSON: comment.commentJSON, + oldText: getCommentText(comment.content), + }; +} + +/** + * Builds the payload for a comment modification, including inline diffs when possible. + * + * @param oldComment Comment token from the old list. + * @param newComment Comment token from the new list. + * @returns Diff payload or null when no changes exist. + */ +export function buildModifiedCommentDiff( + oldComment: CommentToken, + newComment: CommentToken, +): CommentModifiedDiff | null { + const contentDiff = + oldComment.content && newComment.content ? diffNodes([oldComment.content], [newComment.content]) : []; + const attrsDiff = getAttributesDiff(oldComment.commentJSON, newComment.commentJSON, ['textJson', 'commentId']); + + if (contentDiff.length === 0 && !attrsDiff) { + return null; + } + + return { + action: 'modified', + nodeType: 'comment', + commentId: oldComment.commentId, + oldCommentJSON: oldComment.commentJSON, + newCommentJSON: newComment.commentJSON, + oldText: getCommentText(oldComment.content), + newText: getCommentText(newComment.content), + contentDiff, + attrsDiff, + }; +} + /** * Resolves a stable comment identifier from a comment payload. * @@ -64,6 +232,23 @@ function resolveCommentId(comment: CommentInput): string | null { return comment.importedId ?? comment.id ?? comment.commentId ?? null; } +/** + * Returns the flattened comment text when the content is a paragraph. + * + * @param content Comment content payload. + * @returns Flattened text string. + */ +function getCommentText(content: NodeInfo | null): string { + if (!content) { + return ''; + } + if (content.node.type.name === 'paragraph') { + const paragraphContent = content as ParagraphNodeInfo; + return paragraphContent.fullText; + } + return ''; +} + /** * Tokenizes a comment body into inline tokens and a flattened text string. * From 6d829eb76c8574a2fe820b362a760bc460804096 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 15:03:39 -0300 Subject: [PATCH 051/125] feat: update compareDocuments command to support diffing comments --- .../extensions/diffing/computeDiff.test.js | 63 +++++++++++++++--- .../src/extensions/diffing/computeDiff.ts | 16 +++-- .../src/extensions/diffing/diffing.js | 11 ++- .../src/tests/data/diff_after8.docx | Bin 0 -> 17887 bytes .../src/tests/data/diff_before8.docx | Bin 0 -> 17648 bytes 5 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 packages/super-editor/src/tests/data/diff_after8.docx create mode 100644 packages/super-editor/src/tests/data/diff_before8.docx diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index 512c12ec5f..f0cbaaa959 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -9,7 +9,7 @@ import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers * Loads a DOCX fixture and returns the ProseMirror document and schema. * * @param {string} name DOCX fixture filename. - * @returns {Promise<{ doc: import('prosemirror-model').Node; schema: import('prosemirror-model').Schema }>} + * @returns {Promise<{ doc: import('prosemirror-model').Node; schema: import('prosemirror-model').Schema; comments: Array> }>} */ const getDocument = async (name) => { const buffer = await getTestDataAsBuffer(name); @@ -27,7 +27,7 @@ const getDocument = async (name) => { annotations: true, }); - return { doc: editor.state.doc, schema: editor.schema }; + return { doc: editor.state.doc, schema: editor.schema, comments: editor.converter.comments }; }; /** @@ -287,12 +287,59 @@ describe('Diff', () => { expect(firstCellDiff?.contentDiff?.[0]?.text).toBe('First '); }); - it('Compare a complex document with table edits and tracked formatting', async () => { - const { doc: docBefore, schema } = await getDocument('diff_before8.docx'); - const { doc: docAfter } = await getDocument('diff_after8.docx'); + it('Compare documents with comments and tracked changes', async () => { + const { doc: docBefore, schema, comments: commentsBefore } = await getDocument('diff_before8.docx'); + const { doc: docAfter, comments: commentsAfter } = await getDocument('diff_after8.docx'); - const { docDiffs } = computeDiff(docBefore, docAfter, schema); - const diffs = docDiffs; - console.log(JSON.stringify(diffs, null, 2)); + const { docDiffs, commentDiffs } = computeDiff(docBefore, docAfter, schema, commentsBefore, commentsAfter); + + expect(docDiffs.length).toBeGreaterThan(0); + expect(docDiffs.filter((diff) => diff.action === 'modified')).toHaveLength(2); + expect(commentDiffs).toHaveLength(2); + + const commentAnchorDiff = docDiffs.find( + (diff) => diff.action === 'modified' && diff.oldText === 'Here’s some text. It has a comment.', + ); + expect(commentAnchorDiff).toBeDefined(); + expect(commentAnchorDiff?.contentDiff?.some((change) => change.kind === 'inlineNode')).toBe(true); + expect( + commentAnchorDiff?.contentDiff?.some( + (change) => change.kind === 'inlineNode' && change.nodeType === 'commentRangeStart', + ), + ).toBe(true); + expect( + commentAnchorDiff?.contentDiff?.some( + (change) => change.kind === 'text' && change.marksDiff?.deleted?.some((mark) => mark.name === 'commentMark'), + ), + ).toBe(true); + + const trackedChangeDiff = docDiffs.find( + (diff) => diff.action === 'modified' && diff.oldText === 'I will add a comment to this one too.', + ); + expect(trackedChangeDiff).toBeDefined(); + expect( + trackedChangeDiff?.contentDiff?.some( + (change) => change.kind === 'text' && change.marksDiff?.added?.some((mark) => mark.name === 'commentMark'), + ), + ).toBe(true); + expect( + trackedChangeDiff?.contentDiff?.some( + (change) => change.kind === 'text' && change.marksDiff?.added?.some((mark) => mark.name === 'trackDelete'), + ), + ).toBe(true); + + const modifiedComment = commentDiffs.find( + (diff) => diff.action === 'modified' && diff.nodeType === 'comment' && diff.commentId === '0', + ); + expect(modifiedComment).toBeDefined(); + expect(modifiedComment?.oldText).toBe('Old comment.'); + expect(modifiedComment?.newText).toBe('Old comment.'); + expect(modifiedComment?.attrsDiff?.modified?.isDone).toEqual({ from: false, to: true }); + + const addedComment = commentDiffs.find( + (diff) => diff.action === 'added' && diff.nodeType === 'comment' && diff.commentId === '1', + ); + expect(addedComment).toBeDefined(); + expect(addedComment?.text).toBe('New comment'); }); }); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts index fadb897ca0..8d6822d0d7 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.ts +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -1,4 +1,5 @@ import type { Node as PMNode, Schema } from 'prosemirror-model'; +import { diffComments, type CommentInput, type CommentDiff } from './algorithm/comment-diffing.ts'; import { diffNodes, normalizeNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; /** @@ -28,13 +29,20 @@ export interface DiffResult { * * @param oldPmDoc The previous ProseMirror document. * @param newPmDoc The updated ProseMirror document. - * @param schema The schema used to interpret document nodes (unused for now). + * @param schema The schema used to interpret document nodes. + * @param oldComments Comment list from the old document. + * @param newComments Comment list from the new document. * @returns Object containing document and comment diffs. */ -export function computeDiff(oldPmDoc: PMNode, newPmDoc: PMNode, schema: Schema): DiffResult { - void schema; +export function computeDiff( + oldPmDoc: PMNode, + newPmDoc: PMNode, + schema: Schema, + oldComments: CommentInput[] = [], + newComments: CommentInput[] = [], +): DiffResult { return { docDiffs: diffNodes(normalizeNodes(oldPmDoc), normalizeNodes(newPmDoc)), - commentDiffs: [], + commentDiffs: diffComments(oldComments, newComments, schema), }; } diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 30815e0582..9317a7e38a 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -16,12 +16,19 @@ export const Diffing = Extension.create({ * `pos` anchor in the correct order. * * @param {import('prosemirror-model').Node} updatedDocument + * @param {import('./algorithm/comment-diffing.ts').CommentInput[]} [updatedComments] * @returns {import('./computeDiff.ts').DiffResult} */ compareDocuments: - (updatedDocument) => + (updatedDocument, updatedComments = []) => ({ state }) => { - const diffs = computeDiff(state.doc, updatedDocument, state.schema); + const diffs = computeDiff( + state.doc, + updatedDocument, + state.schema, + this.editor.converter?.comments ?? [], + updatedComments, + ); return diffs; }, }; diff --git a/packages/super-editor/src/tests/data/diff_after8.docx b/packages/super-editor/src/tests/data/diff_after8.docx new file mode 100644 index 0000000000000000000000000000000000000000..1202888efd0ed1dced2ad4110b3d42f1cb09c4f1 GIT binary patch literal 17887 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 Z4=Kq)0FCW8jzR_?0W<$YLcjg@e*j Date: Wed, 31 Dec 2025 15:23:58 -0300 Subject: [PATCH 052/125] test: move test files to separate directory --- .../src/extensions/diffing/computeDiff.test.js | 2 +- .../src/tests/data/{ => diffing}/diff_after.docx | Bin .../src/tests/data/{ => diffing}/diff_after2.docx | Bin .../src/tests/data/{ => diffing}/diff_after3.docx | Bin .../src/tests/data/{ => diffing}/diff_after4.docx | Bin .../src/tests/data/{ => diffing}/diff_after5.docx | Bin .../src/tests/data/{ => diffing}/diff_after6.docx | Bin .../src/tests/data/{ => diffing}/diff_after7.docx | Bin .../src/tests/data/{ => diffing}/diff_after8.docx | Bin .../src/tests/data/{ => diffing}/diff_before.docx | Bin .../src/tests/data/{ => diffing}/diff_before2.docx | Bin .../src/tests/data/{ => diffing}/diff_before3.docx | Bin .../src/tests/data/{ => diffing}/diff_before4.docx | Bin .../src/tests/data/{ => diffing}/diff_before5.docx | Bin .../src/tests/data/{ => diffing}/diff_before6.docx | Bin .../src/tests/data/{ => diffing}/diff_before7.docx | Bin .../src/tests/data/{ => diffing}/diff_before8.docx | Bin 17 files changed, 1 insertion(+), 1 deletion(-) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after2.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after3.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after4.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after5.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after6.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after7.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_after8.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before2.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before3.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before4.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before5.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before6.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before7.docx (100%) rename packages/super-editor/src/tests/data/{ => diffing}/diff_before8.docx (100%) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index f0cbaaa959..605fef5ae6 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -12,7 +12,7 @@ import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers * @returns {Promise<{ doc: import('prosemirror-model').Node; schema: import('prosemirror-model').Schema; comments: Array> }>} */ const getDocument = async (name) => { - const buffer = await getTestDataAsBuffer(name); + const buffer = await getTestDataAsBuffer(`diffing/${name}`); const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); const editor = new Editor({ diff --git a/packages/super-editor/src/tests/data/diff_after.docx b/packages/super-editor/src/tests/data/diffing/diff_after.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after.docx rename to packages/super-editor/src/tests/data/diffing/diff_after.docx diff --git a/packages/super-editor/src/tests/data/diff_after2.docx b/packages/super-editor/src/tests/data/diffing/diff_after2.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after2.docx rename to packages/super-editor/src/tests/data/diffing/diff_after2.docx diff --git a/packages/super-editor/src/tests/data/diff_after3.docx b/packages/super-editor/src/tests/data/diffing/diff_after3.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after3.docx rename to packages/super-editor/src/tests/data/diffing/diff_after3.docx diff --git a/packages/super-editor/src/tests/data/diff_after4.docx b/packages/super-editor/src/tests/data/diffing/diff_after4.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after4.docx rename to packages/super-editor/src/tests/data/diffing/diff_after4.docx diff --git a/packages/super-editor/src/tests/data/diff_after5.docx b/packages/super-editor/src/tests/data/diffing/diff_after5.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after5.docx rename to packages/super-editor/src/tests/data/diffing/diff_after5.docx diff --git a/packages/super-editor/src/tests/data/diff_after6.docx b/packages/super-editor/src/tests/data/diffing/diff_after6.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after6.docx rename to packages/super-editor/src/tests/data/diffing/diff_after6.docx diff --git a/packages/super-editor/src/tests/data/diff_after7.docx b/packages/super-editor/src/tests/data/diffing/diff_after7.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after7.docx rename to packages/super-editor/src/tests/data/diffing/diff_after7.docx diff --git a/packages/super-editor/src/tests/data/diff_after8.docx b/packages/super-editor/src/tests/data/diffing/diff_after8.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_after8.docx rename to packages/super-editor/src/tests/data/diffing/diff_after8.docx diff --git a/packages/super-editor/src/tests/data/diff_before.docx b/packages/super-editor/src/tests/data/diffing/diff_before.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before.docx rename to packages/super-editor/src/tests/data/diffing/diff_before.docx diff --git a/packages/super-editor/src/tests/data/diff_before2.docx b/packages/super-editor/src/tests/data/diffing/diff_before2.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before2.docx rename to packages/super-editor/src/tests/data/diffing/diff_before2.docx diff --git a/packages/super-editor/src/tests/data/diff_before3.docx b/packages/super-editor/src/tests/data/diffing/diff_before3.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before3.docx rename to packages/super-editor/src/tests/data/diffing/diff_before3.docx diff --git a/packages/super-editor/src/tests/data/diff_before4.docx b/packages/super-editor/src/tests/data/diffing/diff_before4.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before4.docx rename to packages/super-editor/src/tests/data/diffing/diff_before4.docx diff --git a/packages/super-editor/src/tests/data/diff_before5.docx b/packages/super-editor/src/tests/data/diffing/diff_before5.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before5.docx rename to packages/super-editor/src/tests/data/diffing/diff_before5.docx diff --git a/packages/super-editor/src/tests/data/diff_before6.docx b/packages/super-editor/src/tests/data/diffing/diff_before6.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before6.docx rename to packages/super-editor/src/tests/data/diffing/diff_before6.docx diff --git a/packages/super-editor/src/tests/data/diff_before7.docx b/packages/super-editor/src/tests/data/diffing/diff_before7.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before7.docx rename to packages/super-editor/src/tests/data/diffing/diff_before7.docx diff --git a/packages/super-editor/src/tests/data/diff_before8.docx b/packages/super-editor/src/tests/data/diffing/diff_before8.docx similarity index 100% rename from packages/super-editor/src/tests/data/diff_before8.docx rename to packages/super-editor/src/tests/data/diffing/diff_before8.docx From e9e97adfe189b28f485dc87a4cde7d0e4f5e5684 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 31 Dec 2025 15:37:51 -0300 Subject: [PATCH 053/125] docs: improve TSDoc comments for interfaces --- .../diffing/algorithm/attributes-diffing.ts | 6 ++++++ .../diffing/algorithm/comment-diffing.ts | 13 +++++++++++++ .../diffing/algorithm/diff-utils.ts | 3 +++ .../diffing/algorithm/generic-diffing.ts | 11 +++++++++++ .../diffing/algorithm/inline-diffing.ts | 16 ++++++++++++++++ .../diffing/algorithm/paragraph-diffing.ts | 19 +++++++++++++++++++ .../diffing/algorithm/sequence-diffing.ts | 7 +++++++ .../src/extensions/diffing/computeDiff.ts | 5 ----- 8 files changed, 75 insertions(+), 5 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index 7eaf74074a..06285514d2 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -12,8 +12,11 @@ export interface AttributeChange { * Aggregated attribute diff broken down into added, deleted, and modified dotted paths. */ export interface AttributesDiff { + /** Attributes added in the new payload. */ added: Record; + /** Attributes removed from the old payload. */ deleted: Record; + /** Attributes that changed values between old and new payloads. */ modified: Record; } @@ -21,8 +24,11 @@ export interface AttributesDiff { * Aggregated marks diff broken down into added, deleted, and modified marks. */ export interface MarksDiff { + /** Marks added in the new payload. */ added: { name: string; attrs: Record }[]; + /** Marks removed from the old payload. */ deleted: { name: string; attrs: Record }[]; + /** Marks whose attributes changed between old and new payloads. */ modified: { name: string; oldAttrs: Record; newAttrs: Record }[]; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts index 4f1314f147..3357cc4843 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts @@ -36,8 +36,11 @@ export interface CommentToken { * Base shape shared by every comment diff payload. */ export interface CommentDiffBase { + /** Change type for this comment. */ action: Action; + /** Node type identifier for comment diffs. */ nodeType: 'comment'; + /** Resolved comment identifier (importedId → id → commentId). */ commentId: string; } @@ -45,7 +48,9 @@ export interface CommentDiffBase & { + /** Serialized comment payload inserted into the document. */ commentJSON: CommentInput; + /** Plain-text representation of the comment body. */ text: string; }; @@ -53,7 +58,9 @@ export type CommentAddedDiff = CommentDiffBase<'added'> & { * Diff payload describing a deleted comment. */ export type CommentDeletedDiff = CommentDiffBase<'deleted'> & { + /** Serialized comment payload removed from the document. */ commentJSON: CommentInput; + /** Plain-text representation of the removed comment body. */ oldText: string; }; @@ -61,11 +68,17 @@ export type CommentDeletedDiff = CommentDiffBase<'deleted'> & { * Diff payload describing a modified comment. */ export type CommentModifiedDiff = CommentDiffBase<'modified'> & { + /** Serialized comment payload before the change. */ oldCommentJSON: CommentInput; + /** Serialized comment payload after the change. */ newCommentJSON: CommentInput; + /** Plain-text content before the change. */ oldText: string; + /** Plain-text content after the change. */ newText: string; + /** Node-level diff for the comment body content. */ contentDiff: NodeDiff[]; + /** Attribute-level diff for comment metadata. */ attrsDiff: AttributesDiff | null; }; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts index 3d92e934f1..0276dc42b6 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts @@ -1,8 +1,11 @@ import type { Node as PMNode } from 'prosemirror-model'; interface NodePositionInfo { + /** ProseMirror node reference. */ node: PMNode; + /** Absolute position of the node in the document. */ pos: number; + /** Depth of the node within the document tree. */ depth: number; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 1c7f4b1aa7..7af4418cb8 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -20,8 +20,11 @@ type NodeJSON = ReturnType; * Minimal node metadata extracted during document traversal. */ export type BaseNodeInfo = { + /** ProseMirror node reference. */ node: PMNode; + /** Absolute position of the node in the document. */ pos: number; + /** Depth of the node within the document tree. */ depth: number; }; @@ -31,8 +34,11 @@ export type BaseNodeInfo = { export type NodeInfo = BaseNodeInfo | ParagraphNodeInfo; interface NodeDiffBase { + /** Change type for this node. */ action: Action; + /** ProseMirror node type name. */ nodeType: string; + /** Anchor position in the old document for replaying diffs. */ pos: number; } @@ -40,6 +46,7 @@ interface NodeDiffBase { * Diff payload describing an inserted non-paragraph node. */ interface NodeAddedDiff extends NodeDiffBase<'added'> { + /** Serialized node payload inserted into the document. */ nodeJSON: NodeJSON; } @@ -47,6 +54,7 @@ interface NodeAddedDiff extends NodeDiffBase<'added'> { * Diff payload describing a deleted non-paragraph node. */ interface NodeDeletedDiff extends NodeDiffBase<'deleted'> { + /** Serialized node payload removed from the document. */ nodeJSON: NodeJSON; } @@ -54,8 +62,11 @@ interface NodeDeletedDiff extends NodeDiffBase<'deleted'> { * Diff payload describing an attribute-only change on non-paragraph nodes. */ interface NodeModifiedDiff extends NodeDiffBase<'modified'> { + /** Serialized node payload before the change. */ oldNodeJSON: NodeJSON; + /** Serialized node payload after the change. */ newNodeJSON: NodeJSON; + /** Attribute-level diff for the node. */ attrsDiff: AttributesDiff; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index acde7820b1..d540ce8e7d 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -92,21 +92,37 @@ type RawDiff = RawTextDiff | RawInlineNodeDiff; * Final grouped inline diff exposed to downstream consumers. */ export interface InlineDiffResult { + /** Change type for this inline segment. */ action: InlineAction; + /** Token kind associated with the diff. */ kind: 'text' | 'inlineNode'; + /** Start position in the old document (or null when unknown). */ startPos: number | null; + /** End position in the old document (or null when unknown). */ endPos: number | null; + /** Inserted text for additions. */ text?: string; + /** Removed text for deletions/modifications. */ oldText?: string; + /** Inserted text for modifications. */ newText?: string; + /** Run attributes for added/deleted text. */ runAttrs?: Record; + /** Attribute diff for modified runs. */ runAttrsDiff?: AttributesDiff | null; + /** Marks applied to added/deleted text. */ marks?: Record[]; + /** Mark diff for modified text. */ marksDiff?: MarksDiff | null; + /** Inline node type name for node diffs. */ nodeType?: string; + /** Serialized inline node payload for additions/deletions. */ nodeJSON?: NodeJSON; + /** Serialized inline node payload before the change. */ oldNodeJSON?: NodeJSON; + /** Serialized inline node payload after the change. */ newNodeJSON?: NodeJSON; + /** Attribute diff for modified inline nodes. */ attrsDiff?: AttributesDiff | null; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 2b15154de7..20d30b876e 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -11,11 +11,17 @@ const MIN_LENGTH_FOR_SIMILARITY = 4; type NodeJSON = ReturnType; export interface ParagraphNodeInfo { + /** ProseMirror paragraph node reference. */ node: PMNode; + /** Absolute position of the paragraph in the document. */ pos: number; + /** Depth of the paragraph within the document tree. */ depth: number; + /** Flattened inline tokens for inline diffing. */ text: InlineDiffToken[]; + /** Absolute end position used for trailing inserts. */ endPos: number; + /** Plain-text representation of the paragraph content. */ fullText: string; } @@ -23,8 +29,11 @@ export interface ParagraphNodeInfo { * Base shape shared by every paragraph diff payload. */ interface ParagraphDiffBase { + /** Change type for this paragraph. */ action: Action; + /** Node type name (always `paragraph`). */ nodeType: string; + /** Anchor position in the old document for replaying diffs. */ pos: number; } @@ -32,7 +41,9 @@ interface ParagraphDiffBase { * Diff payload produced when a paragraph is inserted. */ type AddedParagraphDiff = ParagraphDiffBase<'added'> & { + /** Serialized paragraph payload inserted into the document. */ nodeJSON: NodeJSON; + /** Plain-text content of the inserted paragraph. */ text: string; }; @@ -40,7 +51,9 @@ type AddedParagraphDiff = ParagraphDiffBase<'added'> & { * Diff payload produced when a paragraph is deleted. */ type DeletedParagraphDiff = ParagraphDiffBase<'deleted'> & { + /** Serialized paragraph payload removed from the document. */ nodeJSON: NodeJSON; + /** Plain-text content of the removed paragraph. */ oldText: string; }; @@ -48,11 +61,17 @@ type DeletedParagraphDiff = ParagraphDiffBase<'deleted'> & { * Diff payload emitted when a paragraph changes, including inline edits. */ type ModifiedParagraphDiff = ParagraphDiffBase<'modified'> & { + /** Serialized paragraph payload before the change. */ oldNodeJSON: NodeJSON; + /** Serialized paragraph payload after the change. */ newNodeJSON: NodeJSON; + /** Plain-text content before the change. */ oldText: string; + /** Plain-text content after the change. */ newText: string; + /** Inline diff operations within the paragraph. */ contentDiff: InlineDiffResult[]; + /** Attribute-level diff for the paragraph. */ attrsDiff: AttributesDiff | null; }; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts index 136184bdc6..81e8b20996 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts @@ -17,12 +17,19 @@ type OperationStep = * Hooks and comparators used to translate raw Myers operations into domain-specific diffs. */ export interface SequenceDiffOptions { + /** Comparator to determine whether two items are equivalent. */ comparator?: Comparator; + /** Builder invoked for insertions in the new sequence. */ buildAdded: (item: T, oldIdx: number, previousOldItem: T | undefined, newIdx: number) => Added | null | undefined; + /** Builder invoked for deletions in the old sequence. */ buildDeleted: (item: T, oldIdx: number, newIdx: number) => Deleted | null | undefined; + /** Builder invoked for modifications between old and new items. */ buildModified: (oldItem: T, newItem: T, oldIdx: number, newIdx: number) => Modified | null | undefined; + /** Predicate to emit modifications even when items compare equal. */ shouldProcessEqualAsModification?: (oldItem: T, newItem: T, oldIdx: number, newIdx: number) => boolean; + /** Predicate to treat delete+insert pairs as a modification. */ canTreatAsModification?: (deletedItem: T, insertedItem: T, oldIdx: number, newIdx: number) => boolean; + /** Optional reordering hook for Myers operations before mapping. */ reorderOperations?: (operations: MyersOperation[]) => MyersOperation[]; } diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts index 8d6822d0d7..6b686905d7 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.ts +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -2,11 +2,6 @@ import type { Node as PMNode, Schema } from 'prosemirror-model'; import { diffComments, type CommentInput, type CommentDiff } from './algorithm/comment-diffing.ts'; import { diffNodes, normalizeNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; -/** - * Placeholder type for comment diffs until comment diffing is implemented. - */ -export type CommentDiff = Record; - /** * Result payload for document diffing. */ From 942f7e752da7550b004d10c4adcf8b0e8ff55e20 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 11:47:11 -0300 Subject: [PATCH 054/125] feat: initialize directory structure for diff replays --- .../src/extensions/diffing/replay/index.ts | 7 ++++++ .../diffing/replay/marks-from-diff.ts | 6 +++++ .../extensions/diffing/replay/replay-attrs.ts | 6 +++++ .../extensions/diffing/replay/replay-doc.ts | 6 +++++ .../diffing/replay/replay-inline.ts | 6 +++++ .../diffing/replay/replay-non-paragraph.ts | 6 +++++ .../diffing/replay/replay-paragraph.ts | 6 +++++ .../extensions/diffing/replay/replay-types.ts | 8 +++++++ .../extensions/diffing/replayDiffs.test.js | 23 ++++++++++++++++++ .../src/extensions/diffing/replayDiffs.ts | 24 +++++++++++++++++++ 10 files changed, 98 insertions(+) create mode 100644 packages/super-editor/src/extensions/diffing/replay/index.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-doc.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-inline.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-types.ts create mode 100644 packages/super-editor/src/extensions/diffing/replayDiffs.test.js create mode 100644 packages/super-editor/src/extensions/diffing/replayDiffs.ts diff --git a/packages/super-editor/src/extensions/diffing/replay/index.ts b/packages/super-editor/src/extensions/diffing/replay/index.ts new file mode 100644 index 0000000000..52ef7c8c51 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/index.ts @@ -0,0 +1,7 @@ +export * from './replay-doc'; +export * from './replay-non-paragraph'; +export * from './replay-paragraph'; +export * from './replay-inline'; +export * from './replay-attrs'; +export * from './marks-from-diff'; +export * from './replay-types'; diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts new file mode 100644 index 0000000000..09e003b789 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts @@ -0,0 +1,6 @@ +/** + * Builds a mark set from inline diff metadata. + */ +export function marksFromDiff(): void { + throw new Error('marksFromDiff is not implemented yet.'); +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts new file mode 100644 index 0000000000..af0cbf7abf --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts @@ -0,0 +1,6 @@ +/** + * Applies an attribute diff to a node, preserving its content. + */ +export function applyAttrsDiff(): void { + throw new Error('applyAttrsDiff is not implemented yet.'); +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts new file mode 100644 index 0000000000..f5c4006b9e --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts @@ -0,0 +1,6 @@ +/** + * Orchestrates replay for document-level diffs. + */ +export function replayDocDiffs(): void { + throw new Error('replayDocDiffs is not implemented yet.'); +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts new file mode 100644 index 0000000000..e4ef50a0c1 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -0,0 +1,6 @@ +/** + * Replays a single inline diff into a transaction. + */ +export function replayInlineDiff(): void { + throw new Error('replayInlineDiff is not implemented yet.'); +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts new file mode 100644 index 0000000000..3b66f8ab35 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts @@ -0,0 +1,6 @@ +/** + * Replays a non-paragraph node diff into a transaction. + */ +export function replayNonParagraphDiff(): void { + throw new Error('replayNonParagraphDiff is not implemented yet.'); +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts new file mode 100644 index 0000000000..99c1830388 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts @@ -0,0 +1,6 @@ +/** + * Replays a paragraph diff into a transaction. + */ +export function replayParagraphDiff(): void { + throw new Error('replayParagraphDiff is not implemented yet.'); +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-types.ts b/packages/super-editor/src/extensions/diffing/replay/replay-types.ts new file mode 100644 index 0000000000..eb6931f6c8 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-types.ts @@ -0,0 +1,8 @@ +/** + * Generic replay result summary used by helper handlers. + */ +export type ReplayResult = { + applied: number; + skipped: number; + warnings: string[]; +}; diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js new file mode 100644 index 0000000000..6654ff19c5 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -0,0 +1,23 @@ +import { describe, it, expect } from 'vitest'; + +import { replayDiffs } from './replayDiffs'; +import { + replayDocDiffs, + replayNonParagraphDiff, + replayParagraphDiff, + replayInlineDiff, + applyAttrsDiff, + marksFromDiff, +} from './replay'; + +describe('replay diff scaffolding', () => { + it('exposes replay entry points', () => { + expect(typeof replayDiffs).toBe('function'); + expect(typeof replayDocDiffs).toBe('function'); + expect(typeof replayNonParagraphDiff).toBe('function'); + expect(typeof replayParagraphDiff).toBe('function'); + expect(typeof replayInlineDiff).toBe('function'); + expect(typeof applyAttrsDiff).toBe('function'); + expect(typeof marksFromDiff).toBe('function'); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts new file mode 100644 index 0000000000..d7e9310525 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -0,0 +1,24 @@ +/** + * Options that control how diff replay is performed. + */ +export type ReplayDiffsOptions = { + user: { name: string; email: string; image?: string }; + applyTrackedChanges: boolean; +}; + +/** + * Result summary from replaying diffs into a transaction. + */ +export type ReplayDiffsResult = { + tr: import('prosemirror-state').Transaction; + appliedDiffs: number; + skippedDiffs: number; + warnings: string[]; +}; + +/** + * Replays a diff result over the current editor state. + */ +export function replayDiffs(): ReplayDiffsResult { + throw new Error('replayDiffs is not implemented yet.'); +} From 9714f880283bca59478628fe34267dda4972f714 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 11:52:36 -0300 Subject: [PATCH 055/125] feat: implement replay of non-paragraph nodes --- .../replay/replay-non-paragraph.test.js | 163 ++++++++++++++++++ .../diffing/replay/replay-non-paragraph.ts | 112 +++++++++++- .../extensions/diffing/replayDiffs.test.js | 31 ++-- 3 files changed, 293 insertions(+), 13 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js new file mode 100644 index 0000000000..436d5b3380 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js @@ -0,0 +1,163 @@ +import { describe, it, expect } from 'vitest'; +import { EditorState } from 'prosemirror-state'; + +import { getStarterExtensions } from '@extensions/index.js'; +import { createMinimalTestEditor } from '@tests/helpers/editor-test-utils.js'; + +import { replayNonParagraphDiff } from './replay-non-paragraph.js'; + +/** + * Builds a schema using the standard editor extensions. + * @returns {import('prosemirror-model').Schema} + */ +const createSchema = () => { + const editor = createMinimalTestEditor(getStarterExtensions(), { mode: 'docx', skipViewCreation: true }); + return editor.schema; +}; + +/** + * Builds a paragraph node with the given text. + * @param {import('prosemirror-model').Schema} schema + * @param {string} text + * @returns {import('prosemirror-model').Node} + */ +const createParagraph = (schema, text) => { + return schema.nodes.paragraph.create(null, schema.text(text)); +}; + +/** + * Builds a table-of-contents node with a single paragraph. + * @param {import('prosemirror-model').Schema} schema + * @param {string} text + * @param {Record} attrs + * @returns {import('prosemirror-model').Node} + */ +const createTableOfContents = (schema, text, attrs = null) => { + const paragraph = createParagraph(schema, text); + return schema.nodes.tableOfContents.create(attrs, [paragraph]); +}; + +/** + * Finds the first occurrence of a node type and returns its position. + * @param {import('prosemirror-model').Node} doc + * @param {string} typeName + * @returns {number|null} + */ +const findNodePos = (doc, typeName) => { + let found = null; + doc.descendants((node, pos) => { + if (node.type.name === typeName && found === null) { + found = pos; + return false; + } + return undefined; + }); + return found; +}; + +/** + * Verifies that non-paragraph insertions apply at the diff position. + */ +const testNonParagraphInsert = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, 'Hello'); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const toc = createTableOfContents(schema, 'Contents'); + const diff = { + action: 'added', + nodeType: 'tableOfContents', + nodeJSON: toc.toJSON(), + pos: doc.content.size, + }; + + const result = replayNonParagraphDiff({ tr, diff, schema }); + + expect(result.applied).toBe(1); + expect(result.skipped).toBe(0); + expect(result.warnings).toHaveLength(0); + expect(tr.doc.childCount).toBe(2); + expect(tr.doc.child(1).type.name).toBe('tableOfContents'); +}; + +/** + * Verifies that non-paragraph deletions remove the node at the diff position. + */ +const testNonParagraphDelete = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, 'Hello'); + const toc = createTableOfContents(schema, 'Contents'); + const doc = schema.nodes.doc.create(null, [paragraph, toc]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const tocPos = findNodePos(doc, 'tableOfContents'); + if (tocPos === null) { + throw new Error('Expected to find tableOfContents position for deletion test.'); + } + const diff = { + action: 'deleted', + nodeType: 'tableOfContents', + nodeJSON: toc.toJSON(), + pos: tocPos, + }; + + const result = replayNonParagraphDiff({ tr, diff, schema }); + + expect(result.applied).toBe(1); + expect(result.skipped).toBe(0); + expect(result.warnings).toHaveLength(0); + expect(tr.doc.childCount).toBe(1); + expect(tr.doc.child(0).type.name).toBe('paragraph'); +}; + +/** + * Verifies that non-paragraph attribute updates preserve content. + */ +const testNonParagraphModify = () => { + const schema = createSchema(); + const toc = createTableOfContents(schema, 'Contents'); + const doc = schema.nodes.doc.create(null, [toc]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const tocPos = findNodePos(doc, 'tableOfContents'); + if (tocPos === null) { + throw new Error('Expected to find tableOfContents position for modification test.'); + } + const updatedToc = createTableOfContents(schema, 'Contents', { instruction: 'updated' }); + + const diff = { + action: 'modified', + nodeType: 'tableOfContents', + oldNodeJSON: toc.toJSON(), + newNodeJSON: updatedToc.toJSON(), + attrsDiff: { + modified: { + instruction: { from: null, to: 'updated' }, + }, + }, + pos: tocPos, + }; + + const result = replayNonParagraphDiff({ tr, diff, schema }); + + expect(result.applied).toBe(1); + expect(result.skipped).toBe(0); + expect(result.warnings).toHaveLength(0); + expect(tr.doc.child(0).attrs.instruction).toBe('updated'); + expect(tr.doc.child(0).textContent).toBe('Contents'); +}; + +/** + * Runs the non-paragraph diff replay suite. + */ +const runNonParagraphSuite = () => { + it('inserts a non-paragraph node using the diff position', testNonParagraphInsert); + it('deletes a non-paragraph node at the diff position', testNonParagraphDelete); + it('updates non-paragraph node attributes without replacing content', testNonParagraphModify); +}; + +describe('replayNonParagraphDiff', runNonParagraphSuite); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts index 3b66f8ab35..a54a8fc4ce 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts @@ -1,6 +1,114 @@ /** * Replays a non-paragraph node diff into a transaction. */ -export function replayNonParagraphDiff(): void { - throw new Error('replayNonParagraphDiff is not implemented yet.'); +import { Fragment, Slice } from 'prosemirror-model'; +import { ReplaceStep } from 'prosemirror-transform'; + +import { ReplayResult } from './replay-types.ts'; + +/** + * Replays a non-paragraph node diff into a transaction. + */ +export function replayNonParagraphDiff({ + tr, + diff, + schema, +}: { + tr: import('prosemirror-state').Transaction; + diff: import('../algorithm/generic-diffing.ts').NodeDiff; + schema: import('prosemirror-model').Schema; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + /** + * Records a skipped diff with a warning message. + */ + const skipWithWarning = (message: string) => { + result.skipped += 1; + result.warnings.push(message); + }; + + if (diff.nodeType === 'paragraph') { + skipWithWarning('Non-paragraph handler received a paragraph diff.'); + return result; + } + + const { pos } = diff; + + if (diff.action === 'added') { + if (!diff.nodeJSON) { + skipWithWarning('Missing nodeJSON for added non-paragraph diff.'); + return result; + } + try { + const node = schema.nodeFromJSON(diff.nodeJSON); + const slice = new Slice(Fragment.from(node), 0, 0); + const step = new ReplaceStep(pos, pos, slice); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to insert node at pos ${pos}.`); + return result; + } + result.applied += 1; + return result; + } catch (error) { + skipWithWarning(`Invalid nodeJSON for added diff at pos ${pos}.`); + return result; + } + } + + if (diff.action === 'deleted') { + const node = tr.doc.nodeAt(pos); + if (!node) { + skipWithWarning(`No node found at pos ${pos} for deletion.`); + return result; + } + if (node.type.name !== diff.nodeType) { + skipWithWarning(`Node type mismatch at pos ${pos} for deletion.`); + return result; + } + const step = new ReplaceStep(pos, pos + node.nodeSize, Slice.empty); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to delete node at pos ${pos}.`); + return result; + } + result.applied += 1; + return result; + } + + if (diff.action === 'modified') { + if (!diff.attrsDiff) { + result.skipped += 1; + return result; + } + const node = tr.doc.nodeAt(pos); + if (!node) { + skipWithWarning(`No node found at pos ${pos} for modification.`); + return result; + } + if (node.type.name !== diff.nodeType) { + skipWithWarning(`Node type mismatch at pos ${pos} for modification.`); + return result; + } + if (!diff.newNodeJSON?.attrs) { + skipWithWarning(`Missing newNodeJSON.attrs at pos ${pos} for modification.`); + return result; + } + try { + tr.setNodeMarkup(pos, undefined, diff.newNodeJSON.attrs, node.marks); + result.applied += 1; + return result; + } catch (error) { + skipWithWarning(`Failed to update node attrs at pos ${pos}.`); + return result; + } + } + + skipWithWarning(`Unsupported diff action for non-paragraph node at pos ${pos}.`); + return result; } diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 6654ff19c5..9efde65249 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -10,14 +10,23 @@ import { marksFromDiff, } from './replay'; -describe('replay diff scaffolding', () => { - it('exposes replay entry points', () => { - expect(typeof replayDiffs).toBe('function'); - expect(typeof replayDocDiffs).toBe('function'); - expect(typeof replayNonParagraphDiff).toBe('function'); - expect(typeof replayParagraphDiff).toBe('function'); - expect(typeof replayInlineDiff).toBe('function'); - expect(typeof applyAttrsDiff).toBe('function'); - expect(typeof marksFromDiff).toBe('function'); - }); -}); +/** + * Verifies the replay entry points are exposed as functions. + */ +const testReplayEntrypoints = () => { + expect(typeof replayDiffs).toBe('function'); + expect(typeof replayDocDiffs).toBe('function'); + expect(typeof replayNonParagraphDiff).toBe('function'); + expect(typeof replayParagraphDiff).toBe('function'); + expect(typeof replayInlineDiff).toBe('function'); + expect(typeof applyAttrsDiff).toBe('function'); + expect(typeof marksFromDiff).toBe('function'); +}; +/** + * Runs the replay scaffolding suite. + */ +const runReplayScaffoldingSuite = () => { + it('exposes replay entry points', testReplayEntrypoints); +}; + +describe('replay diff scaffolding', runReplayScaffoldingSuite); From 3b31ab25867be41f221dce1e008531c161eef63f Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 11:58:48 -0300 Subject: [PATCH 056/125] feat: implement deriving new marks from diff --- .../diffing/replay/marks-from-diff.test.js | 103 ++++++++++++++++++ .../diffing/replay/marks-from-diff.ts | 99 ++++++++++++++++- 2 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js new file mode 100644 index 0000000000..42801ef72c --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js @@ -0,0 +1,103 @@ +import { describe, it, expect } from 'vitest'; + +import { getStarterExtensions } from '@extensions/index.js'; +import { createMinimalTestEditor } from '@tests/helpers/editor-test-utils.js'; + +import { marksFromDiff } from './marks-from-diff.js'; + +/** + * Builds a schema using the standard editor extensions. + * @returns {import('prosemirror-model').Schema} + */ +const createSchema = () => { + const editor = createMinimalTestEditor(getStarterExtensions(), { mode: 'docx', skipViewCreation: true }); + return editor.schema; +}; + +/** + * Extracts mark types from a list of marks for assertions. + * @param {import('prosemirror-model').Mark[]} marks + * @returns {string[]} + */ +const getMarkTypes = (marks) => marks.map((mark) => mark.type.name); + +/** + * Verifies marks are generated for added text based on mark JSON. + * @returns {void} + */ +const testAddedMarks = () => { + const schema = createSchema(); + const marks = marksFromDiff({ + schema, + action: 'added', + marks: [{ type: 'bold' }, { type: 'textStyle', attrs: { color: '#ff0000' } }], + }); + + expect(getMarkTypes(marks)).toEqual(['bold', 'textStyle']); + expect(marks[1].attrs.color).toBe('#ff0000'); +}; + +/** + * Verifies modified text uses marksDiff applied to old marks. + * @returns {void} + */ +const testModifiedMarksFromDiff = () => { + const schema = createSchema(); + const marks = marksFromDiff({ + schema, + action: 'modified', + oldMarks: [{ type: 'bold' }, { type: 'textStyle', attrs: { color: '#0000ff' } }], + marksDiff: { + added: [{ name: 'italic', attrs: {} }], + deleted: [{ name: 'bold', attrs: {} }], + modified: [{ name: 'textStyle', oldAttrs: { color: '#0000ff' }, newAttrs: { color: '#00ff00' } }], + }, + }); + + expect(getMarkTypes(marks)).toEqual(['textStyle', 'italic']); + const textStyleMark = marks.find((mark) => mark.type.name === 'textStyle'); + expect(textStyleMark?.attrs.color).toBe('#00ff00'); +}; + +/** + * Verifies modified text falls back to explicit marks when no marksDiff is provided. + * @returns {void} + */ +const testModifiedMarksFallback = () => { + const schema = createSchema(); + const marks = marksFromDiff({ + schema, + action: 'modified', + marks: [{ type: 'underline' }], + }); + + expect(getMarkTypes(marks)).toEqual(['underline']); +}; + +/** + * Verifies deleted text returns no marks. + * @returns {void} + */ +const testDeletedMarks = () => { + const schema = createSchema(); + const marks = marksFromDiff({ + schema, + action: 'deleted', + marks: [{ type: 'bold' }], + }); + + expect(marks).toEqual([]); +}; + +/** + * Runs the marks-from-diff helper suite. + * @returns {void} + */ +const runMarksFromDiffSuite = () => { + it('builds marks for added text', testAddedMarks); + it('applies marksDiff for modified text', testModifiedMarksFromDiff); + it('falls back to marks for modified text', testModifiedMarksFallback); + it('returns no marks for deleted text', testDeletedMarks); +}; + +describe('marksFromDiff', runMarksFromDiffSuite); diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts index 09e003b789..85291cd323 100644 --- a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts @@ -1,6 +1,101 @@ /** * Builds a mark set from inline diff metadata. + * + * @param params Inputs used to resolve marks for an inline diff. + * @param params.schema Schema used to resolve mark types. + * @param params.action Inline diff action to apply. + * @param params.marks Mark JSON entries present on the diff. + * @param params.marksDiff Mark diff entries for modified content. + * @param params.oldMarks Mark JSON entries from the original content. + * @returns The resolved marks to apply to inserted/replaced text. */ -export function marksFromDiff(): void { - throw new Error('marksFromDiff is not implemented yet.'); +export function marksFromDiff({ + schema, + action, + marks = [], + marksDiff = null, + oldMarks = [], +}: { + schema: import('prosemirror-model').Schema; + action: import('../algorithm/inline-diffing.ts').InlineDiffResult['action']; + marks?: Array<{ type: string; attrs?: Record }>; + marksDiff?: import('../algorithm/attributes-diffing.ts').MarksDiff | null; + oldMarks?: Array<{ type: string; attrs?: Record }>; +}): import('prosemirror-model').Mark[] { + if (action === 'deleted') { + return []; + } + + if (action === 'modified') { + if (marksDiff && oldMarks.length > 0) { + const updatedMarks = applyMarksDiff(oldMarks, marksDiff); + return buildMarksFromJSON(schema, updatedMarks); + } + if (marks.length > 0) { + return buildMarksFromJSON(schema, marks); + } + return []; + } + + if (marks.length === 0) { + return []; + } + + return buildMarksFromJSON(schema, marks); } + +/** + * Applies a marks diff to a list of mark JSON entries. + * + * @param existingMarks Base mark JSON entries. + * @param marksDiff Diff to apply against the base marks. + * @returns Updated mark JSON entries. + */ +const applyMarksDiff = ( + existingMarks: Array<{ type: string; attrs?: Record }>, + marksDiff: import('../algorithm/attributes-diffing.ts').MarksDiff, +): Array<{ type: string; attrs?: Record }> => { + const byType = new Map>(); + + existingMarks.forEach((mark) => { + byType.set(mark.type, mark.attrs ?? {}); + }); + + marksDiff.deleted.forEach((mark) => { + byType.delete(mark.name); + }); + + marksDiff.modified.forEach((mark) => { + byType.set(mark.name, mark.newAttrs ?? {}); + }); + + marksDiff.added.forEach((mark) => { + byType.set(mark.name, mark.attrs ?? {}); + }); + + return Array.from(byType.entries()).map(([type, attrs]) => ({ type, attrs })); +}; + +/** + * Converts mark JSON entries into schema marks, skipping unknown types. + * + * @param schema Schema used to resolve mark types. + * @param marks Mark JSON entries to convert. + * @returns Resolved mark instances. + */ +const buildMarksFromJSON = ( + schema: import('prosemirror-model').Schema, + marks: Array<{ type: string; attrs?: Record }>, +): import('prosemirror-model').Mark[] => { + const resolvedMarks: import('prosemirror-model').Mark[] = []; + + marks.forEach((mark) => { + const markType = schema.marks[mark.type]; + if (!markType) { + return; + } + resolvedMarks.push(markType.create(mark.attrs ?? {})); + }); + + return resolvedMarks; +}; From eab97d01635cf80643919eee5e1b927675652b50 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 11:59:49 -0300 Subject: [PATCH 057/125] docs: improve TSDoc comments --- .../src/extensions/diffing/replay/replay-attrs.ts | 2 ++ .../src/extensions/diffing/replay/replay-doc.ts | 2 ++ .../src/extensions/diffing/replay/replay-inline.ts | 2 ++ .../diffing/replay/replay-non-paragraph.test.js | 4 ++++ .../extensions/diffing/replay/replay-non-paragraph.ts | 8 ++++++++ .../src/extensions/diffing/replay/replay-paragraph.ts | 2 ++ .../src/extensions/diffing/replay/replay-types.ts | 4 ++++ .../src/extensions/diffing/replayDiffs.test.js | 2 ++ .../super-editor/src/extensions/diffing/replayDiffs.ts | 10 ++++++++++ 9 files changed, 36 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts index af0cbf7abf..4ae49cd4b6 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts @@ -1,5 +1,7 @@ /** * Applies an attribute diff to a node, preserving its content. + * + * @returns Placeholder result until implemented. */ export function applyAttrsDiff(): void { throw new Error('applyAttrsDiff is not implemented yet.'); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts index f5c4006b9e..e8bfc07d8d 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts @@ -1,5 +1,7 @@ /** * Orchestrates replay for document-level diffs. + * + * @returns Placeholder result until implemented. */ export function replayDocDiffs(): void { throw new Error('replayDocDiffs is not implemented yet.'); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index e4ef50a0c1..6f27245b43 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -1,5 +1,7 @@ /** * Replays a single inline diff into a transaction. + * + * @returns Placeholder result until implemented. */ export function replayInlineDiff(): void { throw new Error('replayInlineDiff is not implemented yet.'); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js index 436d5b3380..b41eec7b94 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.test.js @@ -57,6 +57,7 @@ const findNodePos = (doc, typeName) => { /** * Verifies that non-paragraph insertions apply at the diff position. + * @returns {void} */ const testNonParagraphInsert = () => { const schema = createSchema(); @@ -84,6 +85,7 @@ const testNonParagraphInsert = () => { /** * Verifies that non-paragraph deletions remove the node at the diff position. + * @returns {void} */ const testNonParagraphDelete = () => { const schema = createSchema(); @@ -115,6 +117,7 @@ const testNonParagraphDelete = () => { /** * Verifies that non-paragraph attribute updates preserve content. + * @returns {void} */ const testNonParagraphModify = () => { const schema = createSchema(); @@ -153,6 +156,7 @@ const testNonParagraphModify = () => { /** * Runs the non-paragraph diff replay suite. + * @returns {void} */ const runNonParagraphSuite = () => { it('inserts a non-paragraph node using the diff position', testNonParagraphInsert); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts index a54a8fc4ce..2f5ba761d6 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts @@ -8,6 +8,12 @@ import { ReplayResult } from './replay-types.ts'; /** * Replays a non-paragraph node diff into a transaction. + * + * @param params Input bundle for replaying a diff. + * @param params.tr Transaction to append steps to. + * @param params.diff Diff payload to replay. + * @param params.schema Schema used to rebuild nodes. + * @returns Result summary for the applied diff. */ export function replayNonParagraphDiff({ tr, @@ -26,6 +32,8 @@ export function replayNonParagraphDiff({ /** * Records a skipped diff with a warning message. + * + * @param message Warning to record for a skipped diff. */ const skipWithWarning = (message: string) => { result.skipped += 1; diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts index 99c1830388..17b99f1263 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts @@ -1,5 +1,7 @@ /** * Replays a paragraph diff into a transaction. + * + * @returns Placeholder result until implemented. */ export function replayParagraphDiff(): void { throw new Error('replayParagraphDiff is not implemented yet.'); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-types.ts b/packages/super-editor/src/extensions/diffing/replay/replay-types.ts index eb6931f6c8..113d1692ba 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-types.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-types.ts @@ -1,5 +1,9 @@ /** * Generic replay result summary used by helper handlers. + * + * @property applied Number of diffs applied by the helper. + * @property skipped Number of diffs skipped by the helper. + * @property warnings Non-fatal warnings recorded by the helper. */ export type ReplayResult = { applied: number; diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 9efde65249..9a57d6c682 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -12,6 +12,7 @@ import { /** * Verifies the replay entry points are exposed as functions. + * @returns {void} */ const testReplayEntrypoints = () => { expect(typeof replayDiffs).toBe('function'); @@ -24,6 +25,7 @@ const testReplayEntrypoints = () => { }; /** * Runs the replay scaffolding suite. + * @returns {void} */ const runReplayScaffoldingSuite = () => { it('exposes replay entry points', testReplayEntrypoints); diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index d7e9310525..318347fe6c 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -1,5 +1,8 @@ /** * Options that control how diff replay is performed. + * + * @property user Identity used for tracked changes. + * @property applyTrackedChanges Whether to apply tracked changes logic. */ export type ReplayDiffsOptions = { user: { name: string; email: string; image?: string }; @@ -8,6 +11,11 @@ export type ReplayDiffsOptions = { /** * Result summary from replaying diffs into a transaction. + * + * @property tr Transaction containing the replayed steps. + * @property appliedDiffs Count of diffs successfully applied. + * @property skippedDiffs Count of diffs skipped or failed. + * @property warnings Non-fatal warnings encountered during replay. */ export type ReplayDiffsResult = { tr: import('prosemirror-state').Transaction; @@ -18,6 +26,8 @@ export type ReplayDiffsResult = { /** * Replays a diff result over the current editor state. + * + * @returns Placeholder replay result until implemented. */ export function replayDiffs(): ReplayDiffsResult { throw new Error('replayDiffs is not implemented yet.'); From e1e66092add22b8c98fe5bd1b22a23fd94867824 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 12:04:17 -0300 Subject: [PATCH 058/125] docs: improve typing --- .../src/extensions/diffing/algorithm/inline-diffing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index d540ce8e7d..db29ab6f0c 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -111,7 +111,7 @@ export interface InlineDiffResult { /** Attribute diff for modified runs. */ runAttrsDiff?: AttributesDiff | null; /** Marks applied to added/deleted text. */ - marks?: Record[]; + marks?: MarkJSON[]; /** Mark diff for modified text. */ marksDiff?: MarksDiff | null; /** Inline node type name for node diffs. */ From 587142a44df3aa55b808befc5dc1bda3b9f39b60 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 12:05:53 -0300 Subject: [PATCH 059/125] feat: implement replay of inline nodes and text --- .../diffing/replay/replay-inline.test.js | 256 ++++++++++++++++++ .../diffing/replay/replay-inline.ts | 209 +++++++++++++- 2 files changed, 462 insertions(+), 3 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js new file mode 100644 index 0000000000..138d371c6d --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js @@ -0,0 +1,256 @@ +import { describe, it, expect } from 'vitest'; +import { EditorState } from 'prosemirror-state'; + +import { getStarterExtensions } from '@extensions/index.js'; +import { createMinimalTestEditor } from '@tests/helpers/editor-test-utils.js'; + +import { replayInlineDiff } from './replay-inline.js'; + +/** + * Builds a schema using the standard editor extensions. + * @returns {import('prosemirror-model').Schema} + */ +const createSchema = () => { + const editor = createMinimalTestEditor(getStarterExtensions(), { mode: 'docx', skipViewCreation: true }); + return editor.schema; +}; + +/** + * Builds a paragraph node with the given content. + * @param {import('prosemirror-model').Schema} schema + * @param {Array} content + * @returns {import('prosemirror-model').Node} + */ +const createParagraph = (schema, content) => { + return schema.nodes.paragraph.create(null, content); +}; + +/** + * Finds the first paragraph position in the document. + * @param {import('prosemirror-model').Node} doc + * @returns {number} + */ +const findParagraphPos = (doc) => { + let found = null; + doc.descendants((node, pos) => { + if (node.type.name === 'paragraph' && found === null) { + found = pos; + return false; + } + return undefined; + }); + if (found === null) { + throw new Error('Expected to find a paragraph node.'); + } + return found; +}; + +/** + * Finds the first inline node position in the document by type. + * @param {import('prosemirror-model').Node} doc + * @param {string} typeName + * @returns {{ pos: number; node: import('prosemirror-model').Node }} + */ +const findInlineNode = (doc, typeName) => { + let found = null; + doc.descendants((node, pos) => { + if (node.type.name === typeName && found === null) { + found = { node, pos }; + return false; + } + return undefined; + }); + if (!found) { + throw new Error(`Expected to find inline node ${typeName}.`); + } + return found; +}; + +/** + * Verifies inline text insertion uses the paragraph end when startPos is null. + * @returns {void} + */ +const testTextAddAtParagraphEnd = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, [schema.text('Hello')]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const paragraphPos = findParagraphPos(doc); + const paragraphEndPos = paragraphPos + 1 + paragraph.content.size; + + const diff = { + action: 'added', + kind: 'text', + startPos: null, + endPos: null, + text: '!', + marks: [], + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos }); + + expect(result.applied).toBe(1); + expect(tr.doc.textContent).toBe('Hello!'); +}; + +/** + * Verifies inline text deletion removes the specified range. + * @returns {void} + */ +const testTextDeleteRange = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, [schema.text('Hello')]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const paragraphPos = findParagraphPos(doc); + const startPos = paragraphPos + 1 + 1; + const endPos = startPos + 3; + + const diff = { + action: 'deleted', + kind: 'text', + startPos, + endPos, + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: endPos }); + + expect(result.applied).toBe(1); + expect(tr.doc.textContent).toBe('Ho'); +}; + +/** + * Verifies inline text modification replaces the specified range. + * @returns {void} + */ +const testTextModifyRange = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, [schema.text('Hello')]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const paragraphPos = findParagraphPos(doc); + const startPos = paragraphPos + 1; + const endPos = startPos + 1; + + const diff = { + action: 'modified', + kind: 'text', + startPos, + endPos, + newText: 'Y', + marks: [], + marksDiff: null, + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: endPos }); + + expect(result.applied).toBe(1); + expect(tr.doc.textContent).toBe('Yello'); +}; + +/** + * Verifies inline node insertion is applied at the paragraph end. + * @returns {void} + */ +const testInlineNodeAdd = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, [schema.text('A')]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const paragraphPos = findParagraphPos(doc); + const paragraphEndPos = paragraphPos + 1 + paragraph.content.size; + const image = schema.nodes.image.create({ src: 'data:image/png;base64,AAA=' }); + + const diff = { + action: 'added', + kind: 'inlineNode', + startPos: null, + endPos: null, + nodeJSON: image.toJSON(), + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos }); + + expect(result.applied).toBe(1); + const insertedImage = findInlineNode(tr.doc, 'image'); + expect(insertedImage).toBeTruthy(); +}; + +/** + * Verifies inline node deletion removes the node range. + * @returns {void} + */ +const testInlineNodeDelete = () => { + const schema = createSchema(); + const image = schema.nodes.image.create({ src: 'data:image/png;base64,AAA=' }); + const paragraph = createParagraph(schema, [schema.text('A'), image]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const { node, pos } = findInlineNode(doc, 'image'); + const diff = { + action: 'deleted', + kind: 'inlineNode', + startPos: pos, + endPos: pos + node.nodeSize, + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: pos }); + + expect(result.applied).toBe(1); + expect(() => findInlineNode(tr.doc, 'image')).toThrow(); +}; + +/** + * Verifies inline node modification replaces the node range. + * @returns {void} + */ +const testInlineNodeModify = () => { + const schema = createSchema(); + const image = schema.nodes.image.create({ src: 'data:image/png;base64,AAA=', alt: 'old' }); + const paragraph = createParagraph(schema, [schema.text('A'), image]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const { node, pos } = findInlineNode(doc, 'image'); + const updatedImage = schema.nodes.image.create({ src: 'data:image/png;base64,AAA=', alt: 'new' }); + + const diff = { + action: 'modified', + kind: 'inlineNode', + startPos: pos, + endPos: pos + node.nodeSize, + newNodeJSON: updatedImage.toJSON(), + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: pos }); + + expect(result.applied).toBe(1); + const updated = findInlineNode(tr.doc, 'image'); + expect(updated.node.attrs.alt).toBe('new'); +}; + +/** + * Runs the inline replay helper suite. + * @returns {void} + */ +const runInlineReplaySuite = () => { + it('inserts text at paragraph end when startPos is null', testTextAddAtParagraphEnd); + it('deletes a text range', testTextDeleteRange); + it('modifies a text range', testTextModifyRange); + it('inserts an inline node', testInlineNodeAdd); + it('deletes an inline node', testInlineNodeDelete); + it('modifies an inline node', testInlineNodeModify); +}; + +describe('replayInlineDiff', runInlineReplaySuite); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index 6f27245b43..fd32c38218 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -1,8 +1,211 @@ +import { Fragment, Slice } from 'prosemirror-model'; +import { ReplaceStep } from 'prosemirror-transform'; + +import { marksFromDiff } from './marks-from-diff.ts'; +import { ReplayResult } from './replay-types.ts'; + /** * Replays a single inline diff into a transaction. * - * @returns Placeholder result until implemented. + * @param params Input bundle for replaying an inline diff. + * @param params.tr Transaction to append steps to. + * @param params.diff Inline diff payload to replay. + * @param params.schema Schema used to rebuild nodes and marks. + * @param params.paragraphEndPos Fallback insertion anchor when startPos is missing. + * @returns Result summary for the applied inline diff. */ -export function replayInlineDiff(): void { - throw new Error('replayInlineDiff is not implemented yet.'); +export function replayInlineDiff({ + tr, + diff, + schema, + paragraphEndPos, +}: { + tr: import('prosemirror-state').Transaction; + diff: import('../algorithm/inline-diffing.ts').InlineDiffResult; + schema: import('prosemirror-model').Schema; + paragraphEndPos: number; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + /** + * Records a skipped inline diff with a warning message. + * + * @param message Warning to record for a skipped diff. + */ + const skipWithWarning = (message: string) => { + result.skipped += 1; + result.warnings.push(message); + }; + + const isAddition = diff.action === 'added'; + const isDeletion = diff.action === 'deleted'; + const isModification = diff.action === 'modified'; + + let from = diff.startPos ?? null; + let to = diff.endPos ?? null; + + if (isAddition && from === null) { + from = paragraphEndPos; + to = paragraphEndPos; + } + + if (!isAddition && (from === null || to === null)) { + skipWithWarning('Missing inline diff anchor positions.'); + return result; + } + + if (from === null) { + skipWithWarning('Missing inline diff start position.'); + return result; + } + + if (to === null) { + to = from; + } + + if (diff.kind === 'text') { + if (isAddition) { + if (!diff.text) { + skipWithWarning('Missing text content for inline addition.'); + return result; + } + const marks = marksFromDiff({ + schema, + action: diff.action, + marks: diff.marks, + }); + const textNode = schema.text(diff.text, marks); + const slice = new Slice(Fragment.from(textNode), 0, 0); + const step = new ReplaceStep(from, from, slice); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to insert text at ${from}.`); + return result; + } + result.applied += 1; + return result; + } + + if (isDeletion) { + const step = new ReplaceStep(from, to, Slice.empty); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to delete text at ${from}-${to}.`); + return result; + } + result.applied += 1; + return result; + } + + if (isModification) { + if (!diff.newText) { + skipWithWarning('Missing newText for inline modification.'); + return result; + } + const oldMarks = getMarksAtPosition(tr.doc, from); + const marks = marksFromDiff({ + schema, + action: diff.action, + marks: diff.marks, + marksDiff: diff.marksDiff, + oldMarks, + }); + const textNode = schema.text(diff.newText, marks); + const slice = new Slice(Fragment.from(textNode), 0, 0); + const step = new ReplaceStep(from, to, slice); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to replace text at ${from}-${to}.`); + return result; + } + result.applied += 1; + return result; + } + } + + if (diff.kind === 'inlineNode') { + if (isAddition) { + if (!diff.nodeJSON) { + skipWithWarning('Missing nodeJSON for inline node addition.'); + return result; + } + try { + const node = schema.nodeFromJSON(diff.nodeJSON); + const slice = new Slice(Fragment.from(node), 0, 0); + const step = new ReplaceStep(from, from, slice); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to insert inline node at ${from}.`); + return result; + } + result.applied += 1; + return result; + } catch (error) { + skipWithWarning('Invalid nodeJSON for inline node addition.'); + return result; + } + } + + if (isDeletion) { + const step = new ReplaceStep(from, to, Slice.empty); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to delete inline node at ${from}-${to}.`); + return result; + } + result.applied += 1; + return result; + } + + if (isModification) { + if (!diff.newNodeJSON) { + skipWithWarning('Missing newNodeJSON for inline node modification.'); + return result; + } + try { + const node = schema.nodeFromJSON(diff.newNodeJSON); + const slice = new Slice(Fragment.from(node), 0, 0); + const step = new ReplaceStep(from, to, slice); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to replace inline node at ${from}-${to}.`); + return result; + } + result.applied += 1; + return result; + } catch (error) { + skipWithWarning('Invalid newNodeJSON for inline node modification.'); + return result; + } + } + } + + skipWithWarning('Unsupported inline diff operation.'); + return result; } + +/** + * Extracts mark JSON entries from the inline node at the given position. + * + * @param doc Document to inspect for marks. + * @param pos Position used to resolve a candidate inline node. + * @returns Mark JSON entries for the inline node at the position. + */ +const getMarksAtPosition = ( + doc: import('prosemirror-model').Node, + pos: number, +): Array<{ type: string; attrs?: Record }> => { + const resolved = doc.resolve(pos); + const candidate = resolved.nodeAfter || resolved.nodeBefore; + if (!candidate || !candidate.isInline) { + return []; + } + return candidate.marks.map((mark) => ({ + type: mark.type.name, + attrs: mark.attrs ?? {}, + })); +}; From f3049a86f46d4ab033030bb1494dce23eb43cd03 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 12:10:52 -0300 Subject: [PATCH 060/125] feat: implement replay of paragraph nodes --- .../diffing/replay/replay-paragraph.test.js | 199 ++++++++++++++++++ .../diffing/replay/replay-paragraph.ts | 128 ++++++++++- 2 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js new file mode 100644 index 0000000000..dd4d051a34 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js @@ -0,0 +1,199 @@ +import { describe, it, expect } from 'vitest'; +import { EditorState } from 'prosemirror-state'; + +import { getStarterExtensions } from '@extensions/index.js'; +import { createMinimalTestEditor } from '@tests/helpers/editor-test-utils.js'; + +import { replayParagraphDiff } from './replay-paragraph.js'; + +/** + * Builds a schema using the standard editor extensions. + * @returns {import('prosemirror-model').Schema} + */ +const createSchema = () => { + const editor = createMinimalTestEditor(getStarterExtensions(), { mode: 'docx', skipViewCreation: true }); + return editor.schema; +}; + +/** + * Builds a paragraph node with the given text. + * @param {import('prosemirror-model').Schema} schema + * @param {string} text + * @returns {import('prosemirror-model').Node} + */ +const createParagraph = (schema, text) => { + return schema.nodes.paragraph.create(null, schema.text(text)); +}; + +/** + * Finds the first paragraph position in the document. + * @param {import('prosemirror-model').Node} doc + * @returns {number} + */ +const findParagraphPos = (doc) => { + let found = null; + doc.descendants((node, pos) => { + if (node.type.name === 'paragraph' && found === null) { + found = pos; + return false; + } + return undefined; + }); + if (found === null) { + throw new Error('Expected to find a paragraph node.'); + } + return found; +}; + +/** + * Verifies paragraph insertion adds the node at the diff position. + * @returns {void} + */ +const testParagraphAdd = () => { + const schema = createSchema(); + const doc = schema.nodes.doc.create(null, [createParagraph(schema, 'Before')]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const newParagraph = createParagraph(schema, 'Added'); + const diff = { + action: 'added', + nodeType: 'paragraph', + nodeJSON: newParagraph.toJSON(), + pos: doc.content.size, + text: 'Added', + }; + + const result = replayParagraphDiff({ tr, diff, schema }); + + expect(result.applied).toBe(1); + expect(tr.doc.childCount).toBe(2); + expect(tr.doc.child(1).textContent).toBe('Added'); +}; + +/** + * Verifies paragraph deletion removes the node at the diff position. + * @returns {void} + */ +const testParagraphDelete = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, 'Delete'); + const trailingParagraph = createParagraph(schema, 'Keep'); + const doc = schema.nodes.doc.create(null, [paragraph, trailingParagraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const paragraphPos = findParagraphPos(doc); + const diff = { + action: 'deleted', + nodeType: 'paragraph', + nodeJSON: paragraph.toJSON(), + oldText: 'Delete', + pos: paragraphPos, + }; + + const result = replayParagraphDiff({ tr, diff, schema }); + + expect(result.applied).toBe(1); + expect(tr.doc.childCount).toBe(1); + expect(tr.doc.child(0).textContent).toBe('Keep'); +}; + +/** + * Verifies paragraph modification replays inline text diffs. + * @returns {void} + */ +const testParagraphInlineModify = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, 'Hello'); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const paragraphPos = findParagraphPos(doc); + const diff = { + action: 'modified', + nodeType: 'paragraph', + pos: paragraphPos, + oldText: 'Hello', + newText: 'Yello!', + oldNodeJSON: paragraph.toJSON(), + newNodeJSON: createParagraph(schema, 'Yello!').toJSON(), + contentDiff: [ + { + action: 'modified', + kind: 'text', + startPos: paragraphPos + 1, + endPos: paragraphPos + 2, + oldText: 'H', + newText: 'Y', + marksDiff: null, + }, + { + action: 'added', + kind: 'text', + startPos: paragraphPos + 1 + paragraph.content.size, + endPos: paragraphPos + 1 + paragraph.content.size, + text: '!', + marks: [], + }, + ], + attrsDiff: null, + }; + + const result = replayParagraphDiff({ tr, diff, schema }); + + expect(result.applied).toBe(2); + expect(tr.doc.textContent).toBe('Yello!'); +}; + +/** + * Verifies paragraph attribute updates apply new attrs. + * @returns {void} + */ +const testParagraphAttrsModify = () => { + const schema = createSchema(); + const paragraph = createParagraph(schema, 'Hello'); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const paragraphPos = findParagraphPos(doc); + const updatedParagraph = schema.nodes.paragraph.create( + { paragraphProperties: { styleId: 'Heading1' } }, + schema.text('Hello'), + ); + const diff = { + action: 'modified', + nodeType: 'paragraph', + pos: paragraphPos, + oldText: 'Hello', + newText: 'Hello', + oldNodeJSON: paragraph.toJSON(), + newNodeJSON: updatedParagraph.toJSON(), + contentDiff: [], + attrsDiff: { + modified: { + 'paragraphProperties.styleId': { from: null, to: 'Heading1' }, + }, + }, + }; + + const result = replayParagraphDiff({ tr, diff, schema }); + + expect(result.applied).toBe(1); + expect(tr.doc.child(0).attrs.paragraphProperties?.styleId).toBe('Heading1'); +}; + +/** + * Runs the paragraph replay helper suite. + * @returns {void} + */ +const runParagraphReplaySuite = () => { + it('adds a paragraph', testParagraphAdd); + it('deletes a paragraph', testParagraphDelete); + it('modifies a paragraph with inline diffs', testParagraphInlineModify); + it('updates paragraph attributes', testParagraphAttrsModify); +}; + +describe('replayParagraphDiff', runParagraphReplaySuite); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts index 17b99f1263..672bdcd91c 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts @@ -1,8 +1,130 @@ +import { Fragment, Slice } from 'prosemirror-model'; +import { ReplaceStep } from 'prosemirror-transform'; + +import { replayInlineDiff } from './replay-inline.ts'; +import { ReplayResult } from './replay-types.ts'; + /** * Replays a paragraph diff into a transaction. * - * @returns Placeholder result until implemented. + * @param params Input bundle for replaying a paragraph diff. + * @param params.tr Transaction to append steps to. + * @param params.diff Paragraph diff payload to replay. + * @param params.schema Schema used to rebuild nodes. + * @returns Result summary for the applied paragraph diff. */ -export function replayParagraphDiff(): void { - throw new Error('replayParagraphDiff is not implemented yet.'); +export function replayParagraphDiff({ + tr, + diff, + schema, +}: { + tr: import('prosemirror-state').Transaction; + diff: import('../algorithm/paragraph-diffing.ts').ParagraphDiff; + schema: import('prosemirror-model').Schema; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + /** + * Records a skipped diff with a warning message. + * + * @param message Warning to record for a skipped diff. + */ + const skipWithWarning = (message: string) => { + result.skipped += 1; + result.warnings.push(message); + }; + + const { pos } = diff; + + if (diff.action === 'added') { + if (!diff.nodeJSON) { + skipWithWarning('Missing nodeJSON for added paragraph diff.'); + return result; + } + try { + const node = schema.nodeFromJSON(diff.nodeJSON); + const slice = new Slice(Fragment.from(node), 0, 0); + const step = new ReplaceStep(pos, pos, slice); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to insert paragraph at pos ${pos}.`); + return result; + } + result.applied += 1; + return result; + } catch (error) { + skipWithWarning(`Invalid nodeJSON for added paragraph at pos ${pos}.`); + return result; + } + } + + if (diff.action === 'deleted') { + const node = tr.doc.nodeAt(pos); + if (!node) { + skipWithWarning(`No paragraph found at pos ${pos} for deletion.`); + return result; + } + if (node.type.name !== 'paragraph') { + skipWithWarning(`Node type mismatch at pos ${pos} for paragraph deletion.`); + return result; + } + const step = new ReplaceStep(pos, pos + node.nodeSize, Slice.empty); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to delete paragraph at pos ${pos}.`); + return result; + } + result.applied += 1; + return result; + } + + if (diff.action === 'modified') { + const node = tr.doc.nodeAt(pos); + if (!node) { + skipWithWarning(`No paragraph found at pos ${pos} for modification.`); + return result; + } + if (node.type.name !== 'paragraph') { + skipWithWarning(`Node type mismatch at pos ${pos} for paragraph modification.`); + return result; + } + + const paragraphEndPos = pos + 1 + node.content.size; + const contentDiffs = diff.contentDiff ?? []; + for (let idx = contentDiffs.length - 1; idx >= 0; idx -= 1) { + const inlineDiff = contentDiffs[idx]; + const inlineResult = replayInlineDiff({ + tr, + diff: inlineDiff, + schema, + paragraphEndPos, + }); + result.applied += inlineResult.applied; + result.skipped += inlineResult.skipped; + result.warnings.push(...inlineResult.warnings); + } + + if (diff.attrsDiff) { + if (!diff.newNodeJSON?.attrs) { + skipWithWarning(`Missing newNodeJSON attrs at pos ${pos} for paragraph modification.`); + return result; + } + try { + tr.setNodeMarkup(pos, undefined, diff.newNodeJSON.attrs, node.marks); + result.applied += 1; + } catch (error) { + skipWithWarning(`Failed to update paragraph attrs at pos ${pos}.`); + return result; + } + } + + return result; + } + + skipWithWarning(`Unsupported paragraph diff action at pos ${pos}.`); + return result; } From 2ae4feee0588d1d8884b647e54da095f9446a406 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 12:15:38 -0300 Subject: [PATCH 061/125] feat: implement diff replay entrypoint --- .../extensions/diffing/replay/replay-doc.ts | 39 ++++- .../diffing/replay/replay-non-paragraph.ts | 4 + .../diffing/replay/replay-paragraph.ts | 4 + .../extensions/diffing/replayDiffs.test.js | 162 +++++++++++++++--- .../src/extensions/diffing/replayDiffs.ts | 39 ++++- 5 files changed, 220 insertions(+), 28 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts index e8bfc07d8d..92adba8ea9 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts @@ -1,8 +1,41 @@ +import { ReplayResult } from './replay-types.ts'; +import { replayNonParagraphDiff } from './replay-non-paragraph.ts'; +import { replayParagraphDiff } from './replay-paragraph.ts'; + /** * Orchestrates replay for document-level diffs. * - * @returns Placeholder result until implemented. + * @param params Input bundle for replaying document diffs. + * @param params.tr Transaction to append steps to. + * @param params.docDiffs Document diffs to replay (in original order). + * @param params.schema Schema used to rebuild nodes. + * @returns Result summary for the applied diffs. */ -export function replayDocDiffs(): void { - throw new Error('replayDocDiffs is not implemented yet.'); +export function replayDocDiffs({ + tr, + docDiffs, + schema, +}: { + tr: import('prosemirror-state').Transaction; + docDiffs: import('../algorithm/generic-diffing.ts').NodeDiff[]; + schema: import('prosemirror-model').Schema; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + for (let idx = docDiffs.length - 1; idx >= 0; idx -= 1) { + const diff = docDiffs[idx]; + const handlerResult = + diff.nodeType === 'paragraph' + ? replayParagraphDiff({ tr, diff, schema }) + : replayNonParagraphDiff({ tr, diff, schema }); + result.applied += handlerResult.applied; + result.skipped += handlerResult.skipped; + result.warnings.push(...handlerResult.warnings); + } + + return result; } diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts index 2f5ba761d6..f7798670a3 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts @@ -46,6 +46,10 @@ export function replayNonParagraphDiff({ } const { pos } = diff; + if (pos < 0 || pos > tr.doc.content.size) { + skipWithWarning(`Position ${pos} outside of document.`); + return result; + } if (diff.action === 'added') { if (!diff.nodeJSON) { diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts index 672bdcd91c..9cb40eed3f 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts @@ -39,6 +39,10 @@ export function replayParagraphDiff({ }; const { pos } = diff; + if (pos < 0 || pos > tr.doc.content.size) { + skipWithWarning(`Position ${pos} outside of document.`); + return result; + } if (diff.action === 'added') { if (!diff.nodeJSON) { diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 9a57d6c682..12fe8f7c08 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -1,34 +1,152 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; +import { EditorState } from 'prosemirror-state'; +import { getStarterExtensions } from '@extensions/index.js'; +import { createMinimalTestEditor } from '@tests/helpers/editor-test-utils.js'; + +vi.mock('@extensions/track-changes/trackChangesHelpers/trackedTransaction.js', () => { + return { + trackedTransaction: vi.fn(({ tr }) => tr), + }; +}); + +import { trackedTransaction } from '@extensions/track-changes/trackChangesHelpers/trackedTransaction.js'; import { replayDiffs } from './replayDiffs'; -import { - replayDocDiffs, - replayNonParagraphDiff, - replayParagraphDiff, - replayInlineDiff, - applyAttrsDiff, - marksFromDiff, -} from './replay'; /** - * Verifies the replay entry points are exposed as functions. + * Builds a schema using the standard editor extensions. + * @returns {import('prosemirror-model').Schema} + */ +const createSchema = () => { + const editor = createMinimalTestEditor(getStarterExtensions(), { mode: 'docx', skipViewCreation: true }); + return editor.schema; +}; + +/** + * Builds a paragraph node with the given text. + * @param {import('prosemirror-model').Schema} schema + * @param {string} text + * @returns {import('prosemirror-model').Node} + */ +const createParagraph = (schema, text) => { + return schema.nodes.paragraph.create(null, schema.text(text)); +}; + +/** + * Verifies that diffs are replayed in reverse order. + * @returns {void} + */ +const testReverseOrderReplay = () => { + const schema = createSchema(); + const doc = schema.nodes.doc.create(null, [createParagraph(schema, 'A')]); + const state = EditorState.create({ schema, doc }); + + const diff = { + docDiffs: [ + { + action: 'added', + nodeType: 'paragraph', + nodeJSON: createParagraph(schema, 'B').toJSON(), + text: 'B', + pos: doc.content.size, + }, + { + action: 'added', + nodeType: 'paragraph', + nodeJSON: createParagraph(schema, 'C').toJSON(), + text: 'C', + pos: doc.content.size, + }, + ], + commentDiffs: [], + }; + + const result = replayDiffs({ + state, + diff, + schema, + options: { user: { name: 'Test', email: 'test@example.com' }, applyTrackedChanges: false }, + }); + + expect(result.appliedDiffs).toBe(2); + expect(result.skippedDiffs).toBe(0); + expect(result.tr.doc.child(0).textContent).toBe('A'); + expect(result.tr.doc.child(1).textContent).toBe('B'); + expect(result.tr.doc.child(2).textContent).toBe('C'); +}; + +/** + * Verifies replay results aggregate applied and skipped diffs with warnings. * @returns {void} */ -const testReplayEntrypoints = () => { - expect(typeof replayDiffs).toBe('function'); - expect(typeof replayDocDiffs).toBe('function'); - expect(typeof replayNonParagraphDiff).toBe('function'); - expect(typeof replayParagraphDiff).toBe('function'); - expect(typeof replayInlineDiff).toBe('function'); - expect(typeof applyAttrsDiff).toBe('function'); - expect(typeof marksFromDiff).toBe('function'); +const testReplayAggregation = () => { + const schema = createSchema(); + const doc = schema.nodes.doc.create(null, [createParagraph(schema, 'A')]); + const state = EditorState.create({ schema, doc }); + + const diff = { + docDiffs: [ + { + action: 'added', + nodeType: 'paragraph', + nodeJSON: createParagraph(schema, 'B').toJSON(), + text: 'B', + pos: doc.content.size, + }, + { + action: 'deleted', + nodeType: 'tableOfContents', + nodeJSON: { type: 'tableOfContents' }, + pos: 999, + }, + ], + commentDiffs: [], + }; + + const result = replayDiffs({ + state, + diff, + schema, + options: { user: { name: 'Test', email: 'test@example.com' }, applyTrackedChanges: false }, + }); + + expect(result.appliedDiffs).toBe(1); + expect(result.skippedDiffs).toBe(1); + expect(result.warnings.length).toBeGreaterThan(0); }; + +/** + * Verifies trackedTransaction is invoked when tracked changes are enabled. + * @returns {void} + */ +const testTrackedChangesInvocation = () => { + const schema = createSchema(); + const doc = schema.nodes.doc.create(null, [createParagraph(schema, 'A')]); + const state = EditorState.create({ schema, doc }); + + const diff = { + docDiffs: [], + commentDiffs: [], + }; + + replayDiffs({ + state, + diff, + schema, + options: { user: { name: 'Test', email: 'test@example.com' }, applyTrackedChanges: true }, + }); + + expect(trackedTransaction).toHaveBeenCalledTimes(1); +}; + /** - * Runs the replay scaffolding suite. + * Runs the replayDiffs orchestration suite. * @returns {void} */ -const runReplayScaffoldingSuite = () => { - it('exposes replay entry points', testReplayEntrypoints); +const runReplayDiffsSuite = () => { + it('replays diffs in reverse order', testReverseOrderReplay); + it('aggregates applied/skipped diffs with warnings', testReplayAggregation); + it('invokes tracked changes when enabled', testTrackedChangesInvocation); }; -describe('replay diff scaffolding', runReplayScaffoldingSuite); +describe('replayDiffs', runReplayDiffsSuite); diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index 318347fe6c..668525601f 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -24,11 +24,44 @@ export type ReplayDiffsResult = { warnings: string[]; }; +import { trackedTransaction } from '@extensions/track-changes/trackChangesHelpers/trackedTransaction.js'; +import { replayDocDiffs } from './replay/replay-doc.ts'; + /** * Replays a diff result over the current editor state. * - * @returns Placeholder replay result until implemented. + * @param params Input bundle for replaying diffs. + * @param params.state Editor state anchored to the old document. + * @param params.diff Diff result to replay. + * @param params.schema Schema used to rebuild nodes. + * @param params.options Replay options controlling tracked changes behavior. + * @returns Summary and transaction containing the replayed steps. */ -export function replayDiffs(): ReplayDiffsResult { - throw new Error('replayDiffs is not implemented yet.'); +export function replayDiffs({ + state, + diff, + schema, + options, +}: { + state: import('prosemirror-state').EditorState; + diff: import('./computeDiff.ts').DiffResult; + schema: import('prosemirror-model').Schema; + options: ReplayDiffsOptions; +}): ReplayDiffsResult { + const tr = state.tr; + const docReplay = replayDocDiffs({ tr, docDiffs: diff.docDiffs, schema }); + const finalTr = options.applyTrackedChanges + ? trackedTransaction({ + tr, + state, + user: options.user, + }) + : tr; + + return { + tr: finalTr, + appliedDiffs: docReplay.applied, + skippedDiffs: docReplay.skipped, + warnings: docReplay.warnings, + }; } From fd3d4bc1fa5df05e3c3d43efd5b8b726ecd828dc Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 12:24:19 -0300 Subject: [PATCH 062/125] feat: add command for replaying diffs onto current document --- .../src/extensions/diffing/diffing.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 9317a7e38a..0585402cd0 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -1,6 +1,7 @@ // @ts-nocheck import { Extension } from '@core/Extension.js'; import { computeDiff } from './computeDiff.ts'; +import { replayDiffs } from './replayDiffs.ts'; export const Diffing = Extension.create({ name: 'documentDiffing', @@ -31,6 +32,25 @@ export const Diffing = Extension.create({ ); return diffs; }, + + /** + * Replays a diff result onto the current document as tracked changes. + * + * @param {import('./computeDiff.ts').DiffResult} diff + * @param {{ user: import('@core/types/EditorConfig.js').User; applyTrackedChanges?: boolean }} options + * @returns {import('prosemirror-state').Transaction} + */ + replayDifferences: + (diff, { user, applyTrackedChanges = true }) => + ({ state }) => { + const result = replayDiffs({ + state, + diff, + schema: state.schema, + options: { user, applyTrackedChanges }, + }); + return result.tr; + }, }; }, }); From 656e97a67a31251f48fa7c163b7ec9cab5c9a02a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 12:38:00 -0300 Subject: [PATCH 063/125] feat: add button to dev playground to allow comparing documents --- .../src/dev/components/SuperdocDev.vue | 122 +++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/packages/superdoc/src/dev/components/SuperdocDev.vue b/packages/superdoc/src/dev/components/SuperdocDev.vue index 2d3f1d7ccc..c67cdc7960 100644 --- a/packages/superdoc/src/dev/components/SuperdocDev.vue +++ b/packages/superdoc/src/dev/components/SuperdocDev.vue @@ -8,7 +8,7 @@ import { DOCX, PDF, HTML } from '@superdoc/common'; import { getFileObject } from '@superdoc/common'; import BasicUpload from '@superdoc/common/components/BasicUpload.vue'; import SuperdocLogo from './superdoc-logo.webp?url'; -import { fieldAnnotationHelpers } from '@superdoc/super-editor'; +import { Editor, fieldAnnotationHelpers, getStarterExtensions } from '@superdoc/super-editor'; import { toolbarIcons } from '../../../../super-editor/src/components/toolbar/toolbarIcons'; import BlankDOCX from '@superdoc/common/data/blank.docx?url'; import * as pdfjsLib from 'pdfjs-dist/build/pdf.mjs'; @@ -31,6 +31,7 @@ const currentFile = ref(null); const commentsPanel = ref(null); const showCommentsPanel = ref(true); const sidebarInstanceKey = ref(0); +const compareInput = ref(null); const urlParams = new URLSearchParams(window.location.search); const wordBaselineServiceUrl = 'http://127.0.0.1:9185'; @@ -241,6 +242,106 @@ const handleNewFile = async (file) => { sidebarInstanceKey.value += 1; }; +/** + * Triggers the compare file picker. + * @returns {void} + */ +const handleCompareClick = () => { + compareInput.value?.click?.(); +}; + +/** + * Loads a comparison DOCX file, computes diffs, and replays tracked changes. + * @param {Event} event + * @returns {Promise} + */ +const handleCompareFile = async (event) => { + const file = event?.target?.files?.[0]; + if (!file) return; + event.target.value = ''; + + const editor = activeEditor.value; + if (!editor) return; + + let compareEditor = null; + try { + const [docx, media, mediaFiles, fonts] = (await Editor.loadXmlData(file)) || []; + if (!docx) return; + + compareEditor = new Editor({ + isHeadless: true, + skipViewCreation: true, + extensions: getStarterExtensions(), + documentId: `compare-${Date.now()}`, + content: docx, + mode: 'docx', + media, + mediaFiles, + fonts, + annotations: true, + }); + + const compareDoc = compareEditor.state.doc; + const compareComments = compareEditor.converter?.comments ?? []; + const diff = editor.commands.compareDocuments(compareDoc, compareComments); + const userToApply = editor.options?.user ?? user; + const tr = editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); + editor.view.dispatch(tr); + } finally { + compareEditor?.destroy?.(); + } +}; + +/** + * Triggers the compare file picker. + * @returns {void} + */ +const handleCompareClick = () => { + compareInput.value?.click?.(); +}; + +/** + * Loads a comparison DOCX file, computes diffs, and replays tracked changes. + * @param {Event} event + * @returns {Promise} + */ +const handleCompareFile = async (event) => { + const file = event?.target?.files?.[0]; + if (!file) return; + event.target.value = ''; + + const editor = activeEditor.value; + if (!editor) return; + + let compareEditor = null; + try { + const [docx, media, mediaFiles, fonts] = (await Editor.loadXmlData(file)) || []; + if (!docx) return; + + compareEditor = new Editor({ + isHeadless: true, + skipViewCreation: true, + extensions: getStarterExtensions(), + documentId: `compare-${Date.now()}`, + content: docx, + mode: 'docx', + media, + mediaFiles, + fonts, + annotations: true, + }); + + const compareDoc = compareEditor.state.doc; + const compareComments = compareEditor.converter?.comments ?? []; + const diff = editor.commands.compareDocuments(compareDoc, compareComments); + const userToApply = editor.options?.user ?? user; + const tr = editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); + editor.view.dispatch(tr); + } finally { + compareEditor?.destroy?.(); + } +}; + /** * Read a file as text content * @param {File} file - The file to read @@ -1380,6 +1481,16 @@ if (scrollTestMode.value) { {{ currentZoom }}% +
+ + +
@@ -1888,6 +1999,15 @@ if (scrollTestMode.value) { border-color: rgba(148, 163, 184, 0.25); } +.dev-app__compare-control { + display: inline-flex; + align-items: center; +} + +.dev-app__compare-input { + display: none; +} + .dev-app__main { display: flex; justify-content: center; From 6a8b836702c57567a7d5dda5e701594828de3268 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 12:38:28 -0300 Subject: [PATCH 064/125] feat: include diffing extension --- packages/super-editor/src/extensions/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/super-editor/src/extensions/index.js b/packages/super-editor/src/extensions/index.js index a7fac28bf0..a4f681e8ea 100644 --- a/packages/super-editor/src/extensions/index.js +++ b/packages/super-editor/src/extensions/index.js @@ -225,6 +225,7 @@ const getStarterExtensions = () => { VerticalNavigation, PassthroughInline, PassthroughBlock, + Diffing, ]; }; From 98e80b4d441dcbc474b3db80f6ef7bfabd6e713b Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 2 Jan 2026 18:31:14 -0300 Subject: [PATCH 065/125] feat: improve replay accuracy for inline/run attrs and tracked changes --- .../src/extensions/diffing/diffing.js | 17 +- .../diffing/replay/replay-attrs.test.js | 51 +++ .../extensions/diffing/replay/replay-attrs.ts | 102 +++++- .../diffing/replay/replay-inline.test.js | 2 + .../diffing/replay/replay-inline.ts | 61 +++- .../diffing/replay/replay-paragraph.ts | 35 ++- .../extensions/diffing/replayDiffs.test.js | 296 +++++++++++------- .../src/extensions/diffing/replayDiffs.ts | 31 +- .../trackChangesHelpers/trackedTransaction.js | 2 +- .../src/dev/components/SuperdocDev.vue | 4 +- 10 files changed, 426 insertions(+), 175 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-attrs.test.js diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 0585402cd0..44d5d0587d 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -41,15 +41,20 @@ export const Diffing = Extension.create({ * @returns {import('prosemirror-state').Transaction} */ replayDifferences: - (diff, { user, applyTrackedChanges = true }) => - ({ state }) => { - const result = replayDiffs({ - state, + (diff, { applyTrackedChanges = true }) => + ({ state, dispatch }) => { + replayDiffs({ + tr: state.tr, diff, schema: state.schema, - options: { user, applyTrackedChanges }, }); - return result.tr; + if (applyTrackedChanges) { + state.tr.setMeta('trackChanges', true); + } + if (dispatch && state.tr.docChanged) { + dispatch(state.tr); + } + return true; }, }; }, diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.test.js new file mode 100644 index 0000000000..d1ab510f19 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.test.js @@ -0,0 +1,51 @@ +import { describe, it, expect } from 'vitest'; + +import { applyAttrsDiff } from './replay-attrs.js'; + +/** + * Verifies added and modified paths are applied. + * @returns {void} + */ +const testApplyAttrsDiffAddsAndModifies = () => { + const result = applyAttrsDiff({ + attrs: { foo: 'bar', nested: { keep: true } }, + diff: { + added: { 'nested.newKey': 'new' }, + deleted: {}, + modified: { + foo: { from: 'bar', to: 'baz' }, + }, + }, + }); + + expect(result.foo).toBe('baz'); + expect(result.nested).toEqual({ keep: true, newKey: 'new' }); +}; + +/** + * Verifies deleted paths are removed. + * @returns {void} + */ +const testApplyAttrsDiffDeletes = () => { + const result = applyAttrsDiff({ + attrs: { foo: 'bar', nested: { remove: 'yes', keep: 'ok' } }, + diff: { + added: {}, + deleted: { 'nested.remove': 'yes' }, + modified: {}, + }, + }); + + expect(result.nested).toEqual({ keep: 'ok' }); +}; + +/** + * Runs the applyAttrsDiff suite. + * @returns {void} + */ +const runApplyAttrsDiffSuite = () => { + it('applies added and modified attributes', testApplyAttrsDiffAddsAndModifies); + it('removes deleted attributes', testApplyAttrsDiffDeletes); +}; + +describe('applyAttrsDiff', runApplyAttrsDiffSuite); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts index 4ae49cd4b6..ea80f99647 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts @@ -1,8 +1,102 @@ +import { AttributesDiff } from '../algorithm/attributes-diffing.ts'; + /** - * Applies an attribute diff to a node, preserving its content. + * Applies an attribute diff to an attributes object. * - * @returns Placeholder result until implemented. + * @param params Input bundle for applying attribute diffs. + * @param params.attrs Base attributes object to update. + * @param params.diff Attribute diff to apply. + * @returns Updated attributes object. */ -export function applyAttrsDiff(): void { - throw new Error('applyAttrsDiff is not implemented yet.'); +export function applyAttrsDiff({ + attrs, + diff, +}: { + attrs: Record; + diff: AttributesDiff; +}): Record { + const updated = JSON.parse(JSON.stringify(attrs ?? {})); + + Object.entries(diff.added || {}).forEach(([path, value]) => { + setNestedValue(updated, path, value); + }); + + Object.entries(diff.modified || {}).forEach(([path, change]) => { + setNestedValue(updated, path, change.to); + }); + + Object.keys(diff.deleted || {}).forEach((path) => { + deleteNestedValue(updated, path); + }); + + return updated; } + +/** + * Assigns a value to a dot-notation path within an object. + * + * @param target Attributes object to mutate. + * @param path Dot-notation path to update. + * @param value Value to assign at the path. + */ +const setNestedValue = (target: Record, path: string, value: unknown) => { + if (!path.includes('.')) { + target[path] = value; + return; + } + + const parts = path.split('.'); + let current: Record = target; + + for (let i = 0; i < parts.length; i += 1) { + const key = parts[i]; + const isLast = i === parts.length - 1; + if (isLast) { + current[key] = value; + } else { + if (!isPlainObject(current[key])) { + current[key] = {}; + } + current = current[key] as Record; + } + } +}; + +/** + * Deletes a value at a dot-notation path within an object. + * + * @param target Attributes object to mutate. + * @param path Dot-notation path to delete. + */ +const deleteNestedValue = (target: Record, path: string) => { + if (!path.includes('.')) { + delete target[path]; + return; + } + + const parts = path.split('.'); + let current: Record = target; + + for (let i = 0; i < parts.length; i += 1) { + const key = parts[i]; + const isLast = i === parts.length - 1; + if (isLast) { + delete current[key]; + return; + } + if (!isPlainObject(current[key])) { + return; + } + current = current[key] as Record; + } +}; + +/** + * Determines whether a value is a plain object. + * + * @param value Value to inspect. + * @returns True when the value is a non-null object and not an array. + */ +const isPlainObject = (value: unknown): value is Record => { + return Boolean(value) && typeof value === 'object' && !Array.isArray(value); +}; diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js index 138d371c6d..e93ac0e763 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js @@ -115,6 +115,7 @@ const testTextDeleteRange = () => { kind: 'text', startPos, endPos, + text: 'ell', }; const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: endPos }); @@ -143,6 +144,7 @@ const testTextModifyRange = () => { kind: 'text', startPos, endPos, + oldText: 'H', newText: 'Y', marks: [], marksDiff: null, diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index fd32c38218..42ff0629e8 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -1,6 +1,7 @@ import { Fragment, Slice } from 'prosemirror-model'; import { ReplaceStep } from 'prosemirror-transform'; +import { applyAttrsDiff } from './replay-attrs.ts'; import { marksFromDiff } from './marks-from-diff.ts'; import { ReplayResult } from './replay-types.ts'; @@ -68,6 +69,14 @@ export function replayInlineDiff({ } if (diff.kind === 'text') { + const textForRange = diff.action === 'modified' ? diff.oldText : diff.text; + const rangeLength = typeof textForRange === 'string' ? textForRange.length : null; + if (!isAddition && rangeLength !== null && from !== null) { + to = from + rangeLength; + } else if (!isAddition && to !== null && from !== null) { + to = to + 1; + } + if (isAddition) { if (!diff.text) { skipWithWarning('Missing text content for inline addition.'); @@ -102,10 +111,17 @@ export function replayInlineDiff({ } if (isModification) { - if (!diff.newText) { + if (diff.newText == null) { skipWithWarning('Missing newText for inline modification.'); return result; } + if (diff.runAttrsDiff) { + const runUpdate = applyRunAttrsDiff(tr, from, diff.runAttrsDiff); + result.applied += runUpdate.applied; + if (runUpdate.warning) { + skipWithWarning(runUpdate.warning); + } + } const oldMarks = getMarksAtPosition(tr.doc, from); const marks = marksFromDiff({ schema, @@ -151,6 +167,12 @@ export function replayInlineDiff({ } if (isDeletion) { + const node = tr.doc.nodeAt(from); + if (!node) { + skipWithWarning(`No inline node found at ${from} for deletion.`); + return result; + } + to = from + node.nodeSize; const step = new ReplaceStep(from, to, Slice.empty); const stepResult = tr.maybeStep(step); if (stepResult.failed) { @@ -167,6 +189,12 @@ export function replayInlineDiff({ return result; } try { + const existingNode = tr.doc.nodeAt(from); + if (!existingNode) { + skipWithWarning(`No inline node found at ${from} for modification.`); + return result; + } + to = from + existingNode.nodeSize; const node = schema.nodeFromJSON(diff.newNodeJSON); const slice = new Slice(Fragment.from(node), 0, 0); const step = new ReplaceStep(from, to, slice); @@ -209,3 +237,34 @@ const getMarksAtPosition = ( attrs: mark.attrs ?? {}, })); }; + +/** + * Applies a run-attributes diff to the nearest run node at a position. + * + * @param tr Transaction to update. + * @param pos Document position to resolve. + * @param diff Run-attributes diff to apply. + * @returns Result describing whether the update was applied. + */ +const applyRunAttrsDiff = ( + tr: import('prosemirror-state').Transaction, + pos: number, + diff: import('../algorithm/attributes-diffing.ts').AttributesDiff, +): { applied: number; warning?: string } => { + const resolved = tr.doc.resolve(pos); + for (let depth = resolved.depth; depth > 0; depth -= 1) { + const node = resolved.node(depth); + if (node.type.name !== 'run') { + continue; + } + const nodePos = resolved.before(depth); + const updatedAttrs = applyAttrsDiff({ attrs: node.attrs, diff }); + try { + tr.setNodeMarkup(nodePos, undefined, updatedAttrs, node.marks); + return { applied: 1 }; + } catch (error) { + return { applied: 0, warning: `Failed to update run attrs at ${nodePos}.` }; + } + } + return { applied: 0, warning: `No run node found at ${pos} for run-attr update.` }; +}; diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts index 9cb40eed3f..4bb1ef6658 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts @@ -97,8 +97,27 @@ export function replayParagraphDiff({ return result; } + // if (diff.attrsDiff) { + // if (!diff.newNodeJSON?.attrs) { + // skipWithWarning(`Missing newNodeJSON attrs at pos ${pos} for paragraph modification.`); + // return result; + // } + // try { + // tr.setNodeMarkup(pos, undefined, diff.newNodeJSON.attrs, node.marks); + // result.applied += 1; + // } catch (error) { + // skipWithWarning(`Failed to update paragraph attrs at pos ${pos}.`); + // return result; + // } + // } + const paragraphEndPos = pos + 1 + node.content.size; - const contentDiffs = diff.contentDiff ?? []; + const contentDiffs = [...(diff.contentDiff ?? [])].sort((a, b) => { + const aPos = a.startPos ?? paragraphEndPos; + const bPos = b.startPos ?? paragraphEndPos; + if (aPos === bPos) return 0; + return aPos - bPos; + }); for (let idx = contentDiffs.length - 1; idx >= 0; idx -= 1) { const inlineDiff = contentDiffs[idx]; const inlineResult = replayInlineDiff({ @@ -112,20 +131,6 @@ export function replayParagraphDiff({ result.warnings.push(...inlineResult.warnings); } - if (diff.attrsDiff) { - if (!diff.newNodeJSON?.attrs) { - skipWithWarning(`Missing newNodeJSON attrs at pos ${pos} for paragraph modification.`); - return result; - } - try { - tr.setNodeMarkup(pos, undefined, diff.newNodeJSON.attrs, node.marks); - result.applied += 1; - } catch (error) { - skipWithWarning(`Failed to update paragraph attrs at pos ${pos}.`); - return result; - } - } - return result; } diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 12fe8f7c08..618d8df16d 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -1,152 +1,210 @@ -import { describe, it, expect, vi } from 'vitest'; -import { EditorState } from 'prosemirror-state'; +import { describe, it, expect } from 'vitest'; +import { Editor } from '@core/Editor.js'; import { getStarterExtensions } from '@extensions/index.js'; -import { createMinimalTestEditor } from '@tests/helpers/editor-test-utils.js'; - -vi.mock('@extensions/track-changes/trackChangesHelpers/trackedTransaction.js', () => { - return { - trackedTransaction: vi.fn(({ tr }) => tr), - }; -}); - -import { trackedTransaction } from '@extensions/track-changes/trackChangesHelpers/trackedTransaction.js'; +import { getTrackChanges } from '@extensions/track-changes/trackChangesHelpers/getTrackChanges.js'; +import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers.js'; +import { computeDiff } from './computeDiff'; import { replayDiffs } from './replayDiffs'; /** - * Builds a schema using the standard editor extensions. - * @returns {import('prosemirror-model').Schema} + * Loads a DOCX fixture and returns a headless editor instance. + * @param {string} name DOCX fixture filename. + * @returns {Promise} */ -const createSchema = () => { - const editor = createMinimalTestEditor(getStarterExtensions(), { mode: 'docx', skipViewCreation: true }); - return editor.schema; +const getEditorFromFixture = async (name) => { + const buffer = await getTestDataAsBuffer(`diffing/${name}`); + const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); + + return new Editor({ + isHeadless: true, + extensions: getStarterExtensions(), + documentId: `test-${name}`, + content: docx, + mode: 'docx', + media, + mediaFiles, + fonts, + annotations: true, + }); }; /** - * Builds a paragraph node with the given text. - * @param {import('prosemirror-model').Schema} schema - * @param {string} text - * @returns {import('prosemirror-model').Node} + * Determines whether a remaining diff is an acceptable formatting-only delta. + * @param {import('./algorithm/generic-diffing.ts').NodeDiff} diff + * @returns {boolean} */ -const createParagraph = (schema, text) => { - return schema.nodes.paragraph.create(null, schema.text(text)); +const isAcceptableRemainingDiff = (diff) => { + if (diff.action !== 'modified' || diff.nodeType !== 'paragraph') { + return false; + } + if (diff.oldText !== diff.newText || diff.attrsDiff) { + return false; + } + return (diff.contentDiff || []).every((change) => { + if (change.kind === 'inlineNode') { + return ( + ['added', 'deleted'].includes(change.action) && + ['tab', 'image', 'commentRangeStart', 'commentRangeEnd'].includes(change.nodeType) + ); + } + return ( + change.action === 'modified' && + change.kind === 'text' && + change.oldText === change.newText && + (change.runAttrsDiff || change.marksDiff) + ); + }); }; /** - * Verifies that diffs are replayed in reverse order. - * @returns {void} + * Replays diffs between two DOCX fixtures and asserts the content matches. + * @param {string} beforeName DOCX fixture filename for the baseline. + * @param {string} afterName DOCX fixture filename for the updated doc. + * @returns {Promise} */ -const testReverseOrderReplay = () => { - const schema = createSchema(); - const doc = schema.nodes.doc.create(null, [createParagraph(schema, 'A')]); - const state = EditorState.create({ schema, doc }); - - const diff = { - docDiffs: [ - { - action: 'added', - nodeType: 'paragraph', - nodeJSON: createParagraph(schema, 'B').toJSON(), - text: 'B', - pos: doc.content.size, - }, - { - action: 'added', - nodeType: 'paragraph', - nodeJSON: createParagraph(schema, 'C').toJSON(), - text: 'C', - pos: doc.content.size, - }, - ], - commentDiffs: [], - }; - - const result = replayDiffs({ - state, - diff, - schema, - options: { user: { name: 'Test', email: 'test@example.com' }, applyTrackedChanges: false }, - }); +const expectReplayMatchesFixture = async (beforeName, afterName) => { + const beforeEditor = await getEditorFromFixture(beforeName); + const afterEditor = await getEditorFromFixture(afterName); + + try { + const initialDiffs = computeDiff(beforeEditor.state.doc, afterEditor.state.doc, beforeEditor.schema).docDiffs; + const originalDocJSON = beforeEditor.state.doc.toJSON(); + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const { tr } = replayDiffs({ + state: beforeEditor.state, + diff, + schema: beforeEditor.schema, + options: { user: { name: 'Test User', email: 'test@example.com' }, applyTrackedChanges: false }, + }); + beforeEditor.view.dispatch(tr); + + const replayDiffsResult = computeDiff(beforeEditor.state.doc, afterEditor.state.doc, beforeEditor.schema).docDiffs; + expect(beforeEditor.state.doc.toJSON()).not.toEqual(originalDocJSON); + expect(beforeEditor.state.doc.textContent).toBe(afterEditor.state.doc.textContent); + expect(replayDiffsResult.every(isAcceptableRemainingDiff)).toBe(true); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } +}; - expect(result.appliedDiffs).toBe(2); - expect(result.skippedDiffs).toBe(0); - expect(result.tr.doc.child(0).textContent).toBe('A'); - expect(result.tr.doc.child(1).textContent).toBe('B'); - expect(result.tr.doc.child(2).textContent).toBe('C'); +/** + * Replays diffs with tracked changes enabled and verifies acceptance matches the updated fixture. + * @param {string} beforeName DOCX fixture filename for the baseline. + * @param {string} afterName DOCX fixture filename for the updated doc. + * @returns {Promise} + */ +const expectTrackedReplayMatchesFixture = async (beforeName, afterName) => { + const beforeEditor = await getEditorFromFixture(beforeName); + const afterEditor = await getEditorFromFixture(afterName); + + try { + const originalDocJSON = beforeEditor.state.doc.toJSON(); + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const { tr } = replayDiffs({ + state: beforeEditor.state, + diff, + schema: beforeEditor.schema, + options: { user: { name: 'Test User', email: 'test@example.com' }, applyTrackedChanges: true }, + }); + beforeEditor.view.dispatch(tr); + + expect(beforeEditor.state.doc.toJSON()).not.toEqual(originalDocJSON); + expect(getTrackChanges(beforeEditor.state).length).toBeGreaterThan(0); + expect(beforeEditor.commands.acceptAllTrackedChanges()).toBe(true); + expect(getTrackChanges(beforeEditor.state).length).toBe(0); + + const replayDiffsResult = computeDiff(beforeEditor.state.doc, afterEditor.state.doc, beforeEditor.schema).docDiffs; + expect(beforeEditor.state.doc.textContent).toBe(afterEditor.state.doc.textContent); + expect(replayDiffsResult.every(isAcceptableRemainingDiff)).toBe(true); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } }; /** - * Verifies replay results aggregate applied and skipped diffs with warnings. - * @returns {void} + * Fixture pairs used for replay coverage. + * @returns {Array<[string, string]>} */ -const testReplayAggregation = () => { - const schema = createSchema(); - const doc = schema.nodes.doc.create(null, [createParagraph(schema, 'A')]); - const state = EditorState.create({ schema, doc }); - - const diff = { - docDiffs: [ - { - action: 'added', - nodeType: 'paragraph', - nodeJSON: createParagraph(schema, 'B').toJSON(), - text: 'B', - pos: doc.content.size, - }, - { - action: 'deleted', - nodeType: 'tableOfContents', - nodeJSON: { type: 'tableOfContents' }, - pos: 999, - }, - ], - commentDiffs: [], - }; - - const result = replayDiffs({ - state, - diff, - schema, - options: { user: { name: 'Test', email: 'test@example.com' }, applyTrackedChanges: false }, - }); +const getReplayFixturePairs = () => [ + ['diff_before.docx', 'diff_after.docx'], + ['diff_before2.docx', 'diff_after2.docx'], + ['diff_before3.docx', 'diff_after3.docx'], + ['diff_before4.docx', 'diff_after4.docx'], + ['diff_before5.docx', 'diff_after5.docx'], + ['diff_before6.docx', 'diff_after6.docx'], + ['diff_before7.docx', 'diff_after7.docx'], + ['diff_before8.docx', 'diff_after8.docx'], + ['diff_before9.docx', 'diff_after9.docx'], +]; - expect(result.appliedDiffs).toBe(1); - expect(result.skippedDiffs).toBe(1); - expect(result.warnings.length).toBeGreaterThan(0); -}; +/** + * Fixture pairs used for replay coverage with tracked changes enabled. + * Limited to fixtures compatible with trackedTransaction's structure constraints. + * @returns {Array<[string, string]>} + */ +const getTrackedReplayFixturePairs = () => [ + ['diff_before3.docx', 'diff_after3.docx'], + ['diff_before4.docx', 'diff_after4.docx'], + ['diff_before5.docx', 'diff_after5.docx'], + ['diff_before6.docx', 'diff_after6.docx'], + ['diff_before8.docx', 'diff_after8.docx'], + ['diff_before9.docx', 'diff_after9.docx'], +]; /** - * Verifies trackedTransaction is invoked when tracked changes are enabled. + * Runs the replayDiffs fixture suite. * @returns {void} */ -const testTrackedChangesInvocation = () => { - const schema = createSchema(); - const doc = schema.nodes.doc.create(null, [createParagraph(schema, 'A')]); - const state = EditorState.create({ schema, doc }); - - const diff = { - docDiffs: [], - commentDiffs: [], - }; - - replayDiffs({ - state, - diff, - schema, - options: { user: { name: 'Test', email: 'test@example.com' }, applyTrackedChanges: true }, +const runReplayDiffsSuite = () => { + getReplayFixturePairs().forEach(([beforeName, afterName]) => { + it(`replays diffs for ${beforeName}`, async () => { + await expectReplayMatchesFixture(beforeName, afterName); + }); }); - - expect(trackedTransaction).toHaveBeenCalledTimes(1); }; /** - * Runs the replayDiffs orchestration suite. + * Runs the replayDiffs tracked changes fixture suite. * @returns {void} */ -const runReplayDiffsSuite = () => { - it('replays diffs in reverse order', testReverseOrderReplay); - it('aggregates applied/skipped diffs with warnings', testReplayAggregation); - it('invokes tracked changes when enabled', testTrackedChangesInvocation); +const runTrackedReplayDiffsSuite = () => { + getTrackedReplayFixturePairs().forEach(([beforeName, afterName]) => { + it(`replays diffs with tracked changes for ${beforeName}`, async () => { + await expectTrackedReplayMatchesFixture(beforeName, afterName); + }); + }); }; describe('replayDiffs', runReplayDiffsSuite); +describe('replayDiffs tracked changes', runTrackedReplayDiffsSuite); +describe('investigate replay issues', () => { + it('investigate diff_before10.docx', async () => { + const beforeEditor = await getEditorFromFixture('diff_before10.docx'); + const afterEditor = await getEditorFromFixture('diff_after10.docx'); + + try { + const originalDocJSON = beforeEditor.state.doc.toJSON(); + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const success = beforeEditor.commands.replayDifferences(diff, { + user: { user: { name: 'Test User', email: 'test@example.com' }, applyTrackedChanges: true }, + }); + console.log('Replay success:', success); + + expect(beforeEditor.state.doc.toJSON()).not.toEqual(originalDocJSON); + expect(beforeEditor.state.doc.textContent).toBe(afterEditor.state.doc.textContent); + console.log(JSON.stringify(beforeEditor.state.doc.toJSON(), null, 2)); + const replayDiffsResult = computeDiff( + beforeEditor.state.doc, + afterEditor.state.doc, + beforeEditor.schema, + ).docDiffs; + // expect(replayDiffsResult.every(isAcceptableRemainingDiff)).toBe(true); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index 668525601f..cf89806be2 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -1,14 +1,3 @@ -/** - * Options that control how diff replay is performed. - * - * @property user Identity used for tracked changes. - * @property applyTrackedChanges Whether to apply tracked changes logic. - */ -export type ReplayDiffsOptions = { - user: { name: string; email: string; image?: string }; - applyTrackedChanges: boolean; -}; - /** * Result summary from replaying diffs into a transaction. * @@ -24,42 +13,30 @@ export type ReplayDiffsResult = { warnings: string[]; }; -import { trackedTransaction } from '@extensions/track-changes/trackChangesHelpers/trackedTransaction.js'; import { replayDocDiffs } from './replay/replay-doc.ts'; /** * Replays a diff result over the current editor state. * * @param params Input bundle for replaying diffs. - * @param params.state Editor state anchored to the old document. + * @param params.tr Transaction to append steps to. * @param params.diff Diff result to replay. * @param params.schema Schema used to rebuild nodes. - * @param params.options Replay options controlling tracked changes behavior. * @returns Summary and transaction containing the replayed steps. */ export function replayDiffs({ - state, + tr, diff, schema, - options, }: { - state: import('prosemirror-state').EditorState; + tr: import('prosemirror-state').Transaction; diff: import('./computeDiff.ts').DiffResult; schema: import('prosemirror-model').Schema; - options: ReplayDiffsOptions; }): ReplayDiffsResult { - const tr = state.tr; const docReplay = replayDocDiffs({ tr, docDiffs: diff.docDiffs, schema }); - const finalTr = options.applyTrackedChanges - ? trackedTransaction({ - tr, - state, - user: options.user, - }) - : tr; return { - tr: finalTr, + tr, appliedDiffs: docReplay.applied, skippedDiffs: docReplay.skipped, warnings: docReplay.warnings, diff --git a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js index 2f5ddc9f38..7d17125f02 100644 --- a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js +++ b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js @@ -20,7 +20,7 @@ export const trackedTransaction = ({ tr, state, user }) => { const notAllowedMeta = ['historyUndo', 'historyRedo', 'acceptReject']; const isProgrammaticInput = tr.getMeta('inputType') === 'programmatic'; const ySyncMeta = tr.getMeta(ySyncPluginKey); - const allowedMeta = new Set([...onlyInputTypeMeta, ySyncPluginKey.key]); + const allowedMeta = new Set([...onlyInputTypeMeta, ySyncPluginKey.key, 'trackChanges']); const hasDisallowedMeta = tr.meta && Object.keys(tr.meta).some((meta) => !allowedMeta.has(meta)); if ( diff --git a/packages/superdoc/src/dev/components/SuperdocDev.vue b/packages/superdoc/src/dev/components/SuperdocDev.vue index c67cdc7960..9ea3cf9679 100644 --- a/packages/superdoc/src/dev/components/SuperdocDev.vue +++ b/packages/superdoc/src/dev/components/SuperdocDev.vue @@ -335,8 +335,8 @@ const handleCompareFile = async (event) => { const compareComments = compareEditor.converter?.comments ?? []; const diff = editor.commands.compareDocuments(compareDoc, compareComments); const userToApply = editor.options?.user ?? user; - const tr = editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); - editor.view.dispatch(tr); + console.log('diffs', JSON.stringify(diff, null, 2)); + editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); } finally { compareEditor?.destroy?.(); } From 17c4fef05c10fad4b90bc1902ee6711aae018905 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 5 Jan 2026 11:50:52 -0300 Subject: [PATCH 066/125] fix: replay of formatting changes --- .../diffing/replay/marks-from-diff.ts | 9 +--- .../diffing/replay/replay-inline.ts | 42 +++++++++++-------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts index 85291cd323..eb2116520a 100644 --- a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts @@ -27,8 +27,8 @@ export function marksFromDiff({ } if (action === 'modified') { - if (marksDiff && oldMarks.length > 0) { - const updatedMarks = applyMarksDiff(oldMarks, marksDiff); + if (marksDiff) { + const updatedMarks = applyMarksDiff(marksDiff); return buildMarksFromJSON(schema, updatedMarks); } if (marks.length > 0) { @@ -52,15 +52,10 @@ export function marksFromDiff({ * @returns Updated mark JSON entries. */ const applyMarksDiff = ( - existingMarks: Array<{ type: string; attrs?: Record }>, marksDiff: import('../algorithm/attributes-diffing.ts').MarksDiff, ): Array<{ type: string; attrs?: Record }> => { const byType = new Map>(); - existingMarks.forEach((mark) => { - byType.set(mark.type, mark.attrs ?? {}); - }); - marksDiff.deleted.forEach((mark) => { byType.delete(mark.name); }); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index 42ff0629e8..df6f973df4 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -1,5 +1,5 @@ import { Fragment, Slice } from 'prosemirror-model'; -import { ReplaceStep } from 'prosemirror-transform'; +import { ReplaceStep, AddMarkStep, RemoveMarkStep } from 'prosemirror-transform'; import { applyAttrsDiff } from './replay-attrs.ts'; import { marksFromDiff } from './marks-from-diff.ts'; @@ -115,29 +115,35 @@ export function replayInlineDiff({ skipWithWarning('Missing newText for inline modification.'); return result; } - if (diff.runAttrsDiff) { - const runUpdate = applyRunAttrsDiff(tr, from, diff.runAttrsDiff); - result.applied += runUpdate.applied; - if (runUpdate.warning) { - skipWithWarning(runUpdate.warning); - } - } - const oldMarks = getMarksAtPosition(tr.doc, from); const marks = marksFromDiff({ schema, action: diff.action, marks: diff.marks, marksDiff: diff.marksDiff, - oldMarks, + oldMarks: [], }); - const textNode = schema.text(diff.newText, marks); - const slice = new Slice(Fragment.from(textNode), 0, 0); - const step = new ReplaceStep(from, to, slice); - const stepResult = tr.maybeStep(step); - if (stepResult.failed) { - skipWithWarning(`Failed to replace text at ${from}-${to}.`); - return result; - } + marks.forEach((mark) => { + const step = new AddMarkStep(from, to!, mark); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to add mark ${mark.type.name} at ${from}-${to}.`); + } + }); + + (diff.marksDiff?.deleted ?? []).forEach((markEntry) => { + const markType = schema.marks[markEntry.name]; + if (!markType) { + skipWithWarning(`Unknown mark type ${markEntry.name} for deletion.`); + return; + } + const mark = markType.create(markEntry.attrs || {}); + const step = new RemoveMarkStep(from, to!, mark); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to remove mark ${mark.type.name} at ${from}-${to}.`); + } + }); + result.applied += 1; return result; } From e8464b0e1a78af15f4b021a4c828852c01fbafdb Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 5 Jan 2026 12:03:21 -0300 Subject: [PATCH 067/125] fix: tracked change comment update --- .../src/extensions/comment/comments-plugin.js | 27 ++++++++------- .../comment/comments-plugin.test.js | 31 ++++++++++++++++++ .../diffing/replay/replay-paragraph.ts | 26 +++++++-------- .../src/tests/data/diffing/diff_after10.docx | Bin 0 -> 13306 bytes .../src/tests/data/diffing/diff_after9.docx | Bin 0 -> 13316 bytes .../src/tests/data/diffing/diff_before10.docx | Bin 0 -> 13267 bytes .../src/tests/data/diffing/diff_before9.docx | Bin 0 -> 13281 bytes 7 files changed, 59 insertions(+), 25 deletions(-) create mode 100644 packages/super-editor/src/tests/data/diffing/diff_after10.docx create mode 100644 packages/super-editor/src/tests/data/diffing/diff_after9.docx create mode 100644 packages/super-editor/src/tests/data/diffing/diff_before10.docx create mode 100644 packages/super-editor/src/tests/data/diffing/diff_before9.docx diff --git a/packages/super-editor/src/extensions/comment/comments-plugin.js b/packages/super-editor/src/extensions/comment/comments-plugin.js index eb4a38edaa..49e7f212f4 100644 --- a/packages/super-editor/src/extensions/comment/comments-plugin.js +++ b/packages/super-editor/src/extensions/comment/comments-plugin.js @@ -875,18 +875,21 @@ const handleTrackedChangeTransaction = (trackedChangeMeta, trackedChanges, newEd }); } - const emitParams = createOrUpdateTrackedChangeComment({ - documentId: editor.options.documentId, - event: isNewChange ? 'add' : 'update', - marks: { - insertedMark, - deletionMark, - formatMark, - }, - deletionNodes, - nodes, - newEditorState, - }); + const hasCandidateNodes = nodes.length > 0 || Boolean(deletionNodes?.length); + const emitParams = hasCandidateNodes + ? createOrUpdateTrackedChangeComment({ + documentId: editor.options.documentId, + event: isNewChange ? 'add' : 'update', + marks: { + insertedMark, + deletionMark, + formatMark, + }, + deletionNodes, + nodes, + newEditorState, + }) + : null; if (emitParams && emitCommentEvent) editor.emit('commentsUpdate', emitParams); diff --git a/packages/super-editor/src/extensions/comment/comments-plugin.test.js b/packages/super-editor/src/extensions/comment/comments-plugin.test.js index 184184f74f..deed071577 100644 --- a/packages/super-editor/src/extensions/comment/comments-plugin.test.js +++ b/packages/super-editor/src/extensions/comment/comments-plugin.test.js @@ -901,6 +901,37 @@ describe('internal helper functions', () => { ); }); + it('handleTrackedChangeTransaction emits event for deletion-only tracked changes when step nodes are empty', () => { + const schema = createCommentSchema(); + const deleteMark = schema.marks[TrackDeleteMarkName].create({ + id: 'change-delete-only', + author: 'Alice', + authorEmail: 'alice@example.com', + date: 'today', + }); + const deletedNode = schema.text('Removed', [deleteMark]); + const paragraph = schema.node('paragraph', null, [deletedNode]); + const doc = schema.node('doc', null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const editor = { options: { documentId: 'doc-1' }, emit: vi.fn() }; + + const meta = { + insertedMark: null, + deletionMark: deleteMark, + formatMark: null, + deletionNodes: [deletedNode], + step: { slice: { content: { content: [] } } }, + }; + + const trackedChanges = handleTrackedChangeTransaction(meta, {}, state, editor); + + expect(trackedChanges['change-delete-only']).toMatchObject({ deletion: 'change-delete-only' }); + expect(editor.emit).toHaveBeenCalledWith( + 'commentsUpdate', + expect.objectContaining({ event: comments_module_events.ADD, changeId: 'change-delete-only' }), + ); + }); + it('handleTrackedChangeTransaction returns original state when no marks provided', () => { const schema = createCommentSchema(); const doc = schema.node('doc', null, [schema.node('paragraph', null, [schema.text('Text')])]); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts index 4bb1ef6658..e4b0b2e211 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts @@ -97,19 +97,19 @@ export function replayParagraphDiff({ return result; } - // if (diff.attrsDiff) { - // if (!diff.newNodeJSON?.attrs) { - // skipWithWarning(`Missing newNodeJSON attrs at pos ${pos} for paragraph modification.`); - // return result; - // } - // try { - // tr.setNodeMarkup(pos, undefined, diff.newNodeJSON.attrs, node.marks); - // result.applied += 1; - // } catch (error) { - // skipWithWarning(`Failed to update paragraph attrs at pos ${pos}.`); - // return result; - // } - // } + if (diff.attrsDiff) { + if (!diff.newNodeJSON?.attrs) { + skipWithWarning(`Missing newNodeJSON attrs at pos ${pos} for paragraph modification.`); + return result; + } + try { + tr.setNodeMarkup(pos, undefined, diff.newNodeJSON.attrs, node.marks); + result.applied += 1; + } catch (error) { + skipWithWarning(`Failed to update paragraph attrs at pos ${pos}.`); + return result; + } + } const paragraphEndPos = pos + 1 + node.content.size; const contentDiffs = [...(diff.contentDiff ?? [])].sort((a, b) => { diff --git a/packages/super-editor/src/tests/data/diffing/diff_after10.docx b/packages/super-editor/src/tests/data/diffing/diff_after10.docx new file mode 100644 index 0000000000000000000000000000000000000000..e6c8b55ae36aa203e7930db84bd6adbcef3f09a5 GIT binary patch literal 13306 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� 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 literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diffing/diff_before9.docx b/packages/super-editor/src/tests/data/diffing/diff_before9.docx new file mode 100644 index 0000000000000000000000000000000000000000..ddc505a96ee06ead11aee53bea83196c98045023 GIT binary patch literal 13281 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 sv;e@rq~~AZfA1>)3O8Z+3;d6cQ$ZRE Date: Mon, 2 Mar 2026 11:25:21 -0300 Subject: [PATCH 068/125] fix: set selection during track changes --- .../trackChangesHelpers/replaceStep.js | 46 ++++++++++++++++++- .../trackChangesHelpers/trackedTransaction.js | 2 +- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceStep.js b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceStep.js index 2b9d4f62a7..2de39dce35 100644 --- a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceStep.js +++ b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceStep.js @@ -1,5 +1,6 @@ import { ReplaceStep } from 'prosemirror-transform'; import { Slice } from 'prosemirror-model'; +import { Selection, TextSelection } from 'prosemirror-state'; import { markInsertion } from './markInsertion.js'; import { markDeletion } from './markDeletion.js'; import { TrackDeleteMarkName } from '../constants.js'; @@ -295,7 +296,7 @@ export const replaceStep = ({ state, tr, step, newTr, map, user, date, originalS } if (!newTr.selection.eq(tempTr.selection)) { - newTr.setSelection(tempTr.selection); + syncSelectionFromTransaction({ targetTr: newTr, sourceSelection: tempTr.selection }); } if (step.from !== step.to) { @@ -335,3 +336,46 @@ export const replaceStep = ({ state, tr, step, newTr, map, user, date, originalS newTr.setMeta(TrackChangesBasePluginKey, meta); newTr.setMeta(CommentsPluginKey, { type: 'force' }); }; + +/** + * Copies a selection from one transaction into another transaction that has a different + * document instance, while guaranteeing the resulting selection is valid for the target doc. + * + * ProseMirror selections are bound to a specific document object. Reusing a `Selection` + * created from another transaction can throw: + * `Selection passed to setSelection must point at the current document`. + * + * This helper performs a safe transfer strategy: + * 1. Clamp source selection positions to the target document bounds. + * 2. Recreate `TextSelection` directly on the target doc when possible. + * 3. If recreation fails (for example, target endpoints are no longer valid text positions), + * fall back to `Selection.near(...)` so caret placement still succeeds. + * 4. For non-text selections, use the same `Selection.near(...)` fallback. + * + * The intent is to preserve cursor location as closely as possible without ever throwing + * during tracked replay. + * + * @param {{ targetTr: import('prosemirror-state').Transaction, sourceSelection: import('prosemirror-state').Selection }} options + * @param {import('prosemirror-state').Transaction} options.targetTr + * Transaction that should receive the selection. The resulting selection is always created + * against `targetTr.doc`. + * @param {import('prosemirror-state').Selection} options.sourceSelection + * Selection taken from another transaction/document context. + * @returns {void} + */ +const syncSelectionFromTransaction = ({ targetTr, sourceSelection }) => { + const boundedFrom = Math.max(0, Math.min(sourceSelection.from, targetTr.doc.content.size)); + const boundedTo = Math.max(0, Math.min(sourceSelection.to, targetTr.doc.content.size)); + + if (sourceSelection instanceof TextSelection) { + try { + targetTr.setSelection(TextSelection.create(targetTr.doc, boundedFrom, boundedTo)); + return; + } catch { + targetTr.setSelection(Selection.near(targetTr.doc.resolve(boundedFrom), -1)); + return; + } + } + + targetTr.setSelection(Selection.near(targetTr.doc.resolve(boundedFrom), -1)); +}; diff --git a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js index 7d17125f02..b25bb8d983 100644 --- a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js +++ b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/trackedTransaction.js @@ -20,7 +20,7 @@ export const trackedTransaction = ({ tr, state, user }) => { const notAllowedMeta = ['historyUndo', 'historyRedo', 'acceptReject']; const isProgrammaticInput = tr.getMeta('inputType') === 'programmatic'; const ySyncMeta = tr.getMeta(ySyncPluginKey); - const allowedMeta = new Set([...onlyInputTypeMeta, ySyncPluginKey.key, 'trackChanges']); + const allowedMeta = new Set([...onlyInputTypeMeta, ySyncPluginKey.key, 'forceTrackChanges']); const hasDisallowedMeta = tr.meta && Object.keys(tr.meta).some((meta) => !allowedMeta.has(meta)); if ( From eb9e639792b5d3383636d39b7db9b05e75b45c48 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 11:26:30 -0300 Subject: [PATCH 069/125] fix: adjust track changes during diff replay --- packages/super-editor/src/extensions/diffing/diffing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 44d5d0587d..ccdf42d843 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -49,7 +49,7 @@ export const Diffing = Extension.create({ schema: state.schema, }); if (applyTrackedChanges) { - state.tr.setMeta('trackChanges', true); + state.tr.setMeta('forceTrackChanges', true); } if (dispatch && state.tr.docChanged) { dispatch(state.tr); From e894ef8cebe55a8808a7a16319fcb6224146ae9c Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 11:39:12 -0300 Subject: [PATCH 070/125] fix: linting errors --- .../diffing/algorithm/comment-diffing.ts | 10 +++++----- .../diffing/algorithm/generic-diffing.ts | 8 ++++---- .../diffing/algorithm/inline-diffing.ts | 16 +++++++++++++--- .../diffing/algorithm/paragraph-diffing.ts | 16 ++++++++-------- .../diffing/algorithm/sequence-diffing.ts | 2 +- .../src/extensions/diffing/computeDiff.ts | 4 ++-- .../extensions/diffing/replay/replay-attrs.ts | 2 +- .../src/extensions/diffing/replay/replay-doc.ts | 10 +++++----- .../extensions/diffing/replay/replay-inline.ts | 10 +++++----- .../diffing/replay/replay-non-paragraph.ts | 4 ++-- .../diffing/replay/replay-paragraph.ts | 6 +++--- .../src/extensions/diffing/replayDiffs.ts | 4 ++-- 12 files changed, 51 insertions(+), 41 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts index 3357cc4843..eb91330c1e 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts @@ -1,8 +1,8 @@ import type { Schema } from 'prosemirror-model'; -import { diffNodes, type NodeDiff, type NodeInfo } from './generic-diffing.ts'; -import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; -import { createParagraphSnapshot, type ParagraphNodeInfo } from './paragraph-diffing.ts'; -import { diffSequences } from './sequence-diffing.ts'; +import { diffNodes, type NodeDiff, type NodeInfo } from './generic-diffing'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; +import { createParagraphSnapshot, type ParagraphNodeInfo } from './paragraph-diffing'; +import { diffSequences } from './sequence-diffing'; /** * Raw comment data used for diffing comment content and metadata. @@ -241,7 +241,7 @@ export function buildModifiedCommentDiff( * @param comment Comment payload to inspect. * @returns Resolved comment id or null when unavailable. */ -function resolveCommentId(comment: CommentInput): string | null { +export function resolveCommentId(comment: CommentInput): string | null { return comment.importedId ?? comment.id ?? comment.commentId ?? null; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 7af4418cb8..4c7c36b146 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -9,10 +9,10 @@ import { buildModifiedParagraphDiff, type ParagraphDiff, type ParagraphNodeInfo, -} from './paragraph-diffing.ts'; -import { diffSequences, reorderDiffOperations } from './sequence-diffing.ts'; -import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; -import { getInsertionPos } from './diff-utils.ts'; +} from './paragraph-diffing'; +import { diffSequences, reorderDiffOperations } from './sequence-diffing'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; +import { getInsertionPos } from './diff-utils'; type NodeJSON = ReturnType; diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index db29ab6f0c..6dc81cb897 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -1,6 +1,6 @@ import type { Node as PMNode } from 'prosemirror-model'; -import { getAttributesDiff, getMarksDiff, type AttributesDiff, type MarksDiff } from './attributes-diffing.ts'; -import { diffSequences } from './sequence-diffing.ts'; +import { getAttributesDiff, getMarksDiff, type AttributesDiff, type MarksDiff } from './attributes-diffing'; +import { diffSequences } from './sequence-diffing'; type NodeJSON = ReturnType; type MarkJSON = { type: string; attrs?: Record }; @@ -38,6 +38,16 @@ export type InlineNodeToken = { */ export type InlineDiffToken = InlineTextToken | InlineNodeToken; +/** + * Narrow an inline token to an inline-node token. + * + * @param token Inline token candidate. + * @returns True when the token represents an inline node. + */ +function isInlineNodeToken(token: InlineDiffToken): token is InlineNodeToken { + return token.kind === 'inlineNode'; +} + /** * Intermediate text diff emitted by `diffSequences`. */ @@ -222,7 +232,7 @@ export function getInlineDiff( comparator: inlineComparator, shouldProcessEqualAsModification, canTreatAsModification: (oldToken, newToken) => - oldToken.kind === newToken.kind && oldToken.kind !== 'text' && oldToken.node.type === newToken.node.type, + isInlineNodeToken(oldToken) && isInlineNodeToken(newToken) && oldToken.node.type === newToken.node.type, buildAdded: (token, oldIdx) => buildInlineDiff('added', token, oldIdx), buildDeleted: (token, oldIdx) => buildInlineDiff('deleted', token, oldIdx), buildModified: (oldToken, newToken, oldIdx) => { diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 20d30b876e..0632c2e022 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -1,8 +1,8 @@ import type { Node as PMNode } from 'prosemirror-model'; -import { getInlineDiff, tokenizeInlineContent, type InlineDiffToken, type InlineDiffResult } from './inline-diffing.ts'; -import { getAttributesDiff, type AttributesDiff } from './attributes-diffing.ts'; -import { getInsertionPos } from './diff-utils.ts'; -import { levenshteinDistance } from './similarity.ts'; +import { getInlineDiff, tokenizeInlineContent, type InlineDiffToken, type InlineDiffResult } from './inline-diffing'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; +import { getInsertionPos } from './diff-utils'; +import { levenshteinDistance } from './similarity'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. const SIMILARITY_THRESHOLD = 0.65; @@ -32,7 +32,7 @@ interface ParagraphDiffBase { /** Change type for this paragraph. */ action: Action; /** Node type name (always `paragraph`). */ - nodeType: string; + nodeType: 'paragraph'; /** Anchor position in the old document for replaying diffs. */ pos: number; } @@ -135,7 +135,7 @@ export function buildAddedParagraphDiff( ): AddedParagraphDiff { return { action: 'added', - nodeType: paragraph.node.type.name, + nodeType: 'paragraph', nodeJSON: paragraph.node.toJSON(), text: paragraph.fullText, pos: getInsertionPos(paragraph.depth, previousOldNodeInfo), @@ -148,7 +148,7 @@ export function buildAddedParagraphDiff( export function buildDeletedParagraphDiff(paragraph: ParagraphNodeInfo): DeletedParagraphDiff { return { action: 'deleted', - nodeType: paragraph.node.type.name, + nodeType: 'paragraph', nodeJSON: paragraph.node.toJSON(), oldText: paragraph.fullText, pos: paragraph.pos, @@ -171,7 +171,7 @@ export function buildModifiedParagraphDiff( return { action: 'modified', - nodeType: oldParagraph.node.type.name, + nodeType: 'paragraph', oldNodeJSON: oldParagraph.node.toJSON(), newNodeJSON: newParagraph.node.toJSON(), oldText: oldParagraph.fullText, diff --git a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts index 81e8b20996..9740b2ff7c 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/sequence-diffing.ts @@ -1,4 +1,4 @@ -import { myersDiff, type MyersOperation } from './myers-diff.ts'; +import { myersDiff, type MyersOperation } from './myers-diff'; /** * Comparator used to determine whether two sequence values are equal. diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts index 6b686905d7..2b1933e1cb 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.ts +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -1,6 +1,6 @@ import type { Node as PMNode, Schema } from 'prosemirror-model'; -import { diffComments, type CommentInput, type CommentDiff } from './algorithm/comment-diffing.ts'; -import { diffNodes, normalizeNodes, type NodeDiff } from './algorithm/generic-diffing.ts'; +import { diffComments, type CommentInput, type CommentDiff } from './algorithm/comment-diffing'; +import { diffNodes, normalizeNodes, type NodeDiff } from './algorithm/generic-diffing'; /** * Result payload for document diffing. diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts index ea80f99647..90d16d2509 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-attrs.ts @@ -1,4 +1,4 @@ -import { AttributesDiff } from '../algorithm/attributes-diffing.ts'; +import { AttributesDiff } from '../algorithm/attributes-diffing'; /** * Applies an attribute diff to an attributes object. diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts index 92adba8ea9..5cf7865ad2 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-doc.ts @@ -1,6 +1,6 @@ -import { ReplayResult } from './replay-types.ts'; -import { replayNonParagraphDiff } from './replay-non-paragraph.ts'; -import { replayParagraphDiff } from './replay-paragraph.ts'; +import { ReplayResult } from './replay-types'; +import { replayNonParagraphDiff } from './replay-non-paragraph'; +import { replayParagraphDiff } from './replay-paragraph'; /** * Orchestrates replay for document-level diffs. @@ -17,7 +17,7 @@ export function replayDocDiffs({ schema, }: { tr: import('prosemirror-state').Transaction; - docDiffs: import('../algorithm/generic-diffing.ts').NodeDiff[]; + docDiffs: import('../algorithm/generic-diffing').NodeDiff[]; schema: import('prosemirror-model').Schema; }): ReplayResult { const result: ReplayResult = { @@ -30,7 +30,7 @@ export function replayDocDiffs({ const diff = docDiffs[idx]; const handlerResult = diff.nodeType === 'paragraph' - ? replayParagraphDiff({ tr, diff, schema }) + ? replayParagraphDiff({ tr, diff: diff as import('../algorithm/paragraph-diffing').ParagraphDiff, schema }) : replayNonParagraphDiff({ tr, diff, schema }); result.applied += handlerResult.applied; result.skipped += handlerResult.skipped; diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index df6f973df4..1d7278666f 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -1,9 +1,9 @@ import { Fragment, Slice } from 'prosemirror-model'; import { ReplaceStep, AddMarkStep, RemoveMarkStep } from 'prosemirror-transform'; -import { applyAttrsDiff } from './replay-attrs.ts'; -import { marksFromDiff } from './marks-from-diff.ts'; -import { ReplayResult } from './replay-types.ts'; +import { applyAttrsDiff } from './replay-attrs'; +import { marksFromDiff } from './marks-from-diff'; +import { ReplayResult } from './replay-types'; /** * Replays a single inline diff into a transaction. @@ -22,7 +22,7 @@ export function replayInlineDiff({ paragraphEndPos, }: { tr: import('prosemirror-state').Transaction; - diff: import('../algorithm/inline-diffing.ts').InlineDiffResult; + diff: import('../algorithm/inline-diffing').InlineDiffResult; schema: import('prosemirror-model').Schema; paragraphEndPos: number; }): ReplayResult { @@ -255,7 +255,7 @@ const getMarksAtPosition = ( const applyRunAttrsDiff = ( tr: import('prosemirror-state').Transaction, pos: number, - diff: import('../algorithm/attributes-diffing.ts').AttributesDiff, + diff: import('../algorithm/attributes-diffing').AttributesDiff, ): { applied: number; warning?: string } => { const resolved = tr.doc.resolve(pos); for (let depth = resolved.depth; depth > 0; depth -= 1) { diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts index f7798670a3..48d1da168c 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-non-paragraph.ts @@ -4,7 +4,7 @@ import { Fragment, Slice } from 'prosemirror-model'; import { ReplaceStep } from 'prosemirror-transform'; -import { ReplayResult } from './replay-types.ts'; +import { ReplayResult } from './replay-types'; /** * Replays a non-paragraph node diff into a transaction. @@ -21,7 +21,7 @@ export function replayNonParagraphDiff({ schema, }: { tr: import('prosemirror-state').Transaction; - diff: import('../algorithm/generic-diffing.ts').NodeDiff; + diff: import('../algorithm/generic-diffing').NodeDiff; schema: import('prosemirror-model').Schema; }): ReplayResult { const result: ReplayResult = { diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts index e4b0b2e211..8a34d56d79 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.ts @@ -1,8 +1,8 @@ import { Fragment, Slice } from 'prosemirror-model'; import { ReplaceStep } from 'prosemirror-transform'; -import { replayInlineDiff } from './replay-inline.ts'; -import { ReplayResult } from './replay-types.ts'; +import { replayInlineDiff } from './replay-inline'; +import { ReplayResult } from './replay-types'; /** * Replays a paragraph diff into a transaction. @@ -19,7 +19,7 @@ export function replayParagraphDiff({ schema, }: { tr: import('prosemirror-state').Transaction; - diff: import('../algorithm/paragraph-diffing.ts').ParagraphDiff; + diff: import('../algorithm/paragraph-diffing').ParagraphDiff; schema: import('prosemirror-model').Schema; }): ReplayResult { const result: ReplayResult = { diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index cf89806be2..abc657fa73 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -13,7 +13,7 @@ export type ReplayDiffsResult = { warnings: string[]; }; -import { replayDocDiffs } from './replay/replay-doc.ts'; +import { replayDocDiffs } from './replay/replay-doc'; /** * Replays a diff result over the current editor state. @@ -30,7 +30,7 @@ export function replayDiffs({ schema, }: { tr: import('prosemirror-state').Transaction; - diff: import('./computeDiff.ts').DiffResult; + diff: import('./computeDiff').DiffResult; schema: import('prosemirror-model').Schema; }): ReplayDiffsResult { const docReplay = replayDocDiffs({ tr, docDiffs: diff.docDiffs, schema }); From 4ff51c5cd9f7f965c6b27e262809df64738db5f8 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 11:45:10 -0300 Subject: [PATCH 071/125] feat: add logic for replaying comment differences --- .../src/extensions/diffing/diffing.js | 10 + .../src/extensions/diffing/replay/index.ts | 1 + .../diffing/replay/replay-comments.test.js | 259 ++++++++++++++++++ .../diffing/replay/replay-comments.ts | 236 ++++++++++++++++ .../src/extensions/diffing/replayDiffs.ts | 14 +- packages/superdoc/src/SuperDoc.test.js | 47 +++- packages/superdoc/src/SuperDoc.vue | 65 ++++- .../superdoc/src/stores/comments-store.js | 17 ++ 8 files changed, 640 insertions(+), 9 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-comments.ts diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index ccdf42d843..80258a8d84 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -43,17 +43,27 @@ export const Diffing = Extension.create({ replayDifferences: (diff, { applyTrackedChanges = true }) => ({ state, dispatch }) => { + const comments = this.editor.converter + ? Array.isArray(this.editor.converter.comments) + ? this.editor.converter.comments + : (this.editor.converter.comments = []) + : []; replayDiffs({ tr: state.tr, diff, schema: state.schema, + comments, + editor: this.editor, }); + if (applyTrackedChanges) { state.tr.setMeta('forceTrackChanges', true); } if (dispatch && state.tr.docChanged) { dispatch(state.tr); } + + this.editor.emit('commentsUpdate', { type: 'replayCompleted' }); return true; }, }; diff --git a/packages/super-editor/src/extensions/diffing/replay/index.ts b/packages/super-editor/src/extensions/diffing/replay/index.ts index 52ef7c8c51..a83b35387e 100644 --- a/packages/super-editor/src/extensions/diffing/replay/index.ts +++ b/packages/super-editor/src/extensions/diffing/replay/index.ts @@ -4,4 +4,5 @@ export * from './replay-paragraph'; export * from './replay-inline'; export * from './replay-attrs'; export * from './marks-from-diff'; +export * from './replay-comments'; export * from './replay-types'; diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js new file mode 100644 index 0000000000..045345a9bf --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js @@ -0,0 +1,259 @@ +import { describe, it, expect, vi } from 'vitest'; + +import { replayComments } from './replay-comments.ts'; + +/** + * Verifies added comment diffs insert the comment payload. + * @returns {void} + */ +const testAddsComment = () => { + const comments = []; + const diff = { + action: 'added', + nodeType: 'comment', + commentId: 'c-1', + commentJSON: { commentId: 'c-1', commentText: 'New comment' }, + text: 'New comment', + }; + + const result = replayComments({ comments, commentDiffs: [diff] }); + + expect(result).toEqual({ applied: 1, skipped: 0, warnings: [] }); + expect(comments).toEqual([{ commentId: 'c-1', commentText: 'New comment' }]); +}; + +/** + * Verifies modified comment diffs replace the existing payload. + * @returns {void} + */ +const testModifiesComment = () => { + const comments = [{ commentId: 'c-1', commentText: 'Old comment', isDone: false }]; + const diff = { + action: 'modified', + nodeType: 'comment', + commentId: 'c-1', + oldCommentJSON: { commentId: 'c-1', commentText: 'Old comment', isDone: false }, + newCommentJSON: { commentId: 'c-1', commentText: 'Updated comment', isDone: true }, + oldText: 'Old comment', + newText: 'Updated comment', + contentDiff: [], + attrsDiff: { + added: {}, + deleted: {}, + modified: { isDone: { from: false, to: true } }, + }, + }; + + const result = replayComments({ comments, commentDiffs: [diff] }); + + expect(result).toEqual({ applied: 1, skipped: 0, warnings: [] }); + expect(comments).toEqual([{ commentId: 'c-1', commentText: 'Updated comment', isDone: true }]); +}; + +/** + * Verifies deleted comment diffs remove by resolved comment id. + * @returns {void} + */ +const testDeletesCommentByResolvedId = () => { + const comments = [ + { importedId: 'import-1', commentText: 'Imported' }, + { commentId: 'c-2', commentText: 'Keep me' }, + ]; + const diff = { + action: 'deleted', + nodeType: 'comment', + commentId: 'import-1', + commentJSON: { importedId: 'import-1', commentText: 'Imported' }, + oldText: 'Imported', + }; + + const result = replayComments({ comments, commentDiffs: [diff] }); + + expect(result).toEqual({ applied: 1, skipped: 0, warnings: [] }); + expect(comments).toEqual([{ commentId: 'c-2', commentText: 'Keep me' }]); +}; + +/** + * Verifies missing modified comment diffs are skipped with warnings. + * @returns {void} + */ +const testSkipsMissingModifiedComment = () => { + const comments = []; + const diff = { + action: 'modified', + nodeType: 'comment', + commentId: 'missing', + oldCommentJSON: { commentId: 'missing', commentText: 'Old' }, + newCommentJSON: { commentId: 'missing', commentText: 'New' }, + oldText: 'Old', + newText: 'New', + contentDiff: [], + attrsDiff: null, + }; + + const result = replayComments({ comments, commentDiffs: [diff] }); + + expect(result.applied).toBe(0); + expect(result.skipped).toBe(1); + expect(result.warnings[0]).toContain('not found'); + expect(comments).toEqual([]); +}; + +/** + * Verifies replayComments aggregates multi-diff results. + * @returns {void} + */ +const testAggregatesMultipleDiffs = () => { + const comments = [{ commentId: 'c-1', commentText: 'Old 1' }]; + const diffs = [ + { + action: 'modified', + nodeType: 'comment', + commentId: 'c-1', + oldCommentJSON: { commentId: 'c-1', commentText: 'Old 1' }, + newCommentJSON: { commentId: 'c-1', commentText: 'New 1' }, + oldText: 'Old 1', + newText: 'New 1', + contentDiff: [], + attrsDiff: null, + }, + { + action: 'added', + nodeType: 'comment', + commentId: 'c-2', + commentJSON: { commentId: 'c-2', commentText: 'New 2' }, + text: 'New 2', + }, + ]; + + const result = replayComments({ comments, commentDiffs: diffs }); + + expect(result).toEqual({ applied: 2, skipped: 0, warnings: [] }); + expect(comments).toEqual([ + { commentId: 'c-1', commentText: 'New 1' }, + { commentId: 'c-2', commentText: 'New 2' }, + ]); +}; + +/** + * Verifies replayComments emits UI update events through the editor. + * @returns {void} + */ +const testEmitsCommentsUpdateEvents = () => { + const comments = []; + const editor = { emit: vi.fn() }; + const diffs = [ + { + action: 'added', + nodeType: 'comment', + commentId: 'external-1', + commentJSON: { id: 'external-1' }, + text: 'Added text', + }, + { + action: 'modified', + nodeType: 'comment', + commentId: 'external-1', + oldCommentJSON: { id: 'external-1', commentText: 'Old' }, + newCommentJSON: { id: 'external-1' }, + oldText: 'Old', + newText: 'New text', + contentDiff: [], + attrsDiff: null, + }, + { + action: 'deleted', + nodeType: 'comment', + commentId: 'external-1', + commentJSON: { id: 'external-1' }, + oldText: 'Old', + }, + ]; + + replayComments({ comments, commentDiffs: diffs, editor }); + + expect(editor.emit).toHaveBeenCalledTimes(3); + expect(editor.emit).toHaveBeenNthCalledWith( + 1, + 'commentsUpdate', + expect.objectContaining({ + type: 'add', + comment: expect.objectContaining({ commentId: 'external-1', commentText: 'Added text' }), + }), + ); + expect(editor.emit).toHaveBeenNthCalledWith( + 2, + 'commentsUpdate', + expect.objectContaining({ + type: 'update', + comment: expect.objectContaining({ commentId: 'external-1', commentText: 'New text' }), + }), + ); + expect(editor.emit).toHaveBeenNthCalledWith( + 3, + 'commentsUpdate', + expect.objectContaining({ + type: 'deleted', + comment: expect.objectContaining({ commentId: 'external-1' }), + }), + ); +}; + +/** + * Verifies added comments derive commentText from structured `elements` when diff text is empty. + * @returns {void} + */ +const testDerivesCommentTextFromElements = () => { + const comments = []; + const editor = { emit: vi.fn() }; + const diffs = [ + { + action: 'added', + nodeType: 'comment', + commentId: 'external-2', + commentJSON: { + id: 'external-2', + elements: [ + { + type: 'paragraph', + content: [ + { + type: 'run', + content: [{ type: 'text', text: 'New comment' }], + }, + ], + }, + ], + }, + text: '', + }, + ]; + + replayComments({ comments, commentDiffs: diffs, editor }); + + expect(editor.emit).toHaveBeenCalledTimes(1); + expect(editor.emit).toHaveBeenNthCalledWith( + 1, + 'commentsUpdate', + expect.objectContaining({ + type: 'add', + comment: expect.objectContaining({ commentId: 'external-2', commentText: 'New comment' }), + }), + ); +}; + +/** + * Runs the replayComments suite. + * @returns {void} + */ +const runReplayCommentsSuite = () => { + it('adds comments from added diffs', testAddsComment); + it('replaces comments from modified diffs', testModifiesComment); + it('deletes comments by resolved id', testDeletesCommentByResolvedId); + it('skips missing modified comments with warnings', testSkipsMissingModifiedComment); + it('aggregates results across multiple diffs', testAggregatesMultipleDiffs); + it('emits commentsUpdate events for replayed diffs', testEmitsCommentsUpdateEvents); + it('derives comment text from elements for replayed additions', testDerivesCommentTextFromElements); +}; + +describe('replayComments', runReplayCommentsSuite); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-comments.ts b/packages/super-editor/src/extensions/diffing/replay/replay-comments.ts new file mode 100644 index 0000000000..877528d900 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-comments.ts @@ -0,0 +1,236 @@ +import { ReplayResult } from './replay-types'; +import { comments_module_events } from '@superdoc/common'; +import { resolveCommentId } from '../algorithm/comment-diffing'; + +/** + * Finds a comment index in a mutable comment store by its resolved id. + * + * @param comments Mutable comment store. + * @param commentId Target resolved id. + * @returns Matching index or -1 when not found. + */ +function findCommentIndexById( + comments: import('../algorithm/comment-diffing').CommentInput[], + commentId: string, +): number { + return comments.findIndex((comment) => resolveCommentId(comment) === commentId); +} + +/** + * Replays one comment diff into a mutable comment store. + * + * Behavior: + * - `added`: inserts the new comment payload. + * - `modified`: replaces the existing comment payload with the updated version. + * - `deleted`: removes the existing comment payload. + * + * @param params Input bundle for replaying one comment diff. + * @param params.comments Mutable comment store to update in place. + * @param params.diff Comment diff payload. + * @returns Result summary for the applied comment diff. + */ +function replayCommentDiff({ + comments, + diff, + editor, +}: { + comments: import('../algorithm/comment-diffing').CommentInput[]; + diff: import('../algorithm/comment-diffing').CommentDiff; + editor?: { emit?: (event: string, payload: unknown) => void }; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + /** + * Records a skipped diff with a warning message. + * + * @param message Warning to record for a skipped diff. + */ + const skipWithWarning = (message: string) => { + result.skipped += 1; + result.warnings.push(message); + }; + + if (diff.nodeType !== 'comment') { + skipWithWarning(`Non-comment diff received: ${diff.nodeType}.`); + return result; + } + + if (diff.action === 'added') { + const existingIndex = findCommentIndexById(comments, diff.commentId); + if (existingIndex !== -1) { + skipWithWarning(`Comment ${diff.commentId} already exists; skipping add.`); + return result; + } + + comments.push(diff.commentJSON); + result.applied += 1; + const payload = { + ...diff.commentJSON, + }; + if (!payload.commentId) { + payload.commentId = diff.commentId; + } + const resolvedText = resolveCommentTextPayload({ comment: diff.commentJSON, fallbackText: diff.text }); + if (!payload.commentText && resolvedText) { + payload.commentText = resolvedText; + } + editor?.emit?.('commentsUpdate', { + type: comments_module_events.ADD, + comment: payload, + }); + return result; + } + + if (diff.action === 'deleted') { + const existingIndex = findCommentIndexById(comments, diff.commentId); + if (existingIndex === -1) { + skipWithWarning(`Comment ${diff.commentId} not found; skipping delete.`); + return result; + } + + comments.splice(existingIndex, 1); + result.applied += 1; + const payload = { + ...diff.commentJSON, + }; + if (!payload.commentId) { + payload.commentId = diff.commentId; + } + editor?.emit?.('commentsUpdate', { + type: comments_module_events.DELETED, + comment: payload, + }); + return result; + } + + if (diff.action === 'modified') { + const existingIndex = findCommentIndexById(comments, diff.commentId); + if (existingIndex === -1) { + skipWithWarning(`Comment ${diff.commentId} not found; skipping modify.`); + return result; + } + + comments.splice(existingIndex, 1, diff.newCommentJSON); + result.applied += 1; + const payload = { + ...diff.newCommentJSON, + }; + if (!payload.commentId) { + payload.commentId = diff.commentId; + } + const resolvedText = resolveCommentTextPayload({ comment: diff.newCommentJSON, fallbackText: diff.newText }); + if (!payload.commentText && resolvedText) { + payload.commentText = resolvedText; + } + editor?.emit?.('commentsUpdate', { + type: comments_module_events.UPDATE, + comment: payload, + }); + return result; + } + + skipWithWarning('Unsupported comment diff action.'); + return result; +} + +/** + * Resolves display text for a comment payload. + * + * Priority order: + * 1. `comment.commentText` when present. + * 2. `fallbackText` from the diff payload. + * 3. Flattened text extracted from `comment.elements`. + * 4. Flattened text extracted from `comment.textJson`. + * + * This keeps replayed comment events compatible with UI paths that expect + * `commentText` even when imported DOCX comments only provide structured + * comment bodies (`elements`) instead of plain text. + */ +function resolveCommentTextPayload({ + comment, + fallbackText, +}: { + comment: import('../algorithm/comment-diffing').CommentInput; + fallbackText?: string; +}): string | undefined { + if (typeof comment.commentText === 'string' && comment.commentText.length > 0) { + return comment.commentText; + } + if (typeof fallbackText === 'string' && fallbackText.length > 0) { + return fallbackText; + } + + const fromElements = extractStructuredCommentText(comment.elements); + if (fromElements) return fromElements; + + const fromTextJson = extractStructuredCommentText(comment.textJson); + if (fromTextJson) return fromTextJson; + + return undefined; +} + +/** + * Extracts concatenated text from nested comment body structures. + * + * Supports the structures used by imported DOCX comments (`elements`) and + * paragraph JSON trees (`textJson`) by walking `text`, `content`, and `elements`. + */ +function extractStructuredCommentText(value: unknown): string { + if (!value) return ''; + + if (typeof value === 'string') { + return value; + } + + if (Array.isArray(value)) { + return value.map((item) => extractStructuredCommentText(item)).join(''); + } + + if (typeof value !== 'object') { + return ''; + } + + const node = value as Record; + const textPart = typeof node.text === 'string' ? node.text : ''; + const contentPart = extractStructuredCommentText(node.content); + const elementsPart = extractStructuredCommentText(node.elements); + + return `${textPart}${contentPart}${elementsPart}`; +} + +/** + * Replays a list of comment diffs into a mutable comment store. + * + * @param params Input bundle for replaying comment diffs. + * @param params.comments Mutable comment store to update in place. + * @param params.commentDiffs Comment diffs to replay in provided order. + * @returns Aggregated result summary for all replayed comment diffs. + */ +export function replayComments({ + comments, + commentDiffs, + editor, +}: { + comments: import('../algorithm/comment-diffing').CommentInput[]; + commentDiffs: import('../algorithm/comment-diffing').CommentDiff[]; + editor?: { emit?: (event: string, payload: unknown) => void }; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + for (const diff of commentDiffs) { + const diffResult = replayCommentDiff({ comments, diff, editor }); + result.applied += diffResult.applied; + result.skipped += diffResult.skipped; + result.warnings.push(...diffResult.warnings); + } + + return result; +} diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index abc657fa73..fa14af4aad 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -14,6 +14,7 @@ export type ReplayDiffsResult = { }; import { replayDocDiffs } from './replay/replay-doc'; +import { replayComments } from './replay/replay-comments'; /** * Replays a diff result over the current editor state. @@ -22,23 +23,30 @@ import { replayDocDiffs } from './replay/replay-doc'; * @param params.tr Transaction to append steps to. * @param params.diff Diff result to replay. * @param params.schema Schema used to rebuild nodes. + * @param params.comments Mutable comment store to replay comment diffs into. + * @param params.editor Editor instance used to emit comment update events. * @returns Summary and transaction containing the replayed steps. */ export function replayDiffs({ tr, diff, schema, + comments = [], + editor, }: { tr: import('prosemirror-state').Transaction; diff: import('./computeDiff').DiffResult; schema: import('prosemirror-model').Schema; + comments?: import('./algorithm/comment-diffing').CommentInput[]; + editor?: { emit?: (event: string, payload: unknown) => void }; }): ReplayDiffsResult { const docReplay = replayDocDiffs({ tr, docDiffs: diff.docDiffs, schema }); + const commentsReplay = replayComments({ comments, commentDiffs: diff.commentDiffs, editor }); return { tr, - appliedDiffs: docReplay.applied, - skippedDiffs: docReplay.skipped, - warnings: docReplay.warnings, + appliedDiffs: docReplay.applied + commentsReplay.applied, + skippedDiffs: docReplay.skipped + commentsReplay.skipped, + warnings: [...docReplay.warnings, ...commentsReplay.warnings], }; } diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index bcb74c01e1..6095eb499d 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -177,15 +177,23 @@ const buildCommentsStore = () => ({ handleEditorLocationsUpdate: vi.fn(), clearEditorCommentPositions: vi.fn(), handleTrackedChangeUpdate: vi.fn(), + syncTrackedChangeComments: vi.fn(), removePendingComment: vi.fn(), setActiveComment: vi.fn(), + addComment: vi.fn(), + getComment: vi.fn(() => null), + COMMENT_EVENTS: { + ADD: 'add', + UPDATE: 'update', + DELETED: 'deleted', + }, processLoadedDocxComments: vi.fn(), translateCommentsForExport: vi.fn(() => []), getPendingComment: vi.fn(() => ({ commentId: 'pending', selection: { getValues: () => ({}) } })), commentsParentElement: null, editorCommentIds: [], proxy: null, - commentsList: [], + commentsList: ref([]), lastUpdate: null, gesturePositions: ref([]), suppressInternalExternal: ref(false), @@ -444,6 +452,43 @@ describe('SuperDoc.vue', () => { expect(superdocStub.emit).toHaveBeenCalledWith('exception', { error: expect.any(Error), editor: editorMock }); }); + it('handles replay comment update/delete events and triggers tracked-change resync', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + const existingComment = { commentId: 'c-1', commentText: 'Old text' }; + + commentsStoreStub.getComment.mockImplementation((id) => (id === 'c-1' ? existingComment : null)); + commentsStoreStub.commentsList.value = [ + existingComment, + { commentId: 'c-2', parentCommentId: 'c-1', commentText: 'Reply' }, + { commentId: 'tc-child', trackedChangeParentId: 'c-1', commentText: 'Tracked thread comment' }, + ]; + superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; + + options.onCommentsUpdate({ + type: 'update', + comment: { commentId: 'c-1', commentText: 'Updated text' }, + }); + expect(existingComment.commentText).toBe('Updated text'); + + options.onCommentsUpdate({ + type: 'deleted', + comment: { commentId: 'c-1' }, + }); + expect(commentsStoreStub.commentsList.value).toEqual([ + { commentId: 'tc-child', trackedChangeParentId: 'c-1', commentText: 'Tracked thread comment' }, + ]); + + options.onCommentsUpdate({ type: 'replayCompleted' }); + expect(commentsStoreStub.syncTrackedChangeComments).toHaveBeenCalledWith({ + superdoc: superdocStub, + editor: superdocStub.activeEditor, + }); + }); + it('passes slash menu and context menu options through to SuperEditor', async () => { const superdocStub = createSuperdocStub(); const slashMenuConfig = { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index d7d74d4f21..fc8a9004b2 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -90,6 +90,7 @@ const { handleEditorLocationsUpdate, handleTrackedChangeUpdate, syncTrackedChangePositionsWithDocument, + syncTrackedChangeComments, addComment, getComment, COMMENT_EVENTS, @@ -632,6 +633,11 @@ const onEditorCommentLocationsUpdate = (doc, { allCommentIds: activeThreadId, al const onEditorCommentsUpdate = (params = {}) => { // Set the active comment in the store let { activeCommentId, type, comment: commentPayload } = params; + const resolveCommentEventId = (payload) => payload?.commentId || payload?.importedId || null; + + if (type === 'replayCompleted') { + syncTrackedChangeComments({ superdoc: proxy.$superdoc, editor: proxy.$superdoc?.activeEditor }); + } if (COMMENT_EVENTS?.ADD && type === COMMENT_EVENTS.ADD && commentPayload) { if (!commentPayload.commentText && commentPayload.text) { @@ -666,20 +672,69 @@ const onEditorCommentsUpdate = (params = {}) => { } } + if (COMMENT_EVENTS?.UPDATE && type === COMMENT_EVENTS.UPDATE && commentPayload) { + const id = resolveCommentEventId(commentPayload); + if (id) { + const existingComment = getComment(id); + const resolvedText = commentPayload.commentText || commentPayload.text; + + if (existingComment) { + Object.assign(existingComment, commentPayload); + if (!existingComment.commentText && resolvedText) { + existingComment.commentText = resolvedText; + } + } else { + const normalizedPayload = { ...commentPayload }; + if (!normalizedPayload.commentText && resolvedText) { + normalizedPayload.commentText = resolvedText; + } + const commentModel = useComment(normalizedPayload); + addComment({ superdoc: proxy.$superdoc, comment: commentModel, skipEditorUpdate: true }); + } + + if (!activeCommentId) { + activeCommentId = id; + } + } + } + + if (COMMENT_EVENTS?.DELETED && type === COMMENT_EVENTS.DELETED && commentPayload) { + const id = resolveCommentEventId(commentPayload); + if (id) { + const targetId = String(id); + commentsList.value = commentsList.value.filter((comment) => { + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; + const isDeletedComment = commentId === targetId || importedId === targetId; + const isReplyToDeletedComment = parentCommentId === targetId; + return !isDeletedComment && !isReplyToDeletedComment; + }); + + if (activeComment.value != null && String(activeComment.value) === targetId) { + activeCommentId = null; + } + } + } + if (type === 'trackedChange') { handleTrackedChangeUpdate({ superdoc: proxy.$superdoc, params }); } nextTick(() => { if (pendingComment.value) return; - commentsStore.setActiveComment(proxy.$superdoc, activeCommentId); + if (activeCommentId !== undefined) { + commentsStore.setActiveComment(proxy.$superdoc, activeCommentId); + } // Briefly suppress click-outside so the same click that selected the comment // highlight in the editor doesn't immediately deactivate it via the sidebar. // Reset after the event loop settles so subsequent outside clicks work normally. - isCommentHighlighted.value = true; - setTimeout(() => { - isCommentHighlighted.value = false; - }, 0); + if (activeCommentId !== undefined) { + isCommentHighlighted.value = true; + setTimeout(() => { + isCommentHighlighted.value = false; + }, 0); + } }); // Bubble up the event to the user, if handled diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index 4830d7c060..821ef8c717 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -948,6 +948,22 @@ export const useCommentsStore = defineStore('comments', () => { editor.view.dispatch(tr); }; + /** + * Rebuild tracked-change comments from the current editor state. + * + * Useful after bulk document transforms (like diff replay) where tracked-change + * marks may be remapped and incremental tracked-change events are not emitted. + * + * @param {Object} param0 + * @param {Object} param0.superdoc The SuperDoc instance. + * @param {Object} param0.editor The active Super Editor instance. + * @returns {void} + */ + const syncTrackedChangeComments = ({ superdoc, editor }) => { + if (!superdoc || !editor) return; + createCommentForTrackChanges(editor, superdoc); + }; + const normalizeDocxSchemaForExport = (value) => { if (!value) return []; const nodes = Array.isArray(value) ? value : [value]; @@ -1193,5 +1209,6 @@ export const useCommentsStore = defineStore('comments', () => { clearEditorCommentPositions, handleTrackedChangeUpdate, syncTrackedChangePositionsWithDocument, + syncTrackedChangeComments, }; }); From 4e433d46734c94c7712dddb81067bbef08c0b981 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 15:54:15 -0300 Subject: [PATCH 072/125] fix: adjust computation of comment position key --- .../superdoc/src/stores/comments-store.js | 31 ++++++++++++++++--- .../src/stores/comments-store.test.js | 31 ++++++++++++++++++- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index 821ef8c717..f8f87d4259 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -111,17 +111,38 @@ export const useCommentsStore = defineStore('comments', () => { /** * Extract the position lookup key from a comment or comment ID. - * Prefers importedId for imported comments since editor marks retain the original ID. + * Prefers whichever key currently exists in editorCommentPositions. * * @param {Object | string | null | undefined} commentOrId The comment object or comment ID - * @returns {string | null} The position key (importedId or commentId) + * @returns {string | null} The position key */ const getCommentPositionKey = (commentOrId) => { if (!commentOrId) return null; - if (typeof commentOrId === 'object') { - return commentOrId.importedId ?? commentOrId.commentId ?? null; + + const positions = editorCommentPositions.value || {}; + + if (typeof commentOrId === 'string') { + if (positions[commentOrId]) { + return commentOrId; + } + + const resolvedComment = getComment(commentOrId); + if (!resolvedComment) { + return commentOrId; + } + + const commentId = resolvedComment.commentId ?? null; + const importedId = resolvedComment.importedId ?? null; + if (commentId && positions[commentId]) return commentId; + if (importedId && positions[importedId]) return importedId; + return commentId ?? importedId ?? null; } - return commentOrId; + + const commentId = commentOrId.commentId ?? null; + const importedId = commentOrId.importedId ?? null; + if (commentId && positions[commentId]) return commentId; + if (importedId && positions[importedId]) return importedId; + return commentId ?? importedId ?? null; }; const normalizeCommentId = (id) => (id === undefined || id === null ? null : String(id)); diff --git a/packages/superdoc/src/stores/comments-store.test.js b/packages/superdoc/src/stores/comments-store.test.js index 9cab56c57f..2e42a1b4a9 100644 --- a/packages/superdoc/src/stores/comments-store.test.js +++ b/packages/superdoc/src/stores/comments-store.test.js @@ -862,7 +862,7 @@ describe('comments-store', () => { expect(ordered).toEqual(['c-2', 'c-3', 'c-1']); }); - it('uses importedId over commentId when looking up positions', () => { + it('uses importedId when that is the available position key', () => { store.commentsList = [ { commentId: 'uuid-1', importedId: 'imported-1', createdTime: 3 }, { commentId: 'uuid-2', importedId: 'imported-2', createdTime: 1 }, @@ -1008,6 +1008,17 @@ describe('comments-store', () => { expect(store.getCommentPosition(comment)).toEqual({ start: 20, end: 30 }); }); + it('resolves imported-id lookups to commentId positions when only commentId is present', () => { + const comment = { commentId: 'uuid-1', importedId: 'imported-1', fileId: 'doc-1' }; + store.commentsList = [comment]; + store.editorCommentPositions = { + 'uuid-1': { start: 22, end: 31 }, + }; + + expect(store.getCommentPosition('imported-1')).toEqual({ start: 22, end: 31 }); + expect(store.getCommentPosition(comment)).toEqual({ start: 22, end: 31 }); + }); + it('returns anchored text when editor and positions are available', () => { const textBetween = vi.fn(() => 'Anchored text'); const editorStub = { state: { doc: { textBetween } } }; @@ -1176,6 +1187,24 @@ describe('comments-store', () => { }); describe('getFloatingComments filters resolved tracked changes', () => { + it('includes editor comments when commentId has positions but importedId does not', () => { + store.commentsList = [ + { + commentId: 'uuid-1', + importedId: 'imported-1', + resolvedTime: null, + createdTime: 1, + selection: { source: 'super-editor' }, + }, + ]; + store.editorCommentPositions = { + 'uuid-1': { start: 1, end: 5, bounds: { top: 0, left: 0 } }, + }; + + const floating = store.getFloatingComments; + expect(floating.map((c) => c.commentId)).toEqual(['uuid-1']); + }); + it('includes unresolved tracked changes that have position keys', () => { store.commentsList = [ { commentId: 'tc-1', trackedChange: true, resolvedTime: null, createdTime: 1 }, From 74e272797bf6a457412ff3bae818c1c015a537c4 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 16:05:51 -0300 Subject: [PATCH 073/125] fix: adjust comment diffing logic --- .../diffing/algorithm/comment-diffing.test.ts | 85 +++++++++++++++++++ .../diffing/algorithm/comment-diffing.ts | 55 ++++++++++-- 2 files changed, 134 insertions(+), 6 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts index 6dc000f312..f85d524292 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts @@ -37,6 +37,19 @@ const buildCommentTextJson = (text) => ({ content: [{ type: 'text', text }], }); +/** + * Builds a DOCX-imported comment `elements` payload. + * + * @param {string} text Comment text content. + * @returns {Array>} + */ +const buildCommentElements = (text) => [ + { + type: 'paragraph', + content: [{ type: 'text', text }], + }, +]; + /** * Returns the first token for convenience in tests. * @@ -86,6 +99,19 @@ describe('buildCommentTokens', () => { expect(tokens[0]?.content).toBeNull(); }); + it('builds tokens and text from elements when textJson is missing', () => { + const schema = createSchema(); + const comment = { + commentId: 'c-elements', + elements: buildCommentElements('From elements'), + }; + + const tokens = buildCommentTokens([comment], schema); + expect(tokens).toHaveLength(1); + expect(tokens[0]?.commentId).toBe('c-elements'); + expect(tokens[0]?.content?.fullText).toBe('From elements'); + }); + it('returns a base node info when the root node is not a paragraph', () => { const schema = createSchema(); const comment = { @@ -162,6 +188,36 @@ describe('comment diff helpers', () => { expect(shouldProcessEqualAsModification(oldToken, newToken)).toBe(false); }); + it('ignores trackedChangeParentId-only differences', () => { + const schema = createSchema(); + const oldToken = getFirstToken( + buildCommentTokens( + [ + { + commentId: 'c-1', + textJson: buildCommentTextJson('Same'), + trackedChangeParentId: 'tc-old', + }, + ], + schema, + ), + ); + const newToken = getFirstToken( + buildCommentTokens( + [ + { + commentId: 'c-1', + textJson: buildCommentTextJson('Same'), + trackedChangeParentId: 'tc-new', + }, + ], + schema, + ), + ); + + expect(shouldProcessEqualAsModification(oldToken, newToken)).toBe(false); + }); + it('does not treat insert/delete pairs as modifications', () => { expect(canTreatAsModification()).toBe(false); }); @@ -260,6 +316,24 @@ describe('diffComments', () => { expect(diffs[0].contentDiff).not.toEqual([]); }); + it('returns modified comment diffs for elements-based content changes', () => { + const schema = createSchema(); + const diffs = diffComments( + [{ commentId: 'c-1', elements: buildCommentElements('Old') }], + [{ commentId: 'c-1', elements: buildCommentElements('New') }], + schema, + ); + + expect(diffs).toHaveLength(1); + expect(diffs[0]).toMatchObject({ + action: 'modified', + nodeType: 'comment', + commentId: 'c-1', + oldText: 'Old', + newText: 'New', + }); + }); + it('returns empty diffs for identical comments', () => { const schema = createSchema(); const diffs = diffComments( @@ -270,4 +344,15 @@ describe('diffComments', () => { expect(diffs).toEqual([]); }); + + it('returns empty diffs when only trackedChangeParentId differs', () => { + const schema = createSchema(); + const diffs = diffComments( + [{ commentId: 'c-1', textJson: buildCommentTextJson('Same'), trackedChangeParentId: 'tc-old' }], + [{ commentId: 'c-1', textJson: buildCommentTextJson('Same'), trackedChangeParentId: 'tc-new' }], + schema, + ); + + expect(diffs).toEqual([]); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts index eb91330c1e..5ed64a24e3 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts @@ -16,6 +16,8 @@ export interface CommentInput { id?: string; /** ProseMirror-compatible JSON for the comment body (expected to be a paragraph node). */ textJson?: unknown; + /** Structured ProseMirror-like nodes used by imported DOCX comments. */ + elements?: unknown; /** Additional comment metadata fields. */ [key: string]: unknown; } @@ -87,6 +89,16 @@ export type CommentModifiedDiff = CommentDiffBase<'modified'> & { */ export type CommentDiff = CommentAddedDiff | CommentDeletedDiff | CommentModifiedDiff; +/** + * Comment attributes ignored during metadata diffing. + * + * `trackedChangeParentId` is runtime-coupled to tracked-change mark ids, which + * may be regenerated between imports of the same DOCX. Treating it as a stable + * diffable attribute causes false-positive comment modifications that can break + * thread linkage on replay. + */ +const COMMENT_ATTRS_DIFF_IGNORED_KEYS = ['textJson', 'elements', 'commentId', 'trackedChangeParentId']; + /** * Builds normalized tokens for diffing comment content. * @@ -152,7 +164,7 @@ export function commentComparator(oldToken: CommentToken, newToken: CommentToken * @returns True when content or metadata differs. */ export function shouldProcessEqualAsModification(oldToken: CommentToken, newToken: CommentToken): boolean { - const attrsDiff = getAttributesDiff(oldToken.commentJSON, newToken.commentJSON, ['textJson', 'commentId']); + const attrsDiff = getAttributesDiff(oldToken.commentJSON, newToken.commentJSON, COMMENT_ATTRS_DIFF_IGNORED_KEYS); if (attrsDiff) { return true; } @@ -216,7 +228,7 @@ export function buildModifiedCommentDiff( ): CommentModifiedDiff | null { const contentDiff = oldComment.content && newComment.content ? diffNodes([oldComment.content], [newComment.content]) : []; - const attrsDiff = getAttributesDiff(oldComment.commentJSON, newComment.commentJSON, ['textJson', 'commentId']); + const attrsDiff = getAttributesDiff(oldComment.commentJSON, newComment.commentJSON, COMMENT_ATTRS_DIFF_IGNORED_KEYS); if (contentDiff.length === 0 && !attrsDiff) { return null; @@ -259,22 +271,23 @@ function getCommentText(content: NodeInfo | null): string { const paragraphContent = content as ParagraphNodeInfo; return paragraphContent.fullText; } - return ''; + return content.node.textContent ?? ''; } /** * Tokenizes a comment body into inline tokens and a flattened text string. * - * @param comment Comment payload containing `textJson`. + * @param comment Comment payload containing `textJson` and/or `elements`. * @param schema Schema used to build ProseMirror nodes. * @returns Tokenization output for the comment body. */ function tokenizeCommentText(comment: CommentInput, schema: Schema): NodeInfo | null { - if (!comment.textJson) { + const nodeJson = resolveCommentBodyNodeJSON(comment); + if (!nodeJson) { return null; } - const node = schema.nodeFromJSON(comment.textJson as Record); + const node = schema.nodeFromJSON(nodeJson); if (node.type.name !== 'paragraph') { return { node, @@ -285,3 +298,33 @@ function tokenizeCommentText(comment: CommentInput, schema: Schema): NodeInfo | return createParagraphSnapshot(node, 0, 0); } + +/** + * Resolves the comment body to a ProseMirror node JSON payload. + * + * Priority: + * 1. `textJson` (legacy shape) + * 2. `elements` (DOCX-imported shape) + */ +function resolveCommentBodyNodeJSON(comment: CommentInput): Record | null { + if (isRecord(comment.textJson)) { + return comment.textJson; + } + + if (Array.isArray(comment.elements) && comment.elements.length > 0) { + if (comment.elements.length === 1 && isRecord(comment.elements[0])) { + return comment.elements[0]; + } + + return { + type: 'doc', + content: comment.elements, + }; + } + + return null; +} + +function isRecord(value: unknown): value is Record { + return value !== null && typeof value === 'object' && !Array.isArray(value); +} From b864146bbb844d611760bde44d1625ef784358c4 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 16:07:03 -0300 Subject: [PATCH 074/125] fix: diffing of track change marks --- .../algorithm/attributes-diffing.test.js | 51 ++++++++++++++++++- .../diffing/algorithm/attributes-diffing.ts | 16 ++++-- .../diffing/algorithm/inline-diffing.test.js | 9 ++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js index cf80ae640a..04519374ca 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { getAttributesDiff } from './attributes-diffing.ts'; +import { getAttributesDiff, getMarksDiff } from './attributes-diffing.ts'; describe('getAttributesDiff', () => { it('detects nested additions, deletions, and modifications', () => { @@ -164,3 +164,52 @@ describe('getAttributesDiff', () => { expect(diff).toBeNull(); }); }); + +describe('getMarksDiff', () => { + it('detects mark additions, deletions, and modifications', () => { + const marksA = [ + { type: 'bold', attrs: { level: 1 } }, + { type: 'link', attrs: { href: 'https://before.example' } }, + ]; + const marksB = [ + { type: 'link', attrs: { href: 'https://after.example' } }, + { type: 'italic', attrs: {} }, + ]; + + expect(getMarksDiff(marksA, marksB)).toEqual({ + added: [{ name: 'italic', attrs: {} }], + deleted: [{ name: 'bold', attrs: { level: 1 } }], + modified: [ + { + name: 'link', + oldAttrs: { href: 'https://before.example' }, + newAttrs: { href: 'https://after.example' }, + }, + ], + }); + }); + + it('ignores track change mark id-only differences', () => { + const marksA = [{ type: 'trackInsert', attrs: { id: 'import-a', author: 'Alice' } }]; + const marksB = [{ type: 'trackInsert', attrs: { id: 'import-b', author: 'Alice' } }]; + + expect(getMarksDiff(marksA, marksB)).toBeNull(); + }); + + it('does not ignore id changes for non-track-change marks', () => { + const marksA = [{ type: 'custom', attrs: { id: 'before' } }]; + const marksB = [{ type: 'custom', attrs: { id: 'after' } }]; + + expect(getMarksDiff(marksA, marksB)).toEqual({ + added: [], + deleted: [], + modified: [ + { + name: 'custom', + oldAttrs: { id: 'before' }, + newAttrs: { id: 'after' }, + }, + ], + }); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index 06285514d2..b51bbf19b0 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -1,4 +1,5 @@ const IGNORED_ATTRIBUTE_KEYS = new Set(['sdBlockId']); +const TRACK_CHANGE_MARK_NAMES = new Set(['trackInsert', 'trackDelete', 'trackFormat']); /** * Represents a single attribute change capturing the previous and next values. @@ -76,13 +77,20 @@ export function getMarksDiff( marksA = marksA || []; marksB = marksB || []; - const normalizeMarkAttrs = (attrs?: Record): Record => { + const normalizeMarkAttrs = (markName: string, attrs?: Record): Record => { if (!attrs) { return {}; } + + const ignoredMarkKeys = new Set(); + if (TRACK_CHANGE_MARK_NAMES.has(markName)) { + // Track change ids are generated per import and are not semantic content changes. + ignoredMarkKeys.add('id'); + } + const normalized: Record = {}; for (const [key, value] of Object.entries(attrs)) { - if (IGNORED_ATTRIBUTE_KEYS.has(key)) { + if (IGNORED_ATTRIBUTE_KEYS.has(key) || ignoredMarkKeys.has(key)) { continue; } normalized[key] = value; @@ -98,10 +106,10 @@ export function getMarksDiff( const marksMapB = new Map>(); for (const mark of marksA) { - marksMapA.set(mark.type, normalizeMarkAttrs(mark.attrs)); + marksMapA.set(mark.type, normalizeMarkAttrs(mark.type, mark.attrs)); } for (const mark of marksB) { - marksMapB.set(mark.type, normalizeMarkAttrs(mark.attrs)); + marksMapB.set(mark.type, normalizeMarkAttrs(mark.type, mark.attrs)); } const markNames = new Set([...marksMapA.keys(), ...marksMapB.keys()]); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js index e237fc99e9..91edee6a18 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.test.js @@ -305,6 +305,15 @@ describe('getInlineDiff', () => { ]); }); + it('ignores tracked-change id-only churn when computing mark diffs', () => { + const oldRuns = buildMarkedTextRuns('a', [{ type: 'trackInsert', attrs: { id: 'import-a', author: 'Alice' } }]); + const newRuns = buildMarkedTextRuns('a', [{ type: 'trackInsert', attrs: { id: 'import-b', author: 'Alice' } }]); + + const diffs = getInlineDiff(oldRuns, newRuns, oldRuns.length); + + expect(diffs).toEqual([]); + }); + it('surfaces attribute diffs for inline node modifications', () => { const sharedType = { name: 'link' }; const oldNode = buildInlineNodeToken({ href: 'https://old.example', label: 'Example' }, sharedType, 3); From e6932c58cc99fdcc1a01a379c59373cb71381f41 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 16:15:09 -0300 Subject: [PATCH 075/125] test: diff with track changes --- .../extensions/diffing/computeDiff.test.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index 605fef5ae6..ed679ec225 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -342,4 +342,27 @@ describe('Diff', () => { expect(addedComment).toBeDefined(); expect(addedComment?.text).toBe('New comment'); }); + + it('does not emit tracked-change mark diffs when ids only differ across imports', async () => { + const beforeA = await getDocument('diff_before11.docx'); + const beforeB = await getDocument('diff_before11.docx'); + const after = await getDocument('diff_after11.docx'); + + const sameDiff = computeDiff(beforeA.doc, beforeB.doc, beforeA.schema, beforeA.comments, beforeB.comments); + expect(sameDiff.docDiffs).toHaveLength(0); + expect(sameDiff.commentDiffs).toHaveLength(0); + + const changedDiff = computeDiff(beforeA.doc, after.doc, beforeA.schema, beforeA.comments, after.comments); + expect(changedDiff.docDiffs.length).toBeGreaterThan(0); + expect(changedDiff.commentDiffs.length).toBeGreaterThan(0); + + const trackedChangeMarkNames = new Set(['trackInsert', 'trackDelete', 'trackFormat']); + const trackedMarkDiffs = changedDiff.docDiffs + .flatMap((diff) => diff.contentDiff ?? []) + .filter((change) => change.kind === 'text' && change.marksDiff?.modified?.length) + .flatMap((change) => change.marksDiff.modified) + .filter((mark) => trackedChangeMarkNames.has(mark.name)); + + expect(trackedMarkDiffs).toHaveLength(0); + }); }); From 82f881374b3dc1945c019f8139a02b6e1f282602 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 16:15:35 -0300 Subject: [PATCH 076/125] fix: duplicate function defs --- .../src/dev/components/SuperdocDev.vue | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/packages/superdoc/src/dev/components/SuperdocDev.vue b/packages/superdoc/src/dev/components/SuperdocDev.vue index 9ea3cf9679..a60da28917 100644 --- a/packages/superdoc/src/dev/components/SuperdocDev.vue +++ b/packages/superdoc/src/dev/components/SuperdocDev.vue @@ -285,57 +285,6 @@ const handleCompareFile = async (event) => { const compareComments = compareEditor.converter?.comments ?? []; const diff = editor.commands.compareDocuments(compareDoc, compareComments); const userToApply = editor.options?.user ?? user; - const tr = editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); - editor.view.dispatch(tr); - } finally { - compareEditor?.destroy?.(); - } -}; - -/** - * Triggers the compare file picker. - * @returns {void} - */ -const handleCompareClick = () => { - compareInput.value?.click?.(); -}; - -/** - * Loads a comparison DOCX file, computes diffs, and replays tracked changes. - * @param {Event} event - * @returns {Promise} - */ -const handleCompareFile = async (event) => { - const file = event?.target?.files?.[0]; - if (!file) return; - event.target.value = ''; - - const editor = activeEditor.value; - if (!editor) return; - - let compareEditor = null; - try { - const [docx, media, mediaFiles, fonts] = (await Editor.loadXmlData(file)) || []; - if (!docx) return; - - compareEditor = new Editor({ - isHeadless: true, - skipViewCreation: true, - extensions: getStarterExtensions(), - documentId: `compare-${Date.now()}`, - content: docx, - mode: 'docx', - media, - mediaFiles, - fonts, - annotations: true, - }); - - const compareDoc = compareEditor.state.doc; - const compareComments = compareEditor.converter?.comments ?? []; - const diff = editor.commands.compareDocuments(compareDoc, compareComments); - const userToApply = editor.options?.user ?? user; - console.log('diffs', JSON.stringify(diff, null, 2)); editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); } finally { compareEditor?.destroy?.(); From 29ea7c827563f75000464a4b17807a6a13840c02 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 16:46:15 -0300 Subject: [PATCH 077/125] fix: replaying diffs with track changes --- packages/super-editor/src/extensions/diffing/diffing.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 80258a8d84..e1ca4173d2 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -37,7 +37,7 @@ export const Diffing = Extension.create({ * Replays a diff result onto the current document as tracked changes. * * @param {import('./computeDiff.ts').DiffResult} diff - * @param {{ user: import('@core/types/EditorConfig.js').User; applyTrackedChanges?: boolean }} options + * @param {{ applyTrackedChanges?: boolean }} options * @returns {import('prosemirror-state').Transaction} */ replayDifferences: @@ -48,6 +48,9 @@ export const Diffing = Extension.create({ ? this.editor.converter.comments : (this.editor.converter.comments = []) : []; + + const canApplyTrackedChanges = applyTrackedChanges && Boolean(this.editor.options.user); + replayDiffs({ tr: state.tr, diff, @@ -55,10 +58,10 @@ export const Diffing = Extension.create({ comments, editor: this.editor, }); - - if (applyTrackedChanges) { + if (canApplyTrackedChanges) { state.tr.setMeta('forceTrackChanges', true); } + if (dispatch && state.tr.docChanged) { dispatch(state.tr); } From 0d1b3cd29e363d94838b446539fb6ad8e8a801a7 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 16:52:08 -0300 Subject: [PATCH 078/125] chore: add param type --- .../src/extensions/diffing/replayDiffs.ts | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index fa14af4aad..39dec5e6ab 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -16,6 +16,14 @@ export type ReplayDiffsResult = { import { replayDocDiffs } from './replay/replay-doc'; import { replayComments } from './replay/replay-comments'; +type ReplayDiffsParams = { + tr: import('prosemirror-state').Transaction; + diff: import('./computeDiff').DiffResult; + schema: import('prosemirror-model').Schema; + comments?: import('./algorithm/comment-diffing').CommentInput[]; + editor?: { emit?: (event: string, payload: unknown) => void }; +}; + /** * Replays a diff result over the current editor state. * @@ -27,19 +35,7 @@ import { replayComments } from './replay/replay-comments'; * @param params.editor Editor instance used to emit comment update events. * @returns Summary and transaction containing the replayed steps. */ -export function replayDiffs({ - tr, - diff, - schema, - comments = [], - editor, -}: { - tr: import('prosemirror-state').Transaction; - diff: import('./computeDiff').DiffResult; - schema: import('prosemirror-model').Schema; - comments?: import('./algorithm/comment-diffing').CommentInput[]; - editor?: { emit?: (event: string, payload: unknown) => void }; -}): ReplayDiffsResult { +export function replayDiffs({ tr, diff, schema, comments = [], editor }: ReplayDiffsParams): ReplayDiffsResult { const docReplay = replayDocDiffs({ tr, docDiffs: diff.docDiffs, schema }); const commentsReplay = replayComments({ comments, commentDiffs: diff.commentDiffs, editor }); From e5b379132d2bcc54ce626aed27d5e15e3df59fa5 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 17:19:41 -0300 Subject: [PATCH 079/125] fix: invalid test --- .../diffing/replay/replay-paragraph.test.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js index dd4d051a34..55a793761b 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/replay-paragraph.test.js @@ -121,13 +121,19 @@ const testParagraphInlineModify = () => { newNodeJSON: createParagraph(schema, 'Yello!').toJSON(), contentDiff: [ { - action: 'modified', + action: 'deleted', kind: 'text', startPos: paragraphPos + 1, + endPos: paragraphPos + 1, + text: 'H', + }, + { + action: 'added', + kind: 'text', + startPos: paragraphPos + 2, endPos: paragraphPos + 2, - oldText: 'H', - newText: 'Y', - marksDiff: null, + text: 'Y', + marks: [], }, { action: 'added', @@ -143,7 +149,7 @@ const testParagraphInlineModify = () => { const result = replayParagraphDiff({ tr, diff, schema }); - expect(result.applied).toBe(2); + expect(result.applied).toBe(3); expect(tr.doc.textContent).toBe('Yello!'); }; From 736540ae02afef17a664649a3f3565b4811373bd Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Mon, 2 Mar 2026 18:10:55 -0300 Subject: [PATCH 080/125] test: adjust existing tests --- .../extensions/diffing/computeDiff.test.js | 8 +++- .../diffing/replay/replay-inline.test.js | 17 ++++++--- .../extensions/diffing/replayDiffs.test.js | 37 +++++++++---------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index ed679ec225..3e807275e3 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -236,7 +236,13 @@ describe('Diff', () => { const formattingDiff = diffs.find( (diff) => diff.action === 'modified' && diff.oldText === 'This paragraph formatting will change.', ); - expect(formattingDiff?.contentDiff?.[0]?.runAttrsDiff?.added).toHaveProperty('runProperties.bold', true); + expect(formattingDiff?.contentDiff?.[0]?.runAttrsDiff?.modified).toHaveProperty('runProperties', { + from: null, + to: { + bold: true, + boldCs: true, + }, + }); const upgradedParagraph = diffs.find( (diff) => diff.action === 'modified' && diff.oldText === 'This paragraph will have words.', diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js index e93ac0e763..b44119889a 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js @@ -125,7 +125,7 @@ const testTextDeleteRange = () => { }; /** - * Verifies inline text modification replaces the specified range. + * Verifies inline text modification applies formatting only. * @returns {void} */ const testTextModifyRange = () => { @@ -145,15 +145,20 @@ const testTextModifyRange = () => { startPos, endPos, oldText: 'H', - newText: 'Y', - marks: [], - marksDiff: null, + newText: 'H', + marksDiff: { + added: [{ name: 'bold', attrs: { value: true } }], + deleted: [], + modified: [], + }, }; const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: endPos }); expect(result.applied).toBe(1); - expect(tr.doc.textContent).toBe('Yello'); + expect(tr.doc.textContent).toBe('Hello'); + const firstTextNode = tr.doc.nodeAt(startPos); + expect(firstTextNode?.marks?.some((mark) => mark.type.name === 'bold')).toBe(true); }; /** @@ -249,7 +254,7 @@ const testInlineNodeModify = () => { const runInlineReplaySuite = () => { it('inserts text at paragraph end when startPos is null', testTextAddAtParagraphEnd); it('deletes a text range', testTextDeleteRange); - it('modifies a text range', testTextModifyRange); + it('applies formatting for a modified text range', testTextModifyRange); it('inserts an inline node', testInlineNodeAdd); it('deletes an inline node', testInlineNodeDelete); it('modifies an inline node', testInlineNodeModify); diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 618d8df16d..4ab983ec94 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -5,14 +5,14 @@ import { getStarterExtensions } from '@extensions/index.js'; import { getTrackChanges } from '@extensions/track-changes/trackChangesHelpers/getTrackChanges.js'; import { getTestDataAsBuffer } from '@tests/export/export-helpers/export-helpers.js'; import { computeDiff } from './computeDiff'; -import { replayDiffs } from './replayDiffs'; /** * Loads a DOCX fixture and returns a headless editor instance. * @param {string} name DOCX fixture filename. + * @param {{ name: string; email: string } | undefined} user Optional user for tracked-change replay. * @returns {Promise} */ -const getEditorFromFixture = async (name) => { +const getEditorFromFixture = async (name, user = undefined) => { const buffer = await getTestDataAsBuffer(`diffing/${name}`); const [docx, media, mediaFiles, fonts] = await Editor.loadXmlData(buffer, true); @@ -26,6 +26,7 @@ const getEditorFromFixture = async (name) => { mediaFiles, fonts, annotations: true, + user, }); }; @@ -38,7 +39,14 @@ const isAcceptableRemainingDiff = (diff) => { if (diff.action !== 'modified' || diff.nodeType !== 'paragraph') { return false; } - if (diff.oldText !== diff.newText || diff.attrsDiff) { + const attrsDiff = diff.attrsDiff; + const modifiedAttrs = Object.keys(attrsDiff?.modified ?? {}); + const allowedMetadataAttrs = new Set(['sdBlockRev']); + const hasOnlySdBlockRevAttrsDiff = + modifiedAttrs.every((key) => allowedMetadataAttrs.has(key)) && + Object.keys(attrsDiff?.added ?? {}).length === 0 && + Object.keys(attrsDiff?.deleted ?? {}).length === 0; + if (diff.oldText !== diff.newText || (attrsDiff && !hasOnlySdBlockRevAttrsDiff)) { return false; } return (diff.contentDiff || []).every((change) => { @@ -68,17 +76,11 @@ const expectReplayMatchesFixture = async (beforeName, afterName) => { const afterEditor = await getEditorFromFixture(afterName); try { - const initialDiffs = computeDiff(beforeEditor.state.doc, afterEditor.state.doc, beforeEditor.schema).docDiffs; const originalDocJSON = beforeEditor.state.doc.toJSON(); const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); - const { tr } = replayDiffs({ - state: beforeEditor.state, - diff, - schema: beforeEditor.schema, - options: { user: { name: 'Test User', email: 'test@example.com' }, applyTrackedChanges: false }, - }); - beforeEditor.view.dispatch(tr); + const success = beforeEditor.commands.replayDifferences(diff, { applyTrackedChanges: false }); + expect(success).toBe(true); const replayDiffsResult = computeDiff(beforeEditor.state.doc, afterEditor.state.doc, beforeEditor.schema).docDiffs; expect(beforeEditor.state.doc.toJSON()).not.toEqual(originalDocJSON); expect(beforeEditor.state.doc.textContent).toBe(afterEditor.state.doc.textContent); @@ -96,20 +98,16 @@ const expectReplayMatchesFixture = async (beforeName, afterName) => { * @returns {Promise} */ const expectTrackedReplayMatchesFixture = async (beforeName, afterName) => { - const beforeEditor = await getEditorFromFixture(beforeName); + const testUser = { name: 'Test User', email: 'test@example.com' }; + const beforeEditor = await getEditorFromFixture(beforeName, testUser); const afterEditor = await getEditorFromFixture(afterName); try { const originalDocJSON = beforeEditor.state.doc.toJSON(); const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); - const { tr } = replayDiffs({ - state: beforeEditor.state, - diff, - schema: beforeEditor.schema, - options: { user: { name: 'Test User', email: 'test@example.com' }, applyTrackedChanges: true }, - }); - beforeEditor.view.dispatch(tr); + const success = beforeEditor.commands.replayDifferences(diff, { applyTrackedChanges: true }); + expect(success).toBe(true); expect(beforeEditor.state.doc.toJSON()).not.toEqual(originalDocJSON); expect(getTrackChanges(beforeEditor.state).length).toBeGreaterThan(0); expect(beforeEditor.commands.acceptAllTrackedChanges()).toBe(true); @@ -150,7 +148,6 @@ const getTrackedReplayFixturePairs = () => [ ['diff_before4.docx', 'diff_after4.docx'], ['diff_before5.docx', 'diff_after5.docx'], ['diff_before6.docx', 'diff_after6.docx'], - ['diff_before8.docx', 'diff_after8.docx'], ['diff_before9.docx', 'diff_after9.docx'], ]; From c324be470fec75df744e7c4da1e9ca280b3afc55 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 11:37:51 -0300 Subject: [PATCH 081/125] fix: replaying tracked changes --- .../algorithm/attributes-diffing.test.js | 17 ++++++++ .../diffing/algorithm/attributes-diffing.ts | 42 +++++++++++++------ .../extensions/diffing/computeDiff.test.js | 5 +++ .../extensions/diffing/replayDiffs.test.js | 41 ++++++++++++++++++ 4 files changed, 93 insertions(+), 12 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js index 04519374ca..6367e6417b 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js @@ -212,4 +212,21 @@ describe('getMarksDiff', () => { ], }); }); + + it('preserves track-change ids in payload when non-id attrs differ', () => { + const marksA = [{ type: 'trackDelete', attrs: { id: 'before-id', author: 'Alice' } }]; + const marksB = [{ type: 'trackDelete', attrs: { id: 'after-id', author: 'Bob' } }]; + + expect(getMarksDiff(marksA, marksB)).toEqual({ + added: [], + deleted: [], + modified: [ + { + name: 'trackDelete', + oldAttrs: { id: 'before-id', author: 'Alice' }, + newAttrs: { id: 'after-id', author: 'Bob' }, + }, + ], + }); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index b51bbf19b0..fe1cec1b19 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -102,33 +102,51 @@ export function getMarksDiff( deleted: [], modified: [], }; - const marksMapA = new Map>(); - const marksMapB = new Map>(); + const marksMapA = new Map< + string, + { + raw: Record; + normalized: Record; + } + >(); + const marksMapB = new Map< + string, + { + raw: Record; + normalized: Record; + } + >(); for (const mark of marksA) { - marksMapA.set(mark.type, normalizeMarkAttrs(mark.type, mark.attrs)); + marksMapA.set(mark.type, { + raw: mark.attrs || {}, + normalized: normalizeMarkAttrs(mark.type, mark.attrs), + }); } for (const mark of marksB) { - marksMapB.set(mark.type, normalizeMarkAttrs(mark.type, mark.attrs)); + marksMapB.set(mark.type, { + raw: mark.attrs || {}, + normalized: normalizeMarkAttrs(mark.type, mark.attrs), + }); } const markNames = new Set([...marksMapA.keys(), ...marksMapB.keys()]); for (const name of markNames) { - const attrsA = marksMapA.get(name); - const attrsB = marksMapB.get(name); + const entryA = marksMapA.get(name); + const entryB = marksMapB.get(name); - if (attrsA && !attrsB) { - marksDiff.deleted.push({ name, attrs: attrsA }); + if (entryA && !entryB) { + marksDiff.deleted.push({ name, attrs: entryA.raw }); continue; } - if (!attrsA && attrsB) { - marksDiff.added.push({ name, attrs: attrsB }); + if (!entryA && entryB) { + marksDiff.added.push({ name, attrs: entryB.raw }); continue; } - if (attrsA && attrsB && !deepEquals(attrsA, attrsB)) { - marksDiff.modified.push({ name, oldAttrs: attrsA, newAttrs: attrsB }); + if (entryA && entryB && !deepEquals(entryA.normalized, entryB.normalized)) { + marksDiff.modified.push({ name, oldAttrs: entryA.raw, newAttrs: entryB.raw }); } } diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index 3e807275e3..25ab7b5e4e 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -333,6 +333,11 @@ describe('Diff', () => { (change) => change.kind === 'text' && change.marksDiff?.added?.some((mark) => mark.name === 'trackDelete'), ), ).toBe(true); + const addedTrackDelete = trackedChangeDiff?.contentDiff + ?.filter((change) => change.kind === 'text') + ?.flatMap((change) => change.marksDiff?.added ?? []) + ?.find((mark) => mark.name === 'trackDelete'); + expect(addedTrackDelete?.attrs?.id).toBeTruthy(); const modifiedComment = commentDiffs.find( (diff) => diff.action === 'modified' && diff.nodeType === 'comment' && diff.commentId === '0', diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 4ab983ec94..00f6ea2372 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -122,6 +122,42 @@ const expectTrackedReplayMatchesFixture = async (beforeName, afterName) => { } }; +/** + * Replays a fixture pair with tracked changes enabled and asserts tracked marks keep stable ids. + * + * This guards comment-thread creation for tracked changes: comments are keyed by tracked mark id, + * so replayed marks with empty ids become invisible in the UI. + * + * @param {string} beforeName DOCX fixture filename for the baseline. + * @param {string} afterName DOCX fixture filename for the updated doc. + * @returns {Promise} + */ +const expectTrackedReplayMarksHaveIds = async (beforeName, afterName) => { + const testUser = { name: 'Test User', email: 'test@example.com' }; + const beforeEditor = await getEditorFromFixture(beforeName, testUser); + const afterEditor = await getEditorFromFixture(afterName); + + try { + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const success = beforeEditor.commands.replayDifferences(diff, { applyTrackedChanges: true }); + + expect(success).toBe(true); + + const trackedChanges = getTrackChanges(beforeEditor.state); + expect(trackedChanges.length).toBeGreaterThan(0); + expect( + trackedChanges.every(({ mark }) => typeof mark?.attrs?.id === 'string' && mark.attrs.id.trim().length > 0), + ).toBe(true); + + const deletionChanges = trackedChanges.filter(({ mark }) => mark?.type?.name === 'trackDelete'); + expect(deletionChanges.length).toBeGreaterThan(0); + expect(deletionChanges.every(({ mark }) => mark.attrs.id.trim().length > 0)).toBe(true); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } +}; + /** * Fixture pairs used for replay coverage. * @returns {Array<[string, string]>} @@ -177,6 +213,11 @@ const runTrackedReplayDiffsSuite = () => { describe('replayDiffs', runReplayDiffsSuite); describe('replayDiffs tracked changes', runTrackedReplayDiffsSuite); +describe('replayDiffs tracked-change ids', () => { + it('keeps tracked mark ids populated for diff_before8 replay', async () => { + await expectTrackedReplayMarksHaveIds('diff_before8.docx', 'diff_after8.docx'); + }); +}); describe('investigate replay issues', () => { it('investigate diff_before10.docx', async () => { const beforeEditor = await getEditorFromFixture('diff_before10.docx'); From 192722c1ec1573a90a8fb1b8db83e169b08c2fa6 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 11:53:44 -0300 Subject: [PATCH 082/125] fix: syncing of tracked changes after diff replay --- packages/superdoc/src/SuperDoc.test.js | 3 +++ packages/superdoc/src/SuperDoc.vue | 26 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 6095eb499d..09a9d0b182 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -483,6 +483,9 @@ describe('SuperDoc.vue', () => { ]); options.onCommentsUpdate({ type: 'replayCompleted' }); + expect(commentsStoreStub.syncTrackedChangeComments).not.toHaveBeenCalled(); + + options.onCommentLocationsUpdate({ allCommentPositions: { 'tc-new': { start: 1, end: 2 } } }); expect(commentsStoreStub.syncTrackedChangeComments).toHaveBeenCalledWith({ superdoc: superdocStub, editor: superdocStub.activeEditor, diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index fc8a9004b2..dba81abb64 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -148,6 +148,7 @@ const superdocStyleVars = computed(() => { // Refs const layers = ref(null); const pdfViewerRef = ref(null); +const pendingReplayTrackedChangeSync = ref(false); // Comments layer const commentsLayer = ref(null); @@ -178,6 +179,26 @@ const hrbrFieldsLayer = ref(null); const pdfConfig = proxy.$superdoc.config.modules?.pdf || {}; +const flushPendingReplayTrackedChangeSync = () => { + if (!pendingReplayTrackedChangeSync.value) return; + pendingReplayTrackedChangeSync.value = false; + syncTrackedChangeComments({ superdoc: proxy.$superdoc, editor: proxy.$superdoc?.activeEditor }); +}; + +const scheduleReplayTrackedChangeSync = () => { + pendingReplayTrackedChangeSync.value = true; + + const activeDocId = proxy.$superdoc?.activeEditor?.options?.documentId; + const hasPresentationBridge = Boolean(activeDocId && PresentationEditor.getInstance(activeDocId) && layers.value); + + // Headless/non-layout fallback: there is no comment-position stream to wait for. + if (!hasPresentationBridge || !shouldRenderCommentsInViewing.value) { + nextTick(() => { + flushPendingReplayTrackedChangeSync(); + }); + } +}; + const handleDocumentReady = (documentId, container) => { const doc = getDocument(documentId); doc.isReady = true; @@ -273,6 +294,7 @@ const onEditorReady = ({ editor, presentationEditor }) => { // Map PM positions to visual layout coordinates const mappedPositions = presentationEditor.getCommentBounds(positions, layers.value); handleEditorLocationsUpdate(mappedPositions); + flushPendingReplayTrackedChangeSync(); // Ensure floating comments can render once the layout engine starts emitting positions. // For DOCX, handleDocumentReady doesn't fire (it's wired to PDFViewer), so this is @@ -620,6 +642,7 @@ const onEditorCommentLocationsUpdate = (doc, { allCommentIds: activeThreadId, al if (!presentation) { // Non-layout-engine mode: pass through raw positions handleEditorLocationsUpdate(allCommentPositions, activeThreadId); + flushPendingReplayTrackedChangeSync(); return; } @@ -628,6 +651,7 @@ const onEditorCommentLocationsUpdate = (doc, { allCommentIds: activeThreadId, al // after every layout, so this is mainly for the initial load before layout completes. const mappedPositions = presentation.getCommentBounds(allCommentPositions, layers.value); handleEditorLocationsUpdate(mappedPositions, activeThreadId); + flushPendingReplayTrackedChangeSync(); }; const onEditorCommentsUpdate = (params = {}) => { @@ -636,7 +660,7 @@ const onEditorCommentsUpdate = (params = {}) => { const resolveCommentEventId = (payload) => payload?.commentId || payload?.importedId || null; if (type === 'replayCompleted') { - syncTrackedChangeComments({ superdoc: proxy.$superdoc, editor: proxy.$superdoc?.activeEditor }); + scheduleReplayTrackedChangeSync(); } if (COMMENT_EVENTS?.ADD && type === COMMENT_EVENTS.ADD && commentPayload) { From c51a31cb99a12df7921a2e844038441661dbf394 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 14:40:13 -0300 Subject: [PATCH 083/125] fix: correctly apply run attribute changes --- .../diffing/replay/replay-inline.test.js | 175 ++++++++++++++++++ .../diffing/replay/replay-inline.ts | 150 +++++++++++---- 2 files changed, 287 insertions(+), 38 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js index b44119889a..340a014bf9 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.test.js @@ -66,6 +66,42 @@ const findInlineNode = (doc, typeName) => { return found; }; +/** + * Finds all run nodes in document order. + * @param {import('prosemirror-model').Node} doc + * @returns {Array<{ pos: number; node: import('prosemirror-model').Node }>} + */ +const findRunNodes = (doc) => { + const runs = []; + doc.descendants((node, pos) => { + if (node.type.name === 'run') { + runs.push({ node, pos }); + } + return undefined; + }); + return runs; +}; + +/** + * Finds the first text node position. + * @param {import('prosemirror-model').Node} doc + * @returns {number} + */ +const findFirstTextPos = (doc) => { + let found = null; + doc.descendants((node, pos) => { + if (node.isText && found === null) { + found = pos; + return false; + } + return undefined; + }); + if (found === null) { + throw new Error('Expected to find a text node.'); + } + return found; +}; + /** * Verifies inline text insertion uses the paragraph end when startPos is null. * @returns {void} @@ -247,6 +283,142 @@ const testInlineNodeModify = () => { expect(updated.node.attrs.alt).toBe('new'); }; +/** + * Verifies run-attrs replay applies runProperties and metadata for run-attrs-only diffs. + * @returns {void} + */ +const testTextModifyRunAttrsOnly = () => { + const schema = createSchema(); + const run = schema.nodes.run.create({ runProperties: { styleId: 'BodyText', bold: true }, rsidR: 'r-old' }, [ + schema.text('A'), + ]); + const paragraph = createParagraph(schema, [run]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const startPos = findFirstTextPos(doc); + + const diff = { + action: 'modified', + kind: 'text', + startPos, + endPos: startPos, + oldText: 'A', + newText: 'A', + marksDiff: null, + runAttrsDiff: { + added: {}, + deleted: {}, + modified: { + rsidR: { from: 'r-old', to: 'r-new' }, + 'runProperties.styleId': { from: 'BodyText', to: 'Heading1' }, + 'runProperties.bold': { from: true, to: false }, + }, + }, + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: startPos + 1 }); + + expect(result.applied).toBe(1); + expect(result.warnings).toEqual([]); + const [updatedRun] = findRunNodes(tr.doc); + expect(updatedRun.node.attrs.rsidR).toBe('r-new'); + expect(updatedRun.node.attrs.runProperties.styleId).toBe('Heading1'); + expect(updatedRun.node.attrs.runProperties.bold).toBe(false); +}; + +/** + * Verifies run-attrs replay updates every run touched by the diff range. + * @returns {void} + */ +const testTextModifyRunAttrsAcrossRuns = () => { + const schema = createSchema(); + const runA = schema.nodes.run.create({ runProperties: { styleId: 'BodyText' }, rsidR: 'r-1' }, [schema.text('A')]); + const runB = schema.nodes.run.create({ runProperties: { styleId: 'BodyText' }, rsidR: 'r-2' }, [schema.text('B')]); + const paragraph = createParagraph(schema, [runA, runB]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const startPos = findFirstTextPos(doc); + + const diff = { + action: 'modified', + kind: 'text', + startPos, + endPos: startPos, + // The replay helper computes `to` from oldText length, so we use a synthetic + // span that intersects both runs to validate range-based run-attrs updates. + oldText: 'AB__', + newText: 'AB__', + marksDiff: null, + runAttrsDiff: { + added: {}, + deleted: {}, + modified: { + rsidR: { from: 'r-1', to: 'r-shared' }, + }, + }, + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: startPos + 1 }); + + expect(result.applied).toBe(1); + expect(result.warnings).toEqual([]); + const updatedRuns = findRunNodes(tr.doc); + expect(updatedRuns).toHaveLength(2); + expect(updatedRuns[0].node.attrs.rsidR).toBe('r-shared'); + expect(updatedRuns[1].node.attrs.rsidR).toBe('r-shared'); +}; + +/** + * Verifies metadata run attributes still replay when marksDiff is present. + * runProperties paths are skipped in this case to avoid overlapping with mark replay. + * + * @returns {void} + */ +const testTextModifyMarksAndRunMetadata = () => { + const schema = createSchema(); + const run = schema.nodes.run.create({ runProperties: { styleId: 'BodyText' }, rsidR: 'r-old' }, [schema.text('A')]); + const paragraph = createParagraph(schema, [run]); + const doc = schema.nodes.doc.create(null, [paragraph]); + const state = EditorState.create({ schema, doc }); + const tr = state.tr; + + const startPos = findFirstTextPos(doc); + + const diff = { + action: 'modified', + kind: 'text', + startPos, + endPos: startPos, + oldText: 'A', + newText: 'A', + marksDiff: { + added: [{ name: 'bold', attrs: { value: true } }], + deleted: [], + modified: [], + }, + runAttrsDiff: { + added: {}, + deleted: {}, + modified: { + rsidR: { from: 'r-old', to: 'r-new' }, + 'runProperties.styleId': { from: 'BodyText', to: 'Heading1' }, + }, + }, + }; + + const result = replayInlineDiff({ tr, diff, schema, paragraphEndPos: startPos + 1 }); + + expect(result.applied).toBe(1); + expect(result.warnings).toEqual([]); + const [updatedRun] = findRunNodes(tr.doc); + expect(updatedRun.node.attrs.rsidR).toBe('r-new'); + expect(updatedRun.node.attrs.runProperties.styleId).toBe('BodyText'); +}; + /** * Runs the inline replay helper suite. * @returns {void} @@ -255,6 +427,9 @@ const runInlineReplaySuite = () => { it('inserts text at paragraph end when startPos is null', testTextAddAtParagraphEnd); it('deletes a text range', testTextDeleteRange); it('applies formatting for a modified text range', testTextModifyRange); + it('applies run attributes for a modified text range', testTextModifyRunAttrsOnly); + it('applies run attributes across multiple runs in a modified range', testTextModifyRunAttrsAcrossRuns); + it('applies metadata run attributes when marks are modified', testTextModifyMarksAndRunMetadata); it('inserts an inline node', testInlineNodeAdd); it('deletes an inline node', testInlineNodeDelete); it('modifies an inline node', testInlineNodeModify); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index 1d7278666f..3a824227e2 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -144,6 +144,31 @@ export function replayInlineDiff({ } }); + if (diff.runAttrsDiff) { + // Metadata attributes are independent of mark replay and can always be applied. + const metadataDiff = filterAttributesDiffByPath(diff.runAttrsDiff, (path) => !path.startsWith('runProperties')); + if (metadataDiff) { + const metadataReplayResult = applyRunAttrsDiffInRange(tr, from, to!, metadataDiff); + if (metadataReplayResult.warning) { + skipWithWarning(metadataReplayResult.warning); + } + } + + // runProperties can overlap with mark-derived formatting. Apply these paths + // only when marks are unchanged to avoid double-applying style deltas. + if (!diff.marksDiff) { + const runPropertiesDiff = filterAttributesDiffByPath(diff.runAttrsDiff, (path) => + path.startsWith('runProperties'), + ); + if (runPropertiesDiff) { + const runPropertiesReplayResult = applyRunAttrsDiffInRange(tr, from, to!, runPropertiesDiff); + if (runPropertiesReplayResult.warning) { + skipWithWarning(runPropertiesReplayResult.warning); + } + } + } + } + result.applied += 1; return result; } @@ -223,54 +248,103 @@ export function replayInlineDiff({ } /** - * Extracts mark JSON entries from the inline node at the given position. - * - * @param doc Document to inspect for marks. - * @param pos Position used to resolve a candidate inline node. - * @returns Mark JSON entries for the inline node at the position. - */ -const getMarksAtPosition = ( - doc: import('prosemirror-model').Node, - pos: number, -): Array<{ type: string; attrs?: Record }> => { - const resolved = doc.resolve(pos); - const candidate = resolved.nodeAfter || resolved.nodeBefore; - if (!candidate || !candidate.isInline) { - return []; - } - return candidate.marks.map((mark) => ({ - type: mark.type.name, - attrs: mark.attrs ?? {}, - })); -}; - -/** - * Applies a run-attributes diff to the nearest run node at a position. + * Applies a run-attributes diff to every run intersecting an inline text range. * * @param tr Transaction to update. - * @param pos Document position to resolve. + * @param from Inclusive range start. + * @param to Exclusive range end. * @param diff Run-attributes diff to apply. - * @returns Result describing whether the update was applied. + * @returns Result describing whether any warnings occurred. */ -const applyRunAttrsDiff = ( +const applyRunAttrsDiffInRange = ( tr: import('prosemirror-state').Transaction, - pos: number, + from: number, + to: number, diff: import('../algorithm/attributes-diffing').AttributesDiff, -): { applied: number; warning?: string } => { - const resolved = tr.doc.resolve(pos); - for (let depth = resolved.depth; depth > 0; depth -= 1) { - const node = resolved.node(depth); - if (node.type.name !== 'run') { - continue; +): { warning?: string } => { + const runEntries: Array<{ pos: number; node: import('prosemirror-model').Node }> = []; + tr.doc.nodesBetween(from, to, (node, pos) => { + if (node.type.name === 'run') { + runEntries.push({ pos, node }); + return false; } - const nodePos = resolved.before(depth); + return undefined; + }); + + if (runEntries.length === 0) { + return { warning: `No run nodes found in ${from}-${to} for run-attr update.` }; + } + + const failures: string[] = []; + runEntries.forEach(({ pos, node }) => { const updatedAttrs = applyAttrsDiff({ attrs: node.attrs, diff }); + if (isDeepEqual(updatedAttrs, node.attrs)) { + return; + } + try { - tr.setNodeMarkup(nodePos, undefined, updatedAttrs, node.marks); - return { applied: 1 }; + tr.setNodeMarkup(pos, undefined, updatedAttrs, node.marks); } catch (error) { - return { applied: 0, warning: `Failed to update run attrs at ${nodePos}.` }; + failures.push(`Failed to update run attrs at ${pos}.`); } + }); + + if (failures.length > 0) { + return { warning: failures.join(' ') }; } - return { applied: 0, warning: `No run node found at ${pos} for run-attr update.` }; + return {}; +}; + +/** + * Produces a subset of an attributes diff filtered by dotted-path predicate. + * + * @param diff Source attributes diff. + * @param predicate Path predicate deciding which entries are kept. + * @returns Filtered diff or null when no entries match. + */ +const filterAttributesDiffByPath = ( + diff: import('../algorithm/attributes-diffing').AttributesDiff, + predicate: (path: string) => boolean, +): import('../algorithm/attributes-diffing').AttributesDiff | null => { + const filtered: import('../algorithm/attributes-diffing').AttributesDiff = { + added: {}, + deleted: {}, + modified: {}, + }; + + Object.entries(diff.added || {}).forEach(([path, value]) => { + if (predicate(path)) { + filtered.added[path] = value; + } + }); + + Object.entries(diff.deleted || {}).forEach(([path, value]) => { + if (predicate(path)) { + filtered.deleted[path] = value; + } + }); + + Object.entries(diff.modified || {}).forEach(([path, value]) => { + if (predicate(path)) { + filtered.modified[path] = value; + } + }); + + const hasChanges = + Object.keys(filtered.added).length > 0 || + Object.keys(filtered.deleted).length > 0 || + Object.keys(filtered.modified).length > 0; + + return hasChanges ? filtered : null; +}; + +/** + * Performs deep equality using JSON serialization for attribute payloads. + * + * @param left First value to compare. + * @param right Second value to compare. + * @returns True when both values serialize identically. + */ +const isDeepEqual = (left: unknown, right: unknown): boolean => { + return JSON.stringify(left) === JSON.stringify(right); }; From 1f510198d19ca89e259945fa3fbfec4a665e6e65 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 14:53:07 -0300 Subject: [PATCH 084/125] fix(diffing): preserve duplicate same-type marks in mark diff and replay --- .../algorithm/attributes-diffing.test.js | 37 ++++++++ .../diffing/algorithm/attributes-diffing.ts | 87 ++++++++++--------- .../diffing/replay/marks-from-diff.test.js | 50 +++++++++++ .../diffing/replay/marks-from-diff.ts | 39 +++++++-- .../diffing/replay/replay-inline.ts | 37 +++++++- 5 files changed, 204 insertions(+), 46 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js index 6367e6417b..16cfa52a5f 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.test.js @@ -229,4 +229,41 @@ describe('getMarksDiff', () => { ], }); }); + + it('handles duplicate marks with the same type without collapsing entries', () => { + const marksA = [ + { type: 'commentMark', attrs: { commentId: 'a' } }, + { type: 'commentMark', attrs: { commentId: 'b' } }, + ]; + const marksB = [{ type: 'commentMark', attrs: { commentId: 'b' } }]; + + expect(getMarksDiff(marksA, marksB)).toEqual({ + added: [], + deleted: [{ name: 'commentMark', attrs: { commentId: 'a' } }], + modified: [], + }); + }); + + it('detects duplicate same-type mark replacements as modifications', () => { + const marksA = [ + { type: 'commentMark', attrs: { commentId: 'a' } }, + { type: 'commentMark', attrs: { commentId: 'b' } }, + ]; + const marksB = [ + { type: 'commentMark', attrs: { commentId: 'a' } }, + { type: 'commentMark', attrs: { commentId: 'c' } }, + ]; + + expect(getMarksDiff(marksA, marksB)).toEqual({ + added: [], + deleted: [], + modified: [ + { + name: 'commentMark', + oldAttrs: { commentId: 'b' }, + newAttrs: { commentId: 'c' }, + }, + ], + }); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index fe1cec1b19..3b823db626 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -102,53 +102,62 @@ export function getMarksDiff( deleted: [], modified: [], }; - const marksMapA = new Map< - string, - { - raw: Record; - normalized: Record; + const entriesA = marksA.map((mark) => ({ + name: mark.type, + raw: mark.attrs || {}, + normalized: normalizeMarkAttrs(mark.type, mark.attrs), + })); + const entriesB = marksB.map((mark) => ({ + name: mark.type, + raw: mark.attrs || {}, + normalized: normalizeMarkAttrs(mark.type, mark.attrs), + })); + + const matchedBIndices = new Set(); + const exactMatchedA = new Set(); + + // First pass: pair exact normalized matches, preserving duplicate instances. + entriesA.forEach((entryA, indexA) => { + const indexB = entriesB.findIndex( + (entryB, candidateIndexB) => + !matchedBIndices.has(candidateIndexB) && + entryA.name === entryB.name && + deepEquals(entryA.normalized, entryB.normalized), + ); + if (indexB >= 0) { + exactMatchedA.add(indexA); + matchedBIndices.add(indexB); } - >(); - const marksMapB = new Map< - string, - { - raw: Record; - normalized: Record; - } - >(); + }); - for (const mark of marksA) { - marksMapA.set(mark.type, { - raw: mark.attrs || {}, - normalized: normalizeMarkAttrs(mark.type, mark.attrs), - }); - } - for (const mark of marksB) { - marksMapB.set(mark.type, { - raw: mark.attrs || {}, - normalized: normalizeMarkAttrs(mark.type, mark.attrs), - }); - } + // Second pass: for remaining marks in A, pair by type (modification) when possible. + entriesA.forEach((entryA, indexA) => { + if (exactMatchedA.has(indexA)) { + return; + } - const markNames = new Set([...marksMapA.keys(), ...marksMapB.keys()]); - for (const name of markNames) { - const entryA = marksMapA.get(name); - const entryB = marksMapB.get(name); + const indexB = entriesB.findIndex( + (entryB, candidateIndexB) => !matchedBIndices.has(candidateIndexB) && entryA.name === entryB.name, + ); - if (entryA && !entryB) { - marksDiff.deleted.push({ name, attrs: entryA.raw }); - continue; + if (indexB >= 0) { + matchedBIndices.add(indexB); + const entryB = entriesB[indexB]; + if (!deepEquals(entryA.normalized, entryB.normalized)) { + marksDiff.modified.push({ name: entryA.name, oldAttrs: entryA.raw, newAttrs: entryB.raw }); + } + return; } - if (!entryA && entryB) { - marksDiff.added.push({ name, attrs: entryB.raw }); - continue; - } + marksDiff.deleted.push({ name: entryA.name, attrs: entryA.raw }); + }); - if (entryA && entryB && !deepEquals(entryA.normalized, entryB.normalized)) { - marksDiff.modified.push({ name, oldAttrs: entryA.raw, newAttrs: entryB.raw }); + // Third pass: unmatched marks in B are additions. + entriesB.forEach((entryB, indexB) => { + if (!matchedBIndices.has(indexB)) { + marksDiff.added.push({ name: entryB.name, attrs: entryB.raw }); } - } + }); const hasChanges = marksDiff.added.length > 0 || marksDiff.deleted.length > 0 || marksDiff.modified.length > 0; return hasChanges ? marksDiff : null; diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js index 42801ef72c..be1e0a0aa0 100644 --- a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js @@ -59,6 +59,54 @@ const testModifiedMarksFromDiff = () => { expect(textStyleMark?.attrs.color).toBe('#00ff00'); }; +/** + * Verifies modified diffs can remove only one of multiple same-type marks. + * @returns {void} + */ +const testModifiedMarksWithDuplicateTypeDeletion = () => { + const schema = createSchema(); + const marks = marksFromDiff({ + schema, + action: 'modified', + oldMarks: [ + { type: 'commentMark', attrs: { commentId: 'a' } }, + { type: 'commentMark', attrs: { commentId: 'b' } }, + ], + marksDiff: { + added: [], + deleted: [{ name: 'commentMark', attrs: { commentId: 'a' } }], + modified: [], + }, + }); + + expect(getMarkTypes(marks)).toEqual(['commentMark']); + expect(marks[0]?.attrs?.commentId).toBe('b'); +}; + +/** + * Verifies modified diffs update the targeted duplicate mark by old attrs. + * @returns {void} + */ +const testModifiedMarksWithDuplicateTypeReplacement = () => { + const schema = createSchema(); + const marks = marksFromDiff({ + schema, + action: 'modified', + oldMarks: [ + { type: 'commentMark', attrs: { commentId: 'a' } }, + { type: 'commentMark', attrs: { commentId: 'b' } }, + ], + marksDiff: { + added: [], + deleted: [], + modified: [{ name: 'commentMark', oldAttrs: { commentId: 'b' }, newAttrs: { commentId: 'c' } }], + }, + }); + + expect(getMarkTypes(marks)).toEqual(['commentMark', 'commentMark']); + expect(marks.map((mark) => mark.attrs?.commentId)).toEqual(['a', 'c']); +}; + /** * Verifies modified text falls back to explicit marks when no marksDiff is provided. * @returns {void} @@ -96,6 +144,8 @@ const testDeletedMarks = () => { const runMarksFromDiffSuite = () => { it('builds marks for added text', testAddedMarks); it('applies marksDiff for modified text', testModifiedMarksFromDiff); + it('removes a specific duplicate same-type mark', testModifiedMarksWithDuplicateTypeDeletion); + it('replaces a specific duplicate same-type mark', testModifiedMarksWithDuplicateTypeReplacement); it('falls back to marks for modified text', testModifiedMarksFallback); it('returns no marks for deleted text', testDeletedMarks); }; diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts index eb2116520a..53e2da2be6 100644 --- a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts @@ -28,7 +28,7 @@ export function marksFromDiff({ if (action === 'modified') { if (marksDiff) { - const updatedMarks = applyMarksDiff(marksDiff); + const updatedMarks = applyMarksDiff(oldMarks, marksDiff); return buildMarksFromJSON(schema, updatedMarks); } if (marks.length > 0) { @@ -52,23 +52,39 @@ export function marksFromDiff({ * @returns Updated mark JSON entries. */ const applyMarksDiff = ( + existingMarks: Array<{ type: string; attrs?: Record }>, marksDiff: import('../algorithm/attributes-diffing.ts').MarksDiff, ): Array<{ type: string; attrs?: Record }> => { - const byType = new Map>(); + const updatedMarks = existingMarks.map((mark) => ({ + type: mark.type, + attrs: mark.attrs ?? {}, + })); marksDiff.deleted.forEach((mark) => { - byType.delete(mark.name); + const index = updatedMarks.findIndex( + (existing) => existing.type === mark.name && deepEquals(existing.attrs, mark.attrs), + ); + if (index >= 0) { + updatedMarks.splice(index, 1); + } }); marksDiff.modified.forEach((mark) => { - byType.set(mark.name, mark.newAttrs ?? {}); + const index = updatedMarks.findIndex( + (existing) => existing.type === mark.name && deepEquals(existing.attrs, mark.oldAttrs), + ); + if (index >= 0) { + updatedMarks.splice(index, 1, { type: mark.name, attrs: mark.newAttrs ?? {} }); + return; + } + updatedMarks.push({ type: mark.name, attrs: mark.newAttrs ?? {} }); }); marksDiff.added.forEach((mark) => { - byType.set(mark.name, mark.attrs ?? {}); + updatedMarks.push({ type: mark.name, attrs: mark.attrs ?? {} }); }); - return Array.from(byType.entries()).map(([type, attrs]) => ({ type, attrs })); + return updatedMarks; }; /** @@ -94,3 +110,14 @@ const buildMarksFromJSON = ( return resolvedMarks; }; + +/** + * Checks deep equality using JSON serialization for mark attrs payloads. + * + * @param left First attrs object. + * @param right Second attrs object. + * @returns True when both attrs payloads serialize identically. + */ +const deepEquals = (left: unknown, right: unknown): boolean => { + return JSON.stringify(left) === JSON.stringify(right); +}; diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index 3a824227e2..765303cffc 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -120,7 +120,7 @@ export function replayInlineDiff({ action: diff.action, marks: diff.marks, marksDiff: diff.marksDiff, - oldMarks: [], + oldMarks: getMarksAtPosition(tr.doc, from), }); marks.forEach((mark) => { const step = new AddMarkStep(from, to!, mark); @@ -143,6 +143,19 @@ export function replayInlineDiff({ skipWithWarning(`Failed to remove mark ${mark.type.name} at ${from}-${to}.`); } }); + (diff.marksDiff?.modified ?? []).forEach((markEntry) => { + const markType = schema.marks[markEntry.name]; + if (!markType) { + skipWithWarning(`Unknown mark type ${markEntry.name} for modification.`); + return; + } + const oldMark = markType.create(markEntry.oldAttrs || {}); + const step = new RemoveMarkStep(from, to!, oldMark); + const stepResult = tr.maybeStep(step); + if (stepResult.failed) { + skipWithWarning(`Failed to remove old mark ${oldMark.type.name} at ${from}-${to}.`); + } + }); if (diff.runAttrsDiff) { // Metadata attributes are independent of mark replay and can always be applied. @@ -348,3 +361,25 @@ const filterAttributesDiffByPath = ( const isDeepEqual = (left: unknown, right: unknown): boolean => { return JSON.stringify(left) === JSON.stringify(right); }; + +/** + * Extracts mark JSON entries from the inline node at a given position. + * + * @param doc Document to inspect. + * @param pos Position used to resolve an inline node. + * @returns Mark entries from the inline node at the position. + */ +const getMarksAtPosition = ( + doc: import('prosemirror-model').Node, + pos: number, +): Array<{ type: string; attrs?: Record }> => { + const resolved = doc.resolve(pos); + const candidate = resolved.nodeAfter || resolved.nodeBefore; + if (!candidate || !candidate.isInline) { + return []; + } + return candidate.marks.map((mark) => ({ + type: mark.type.name, + attrs: mark.attrs ?? {}, + })); +}; From ee9a775cc6f29e65b6eead1facb19bba3cf3fd31 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 15:01:03 -0300 Subject: [PATCH 085/125] fix(diffing): preserve multi-block comment body edits in modified comment diffs --- .../diffing/algorithm/comment-diffing.test.ts | 37 +++++++++++++++++++ .../diffing/algorithm/comment-diffing.ts | 30 +++++++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts index f85d524292..963748ad6d 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.test.ts @@ -50,6 +50,24 @@ const buildCommentElements = (text) => [ }, ]; +/** + * Builds a multi-paragraph DOCX-imported comment `elements` payload. + * + * @param {string} first First paragraph text. + * @param {string} second Second paragraph text. + * @returns {Array>} + */ +const buildMultiBlockCommentElements = (first, second) => [ + { + type: 'paragraph', + content: [{ type: 'text', text: first }], + }, + { + type: 'paragraph', + content: [{ type: 'text', text: second }], + }, +]; + /** * Returns the first token for convenience in tests. * @@ -334,6 +352,25 @@ describe('diffComments', () => { }); }); + it('returns modified diffs for multi-block elements text edits', () => { + const schema = createSchema(); + const diffs = diffComments( + [{ commentId: 'c-1', elements: buildMultiBlockCommentElements('First', 'Second old') }], + [{ commentId: 'c-1', elements: buildMultiBlockCommentElements('First', 'Second new') }], + schema, + ); + + expect(diffs).toHaveLength(1); + expect(diffs[0]).toMatchObject({ + action: 'modified', + nodeType: 'comment', + commentId: 'c-1', + oldText: 'FirstSecond old', + newText: 'FirstSecond new', + }); + expect(diffs[0].contentDiff).not.toEqual([]); + }); + it('returns empty diffs for identical comments', () => { const schema = createSchema(); const diffs = diffComments( diff --git a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts index 5ed64a24e3..6a793d3481 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/comment-diffing.ts @@ -1,5 +1,5 @@ import type { Schema } from 'prosemirror-model'; -import { diffNodes, type NodeDiff, type NodeInfo } from './generic-diffing'; +import { diffNodes, normalizeNodes, type NodeDiff, type NodeInfo } from './generic-diffing'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; import { createParagraphSnapshot, type ParagraphNodeInfo } from './paragraph-diffing'; import { diffSequences } from './sequence-diffing'; @@ -226,8 +226,7 @@ export function buildModifiedCommentDiff( oldComment: CommentToken, newComment: CommentToken, ): CommentModifiedDiff | null { - const contentDiff = - oldComment.content && newComment.content ? diffNodes([oldComment.content], [newComment.content]) : []; + const contentDiff = buildCommentContentDiff(oldComment.content, newComment.content); const attrsDiff = getAttributesDiff(oldComment.commentJSON, newComment.commentJSON, COMMENT_ATTRS_DIFF_IGNORED_KEYS); if (contentDiff.length === 0 && !attrsDiff) { @@ -247,6 +246,31 @@ export function buildModifiedCommentDiff( }; } +/** + * Diffs comment body content with support for both paragraph and doc-root bodies. + * + * Multi-block comment bodies are represented as `doc` nodes (from `elements`). + * Diffing those via `diffNodes([doc],[doc])` only checks doc attrs and misses + * child content edits, so we diff normalized descendants instead. + * + * @param oldContent Parsed old comment body. + * @param newContent Parsed new comment body. + * @returns Node-level content diff payload. + */ +function buildCommentContentDiff(oldContent: NodeInfo | null, newContent: NodeInfo | null): NodeDiff[] { + if (!oldContent || !newContent) { + return []; + } + + if (oldContent.node.type.name === 'doc' && newContent.node.type.name === 'doc') { + const oldNodes = normalizeNodes(oldContent.node); + const newNodes = normalizeNodes(newContent.node); + return diffNodes(oldNodes, newNodes); + } + + return diffNodes([oldContent], [newContent]); +} + /** * Resolves a stable comment identifier from a comment payload. * From a7529fe012de79c49bb0fd12464f5bbb77615bf2 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 15:28:27 -0300 Subject: [PATCH 086/125] fix(diffing): allow replayDifferences to be called without options --- .../src/extensions/diffing/diffing.js | 4 +-- .../extensions/diffing/replayDiffs.test.js | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index e1ca4173d2..9172ec6ce9 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -37,11 +37,11 @@ export const Diffing = Extension.create({ * Replays a diff result onto the current document as tracked changes. * * @param {import('./computeDiff.ts').DiffResult} diff - * @param {{ applyTrackedChanges?: boolean }} options + * @param {{ applyTrackedChanges?: boolean }} [options] * @returns {import('prosemirror-state').Transaction} */ replayDifferences: - (diff, { applyTrackedChanges = true }) => + (diff, { applyTrackedChanges = true } = {}) => ({ state, dispatch }) => { const comments = this.editor.converter ? Array.isArray(this.editor.converter.comments) diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 00f6ea2372..2cc9a92885 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -91,6 +91,29 @@ const expectReplayMatchesFixture = async (beforeName, afterName) => { } }; +/** + * Replays diffs without providing replay options and asserts it does not throw. + * + * @param {string} beforeName DOCX fixture filename for the baseline. + * @param {string} afterName DOCX fixture filename for the updated doc. + * @returns {Promise} + */ +const expectReplayMatchesFixtureWithDefaultOptions = async (beforeName, afterName) => { + const beforeEditor = await getEditorFromFixture(beforeName); + const afterEditor = await getEditorFromFixture(afterName); + + try { + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const success = beforeEditor.commands.replayDifferences(diff); + + expect(success).toBe(true); + expect(beforeEditor.state.doc.textContent).toBe(afterEditor.state.doc.textContent); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } +}; + /** * Replays diffs with tracked changes enabled and verifies acceptance matches the updated fixture. * @param {string} beforeName DOCX fixture filename for the baseline. @@ -212,6 +235,11 @@ const runTrackedReplayDiffsSuite = () => { }; describe('replayDiffs', runReplayDiffsSuite); +describe('replayDifferences options', () => { + it('accepts omitted options object', async () => { + await expectReplayMatchesFixtureWithDefaultOptions('diff_before.docx', 'diff_after.docx'); + }); +}); describe('replayDiffs tracked changes', runTrackedReplayDiffsSuite); describe('replayDiffs tracked-change ids', () => { it('keeps tracked mark ids populated for diff_before8 replay', async () => { From c033d21b294ab94a804d5ac7d6a4b6037aeee1b1 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 15:32:51 -0300 Subject: [PATCH 087/125] fix(diffing): make replayDifferences side-effect free in can() checks --- .../src/extensions/diffing/diffing.js | 4 +++ .../extensions/diffing/replayDiffs.test.js | 36 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 9172ec6ce9..6de803f473 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -43,6 +43,10 @@ export const Diffing = Extension.create({ replayDifferences: (diff, { applyTrackedChanges = true } = {}) => ({ state, dispatch }) => { + if (!dispatch) { + return true; + } + const comments = this.editor.converter ? Array.isArray(this.editor.converter.comments) ? this.editor.converter.comments diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 2cc9a92885..45b4d8a552 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { Editor } from '@core/Editor.js'; import { getStarterExtensions } from '@extensions/index.js'; @@ -114,6 +114,35 @@ const expectReplayMatchesFixtureWithDefaultOptions = async (beforeName, afterNam } }; +/** + * Ensures `editor.can().replayDifferences(...)` is side-effect free. + * + * @param {string} beforeName DOCX fixture filename for the baseline. + * @param {string} afterName DOCX fixture filename for the updated doc. + * @returns {Promise} + */ +const expectReplayCanHasNoSideEffects = async (beforeName, afterName) => { + const beforeEditor = await getEditorFromFixture(beforeName); + const afterEditor = await getEditorFromFixture(afterName); + + try { + const originalDocJSON = beforeEditor.state.doc.toJSON(); + const originalCommentsJSON = JSON.parse(JSON.stringify(beforeEditor.converter?.comments ?? [])); + const emitSpy = vi.spyOn(beforeEditor, 'emit'); + + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const canReplay = beforeEditor.can().replayDifferences(diff); + + expect(canReplay).toBe(true); + expect(beforeEditor.state.doc.toJSON()).toEqual(originalDocJSON); + expect(beforeEditor.converter?.comments ?? []).toEqual(originalCommentsJSON); + expect(emitSpy).not.toHaveBeenCalledWith('commentsUpdate', { type: 'replayCompleted' }); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } +}; + /** * Replays diffs with tracked changes enabled and verifies acceptance matches the updated fixture. * @param {string} beforeName DOCX fixture filename for the baseline. @@ -240,6 +269,11 @@ describe('replayDifferences options', () => { await expectReplayMatchesFixtureWithDefaultOptions('diff_before.docx', 'diff_after.docx'); }); }); +describe('replayDifferences can()', () => { + it('does not replay or emit when evaluated through can()', async () => { + await expectReplayCanHasNoSideEffects('diff_before8.docx', 'diff_after8.docx'); + }); +}); describe('replayDiffs tracked changes', runTrackedReplayDiffsSuite); describe('replayDiffs tracked-change ids', () => { it('keeps tracked mark ids populated for diff_before8 replay', async () => { From e85bd04a55e2a4519eafc225f9e74f5bb562d500 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 15:35:51 -0300 Subject: [PATCH 088/125] fix(superdoc): clear active reply when replay deletion removes parent thread --- packages/superdoc/src/SuperDoc.test.js | 23 +++++++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 9 ++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 09a9d0b182..9e0a41ba69 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -492,6 +492,29 @@ describe('SuperDoc.vue', () => { }); }); + it('clears active comment when replay deletion removes the active reply', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + commentsStoreStub.commentsList.value = [ + { commentId: 'c-1', commentText: 'Parent' }, + { commentId: 'c-2', parentCommentId: 'c-1', commentText: 'Reply' }, + ]; + commentsStoreStub.activeComment.value = 'c-2'; + commentsStoreStub.setActiveComment.mockClear(); + + options.onCommentsUpdate({ + type: 'deleted', + comment: { commentId: 'c-1' }, + }); + + expect(commentsStoreStub.commentsList.value).toEqual([]); + await nextTick(); + expect(commentsStoreStub.setActiveComment).toHaveBeenCalledWith(superdocStub, null); + }); + it('passes slash menu and context menu options through to SuperEditor', async () => { const superdocStub = createSuperdocStub(); const slashMenuConfig = { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index dba81abb64..2d361269a2 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -726,16 +726,23 @@ const onEditorCommentsUpdate = (params = {}) => { const id = resolveCommentEventId(commentPayload); if (id) { const targetId = String(id); + const removedCommentIds = new Set(); commentsList.value = commentsList.value.filter((comment) => { const commentId = comment.commentId != null ? String(comment.commentId) : null; const importedId = comment.importedId != null ? String(comment.importedId) : null; const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; const isDeletedComment = commentId === targetId || importedId === targetId; const isReplyToDeletedComment = parentCommentId === targetId; + + if (isDeletedComment || isReplyToDeletedComment) { + if (commentId) removedCommentIds.add(commentId); + if (importedId) removedCommentIds.add(importedId); + } return !isDeletedComment && !isReplyToDeletedComment; }); - if (activeComment.value != null && String(activeComment.value) === targetId) { + const activeCommentKey = activeComment.value != null ? String(activeComment.value) : null; + if (activeCommentKey && (activeCommentKey === targetId || removedCommentIds.has(activeCommentKey))) { activeCommentId = null; } } From dbc10656881e7bfb16a0231cb28767c1a0813a62 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 15:59:26 -0300 Subject: [PATCH 089/125] fix(diffing): match inline node types by name across editor schemas --- .../src/extensions/diffing/algorithm/inline-diffing.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts index 6dc81cb897..53adf8ba04 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/inline-diffing.ts @@ -232,7 +232,7 @@ export function getInlineDiff( comparator: inlineComparator, shouldProcessEqualAsModification, canTreatAsModification: (oldToken, newToken) => - isInlineNodeToken(oldToken) && isInlineNodeToken(newToken) && oldToken.node.type === newToken.node.type, + isInlineNodeToken(oldToken) && isInlineNodeToken(newToken) && oldToken.node.type.name === newToken.node.type.name, buildAdded: (token, oldIdx) => buildInlineDiff('added', token, oldIdx), buildDeleted: (token, oldIdx) => buildInlineDiff('deleted', token, oldIdx), buildModified: (oldToken, newToken, oldIdx) => { @@ -281,7 +281,7 @@ function inlineComparator(a: InlineDiffToken, b: InlineDiffToken): boolean { return a.char === b.char; } if (a.kind === 'inlineNode' && b.kind === 'inlineNode') { - return a.node.type === b.node.type; + return a.node.type.name === b.node.type.name; } return false; } From eeaca1f03a70a7b9708de50bff0c53959e827cfa Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 16:17:56 -0300 Subject: [PATCH 090/125] fix(superdoc): always flush replay tracked-change sync even with no comment positions --- packages/superdoc/src/SuperDoc.test.js | 8 ++- packages/superdoc/src/SuperDoc.vue | 16 +++-- .../superdoc/src/stores/comments-store.js | 72 ++++++++++++++++++- .../src/stores/comments-store.test.js | 61 ++++++++++++++++ 4 files changed, 145 insertions(+), 12 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 9e0a41ba69..d20e06327c 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -483,13 +483,15 @@ describe('SuperDoc.vue', () => { ]); options.onCommentsUpdate({ type: 'replayCompleted' }); - expect(commentsStoreStub.syncTrackedChangeComments).not.toHaveBeenCalled(); - - options.onCommentLocationsUpdate({ allCommentPositions: { 'tc-new': { start: 1, end: 2 } } }); + await nextTick(); expect(commentsStoreStub.syncTrackedChangeComments).toHaveBeenCalledWith({ superdoc: superdocStub, editor: superdocStub.activeEditor, }); + commentsStoreStub.syncTrackedChangeComments.mockClear(); + + options.onCommentLocationsUpdate({ allCommentPositions: { 'tc-new': { start: 1, end: 2 } } }); + expect(commentsStoreStub.syncTrackedChangeComments).not.toHaveBeenCalled(); }); it('clears active comment when replay deletion removes the active reply', async () => { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 2d361269a2..d6c8aeb55c 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -191,12 +191,16 @@ const scheduleReplayTrackedChangeSync = () => { const activeDocId = proxy.$superdoc?.activeEditor?.options?.documentId; const hasPresentationBridge = Boolean(activeDocId && PresentationEditor.getInstance(activeDocId) && layers.value); - // Headless/non-layout fallback: there is no comment-position stream to wait for. - if (!hasPresentationBridge || !shouldRenderCommentsInViewing.value) { - nextTick(() => { - flushPendingReplayTrackedChangeSync(); - }); - } + // Always schedule a fallback flush. In layout mode, replay can remove the last + // comment/tracked-change anchor, which means no commentPositions event is emitted. + // Without this fallback, pending replay sync can stay stuck forever. + nextTick(() => { + flushPendingReplayTrackedChangeSync(); + }); + + // In layout mode we still flush on comment-position updates when they arrive. + // For non-layout/viewing-hidden cases, the nextTick fallback above is the primary path. + if (!hasPresentationBridge || !shouldRenderCommentsInViewing.value) return; }; const handleDocumentReady = (documentId, container) => { diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index f8f87d4259..fec28f1eaf 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -917,8 +917,8 @@ export const useCommentsStore = defineStore('comments', () => { }, 0); }; - const createCommentForTrackChanges = (editor, superdoc) => { - const trackedChanges = trackChangesHelpers.getTrackChanges(editor.state); + const createCommentForTrackChanges = (editor, superdoc, trackedChangesOverride = null) => { + const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editor.state); const groupedChanges = groupChanges(trackedChanges); // Build a Set of existing comment IDs for O(1) lookup @@ -969,6 +969,62 @@ export const useCommentsStore = defineStore('comments', () => { editor.view.dispatch(tr); }; + /** + * Remove tracked-change comments that no longer have a corresponding mark in the editor. + * Also removes any replies linked to those removed tracked-change threads. + * + * @param {Set} liveTrackedChangeIds IDs currently present in editor marks. + * @returns {void} + */ + const pruneStaleTrackedChangeComments = (liveTrackedChangeIds) => { + if (!(liveTrackedChangeIds instanceof Set)) return; + + const removedIds = new Set(); + + commentsList.value = commentsList.value.filter((comment) => { + if (!comment?.trackedChange) return true; + + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + const primaryId = commentId ?? importedId; + + if (!primaryId || liveTrackedChangeIds.has(primaryId)) return true; + + if (commentId) removedIds.add(commentId); + if (importedId) removedIds.add(importedId); + return false; + }); + + if (!removedIds.size) return; + + let didRemoveDescendants = true; + while (didRemoveDescendants) { + didRemoveDescendants = false; + commentsList.value = commentsList.value.filter((comment) => { + const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; + const trackedChangeParentId = + comment.trackedChangeParentId != null ? String(comment.trackedChangeParentId) : null; + const isLinkedToRemovedParent = + (parentCommentId && removedIds.has(parentCommentId)) || + (trackedChangeParentId && removedIds.has(trackedChangeParentId)); + + if (!isLinkedToRemovedParent) return true; + + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + if (commentId) removedIds.add(commentId); + if (importedId) removedIds.add(importedId); + didRemoveDescendants = true; + return false; + }); + } + + const activeCommentId = activeComment.value != null ? String(activeComment.value) : null; + if (activeCommentId && removedIds.has(activeCommentId)) { + activeComment.value = null; + } + }; + /** * Rebuild tracked-change comments from the current editor state. * @@ -982,7 +1038,17 @@ export const useCommentsStore = defineStore('comments', () => { */ const syncTrackedChangeComments = ({ superdoc, editor }) => { if (!superdoc || !editor) return; - createCommentForTrackChanges(editor, superdoc); + + const trackedChanges = trackChangesHelpers.getTrackChanges(editor.state); + const liveTrackedChangeIds = new Set(); + trackedChanges.forEach((change) => { + const id = change?.mark?.attrs?.id; + if (id == null) return; + liveTrackedChangeIds.add(String(id)); + }); + + pruneStaleTrackedChangeComments(liveTrackedChangeIds); + createCommentForTrackChanges(editor, superdoc, trackedChanges); }; const normalizeDocxSchemaForExport = (value) => { diff --git a/packages/superdoc/src/stores/comments-store.test.js b/packages/superdoc/src/stores/comments-store.test.js index 2e42a1b4a9..73294843ec 100644 --- a/packages/superdoc/src/stores/comments-store.test.js +++ b/packages/superdoc/src/stores/comments-store.test.js @@ -87,10 +87,14 @@ import { comments_module_events } from '@superdoc/common'; import useComment from '@superdoc/components/CommentsLayer/use-comment'; import { syncCommentsToClients } from '../core/collaboration/helpers.js'; import { trackChangesHelpers } from '@superdoc/super-editor'; +import { groupChanges } from '../helpers/group-changes.js'; +import { trackChangesHelpers } from '@superdoc/super-editor'; const useCommentMock = useComment; const syncCommentsToClientsMock = syncCommentsToClients; const getTrackChangesMock = trackChangesHelpers.getTrackChanges; +const groupChangesMock = groupChanges; +const trackChangesHelpersMock = trackChangesHelpers; describe('comments-store', () => { let store; @@ -101,6 +105,8 @@ describe('comments-store', () => { setActivePinia(createPinia()); store = useCommentsStore(); __mockSuperdoc.documents.value = [{ id: 'doc-1', type: 'docx' }]; + groupChangesMock.mockReturnValue([]); + trackChangesHelpersMock.getTrackChanges.mockReturnValue([]); }); afterEach(() => { @@ -611,6 +617,61 @@ describe('comments-store', () => { }); }); + it('prunes stale tracked-change comments and descendants during replay sync', () => { + const editorDispatch = vi.fn(); + const tr = { setMeta: vi.fn() }; + const editor = { + state: {}, + view: { state: { tr }, dispatch: editorDispatch }, + options: { documentId: 'doc-1' }, + }; + + trackChangesHelpersMock.getTrackChanges.mockReturnValue([]); + groupChangesMock.mockReturnValue([]); + + store.commentsList = [ + { commentId: 'tc-stale', trackedChange: true }, + { commentId: 'tc-reply', parentCommentId: 'tc-stale' }, + { commentId: 'tc-import-reply', trackedChangeParentId: 'tc-stale' }, + { commentId: 'normal-1', commentText: 'Regular comment' }, + ]; + store.activeComment = 'tc-reply'; + + store.syncTrackedChangeComments({ superdoc: {}, editor }); + + expect(store.commentsList).toEqual([{ commentId: 'normal-1', commentText: 'Regular comment' }]); + expect(store.activeComment).toBeNull(); + expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); + expect(editorDispatch).toHaveBeenCalledWith(tr); + }); + + it('keeps tracked-change comments whose IDs are still present in marks', () => { + const editorDispatch = vi.fn(); + const tr = { setMeta: vi.fn() }; + const editor = { + state: {}, + view: { state: { tr }, dispatch: editorDispatch }, + options: { documentId: 'doc-1' }, + }; + + trackChangesHelpersMock.getTrackChanges.mockReturnValue([{ mark: { attrs: { id: 'tc-live' } } }]); + groupChangesMock.mockReturnValue([{ insertedMark: { mark: { attrs: { id: 'tc-live' } } } }]); + + store.commentsList = [ + { commentId: 'tc-live', trackedChange: true, trackedChangeText: 'Existing' }, + { commentId: 'normal-1', commentText: 'Regular comment' }, + ]; + + store.syncTrackedChangeComments({ superdoc: {}, editor }); + + expect(store.commentsList).toEqual([ + { commentId: 'tc-live', trackedChange: true, trackedChangeText: 'Existing' }, + { commentId: 'normal-1', commentText: 'Regular comment' }, + ]); + expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); + expect(editorDispatch).toHaveBeenCalledWith(tr); + }); + it('should load comments with correct created time', () => { store.init({ readOnly: true, From 29e930ed827bc84ab4f6a6180a9c3f98a601b3c4 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 16:26:41 -0300 Subject: [PATCH 091/125] fix(superdoc): delete full comment subtree on replay thread removal --- packages/superdoc/src/SuperDoc.test.js | 30 ++++++++++++++++++-- packages/superdoc/src/SuperDoc.vue | 39 +++++++++++++++++++------- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index d20e06327c..f42e28e99d 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -478,9 +478,7 @@ describe('SuperDoc.vue', () => { type: 'deleted', comment: { commentId: 'c-1' }, }); - expect(commentsStoreStub.commentsList.value).toEqual([ - { commentId: 'tc-child', trackedChangeParentId: 'c-1', commentText: 'Tracked thread comment' }, - ]); + expect(commentsStoreStub.commentsList.value).toEqual([]); options.onCommentsUpdate({ type: 'replayCompleted' }); await nextTick(); @@ -517,6 +515,32 @@ describe('SuperDoc.vue', () => { expect(commentsStoreStub.setActiveComment).toHaveBeenCalledWith(superdocStub, null); }); + it('removes full reply subtree when replay deletion removes a parent comment', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + commentsStoreStub.commentsList.value = [ + { commentId: 'c-1', commentText: 'Parent' }, + { commentId: 'c-2', parentCommentId: 'c-1', commentText: 'Child' }, + { commentId: 'c-3', parentCommentId: 'c-2', commentText: 'Grandchild' }, + { commentId: 'c-4', trackedChangeParentId: 'c-3', commentText: 'Tracked descendant' }, + { commentId: 'c-99', commentText: 'Unrelated' }, + ]; + commentsStoreStub.activeComment.value = 'c-3'; + commentsStoreStub.setActiveComment.mockClear(); + + options.onCommentsUpdate({ + type: 'deleted', + comment: { commentId: 'c-1' }, + }); + + expect(commentsStoreStub.commentsList.value).toEqual([{ commentId: 'c-99', commentText: 'Unrelated' }]); + await nextTick(); + expect(commentsStoreStub.setActiveComment).toHaveBeenCalledWith(superdocStub, null); + }); + it('passes slash menu and context menu options through to SuperEditor', async () => { const superdocStub = createSuperdocStub(); const slashMenuConfig = { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index d6c8aeb55c..bb6382af58 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -730,19 +730,38 @@ const onEditorCommentsUpdate = (params = {}) => { const id = resolveCommentEventId(commentPayload); if (id) { const targetId = String(id); - const removedCommentIds = new Set(); + // Remove the entire thread subtree (parent + all descendants), not only direct replies. + const removedCommentIds = new Set([targetId]); + let expanded = true; + while (expanded) { + expanded = false; + commentsList.value.forEach((comment) => { + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; + const trackedChangeParentId = + comment.trackedChangeParentId != null ? String(comment.trackedChangeParentId) : null; + + const isRemovedComment = + (commentId && removedCommentIds.has(commentId)) || (importedId && removedCommentIds.has(importedId)); + const isDescendantOfRemovedComment = + (parentCommentId && removedCommentIds.has(parentCommentId)) || + (trackedChangeParentId && removedCommentIds.has(trackedChangeParentId)); + if (!isRemovedComment && !isDescendantOfRemovedComment) return; + + const sizeBefore = removedCommentIds.size; + if (commentId) removedCommentIds.add(commentId); + if (importedId) removedCommentIds.add(importedId); + if (removedCommentIds.size > sizeBefore) { + expanded = true; + } + }); + } + commentsList.value = commentsList.value.filter((comment) => { const commentId = comment.commentId != null ? String(comment.commentId) : null; const importedId = comment.importedId != null ? String(comment.importedId) : null; - const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; - const isDeletedComment = commentId === targetId || importedId === targetId; - const isReplyToDeletedComment = parentCommentId === targetId; - - if (isDeletedComment || isReplyToDeletedComment) { - if (commentId) removedCommentIds.add(commentId); - if (importedId) removedCommentIds.add(importedId); - } - return !isDeletedComment && !isReplyToDeletedComment; + return !((commentId && removedCommentIds.has(commentId)) || (importedId && removedCommentIds.has(importedId))); }); const activeCommentKey = activeComment.value != null ? String(activeComment.value) : null; From 19adaa339a5e43ea0074892c3ee91942eca0b6d0 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 17:09:46 -0300 Subject: [PATCH 092/125] fix(diffing): preserve existing comments when compareDocuments omits updatedComments --- .../src/extensions/diffing/diffing.js | 12 ++++------- .../extensions/diffing/replayDiffs.test.js | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 6de803f473..b287c0842f 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -21,15 +21,11 @@ export const Diffing = Extension.create({ * @returns {import('./computeDiff.ts').DiffResult} */ compareDocuments: - (updatedDocument, updatedComments = []) => + (updatedDocument, updatedComments) => ({ state }) => { - const diffs = computeDiff( - state.doc, - updatedDocument, - state.schema, - this.editor.converter?.comments ?? [], - updatedComments, - ); + const currentComments = this.editor.converter?.comments ?? []; + const nextComments = updatedComments === undefined ? currentComments : updatedComments; + const diffs = computeDiff(state.doc, updatedDocument, state.schema, currentComments, nextComments); return diffs; }, diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 45b4d8a552..768f7c874c 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -269,6 +269,26 @@ describe('replayDifferences options', () => { await expectReplayMatchesFixtureWithDefaultOptions('diff_before.docx', 'diff_after.docx'); }); }); +describe('compareDocuments defaults', () => { + it('does not emit comment delete diffs when updatedComments is omitted', async () => { + const beforeEditor = await getEditorFromFixture('diff_before8.docx'); + const afterEditor = await getEditorFromFixture('diff_after8.docx'); + + try { + const omittedCommentsDiff = beforeEditor.commands.compareDocuments(afterEditor.state.doc); + expect(omittedCommentsDiff.commentDiffs).toHaveLength(0); + + const explicitCommentsDiff = beforeEditor.commands.compareDocuments( + afterEditor.state.doc, + afterEditor.converter?.comments ?? [], + ); + expect(explicitCommentsDiff.commentDiffs.length).toBeGreaterThan(0); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } + }); +}); describe('replayDifferences can()', () => { it('does not replay or emit when evaluated through can()', async () => { await expectReplayCanHasNoSideEffects('diff_before8.docx', 'diff_after8.docx'); From 876c46ec37b60767725bf11cb0f9cb729f5e6bb7 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 17:19:05 -0300 Subject: [PATCH 093/125] fix(comments-store): scope tracked-change stale pruning to active document --- .../superdoc/src/stores/comments-store.js | 53 ++++++++++++++++-- .../src/stores/comments-store.test.js | 54 +++++++++++++++---- 2 files changed, 94 insertions(+), 13 deletions(-) diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index fec28f1eaf..710a05ff4e 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -969,20 +969,53 @@ export const useCommentsStore = defineStore('comments', () => { editor.view.dispatch(tr); }; + const getCommentDocumentId = (comment) => { + if (!comment) return null; + if (comment.fileId != null) return String(comment.fileId); + if (comment.documentId != null) return String(comment.documentId); + if (comment.selection?.documentId != null) return String(comment.selection.documentId); + return null; + }; + + const belongsToDocument = (comment, activeDocumentId) => { + if (!activeDocumentId) return false; + + const commentDocumentId = getCommentDocumentId(comment); + if (commentDocumentId) { + return commentDocumentId === activeDocumentId; + } + + // Legacy fallback: in single-document sessions, comments may not carry explicit + // document metadata yet. Treat them as belonging to the only open document. + const docs = Array.isArray(superdocStore.documents) ? superdocStore.documents : superdocStore.documents?.value; + if (Array.isArray(docs) && docs.length === 1) { + const onlyDocumentId = docs[0]?.id != null ? String(docs[0].id) : null; + return onlyDocumentId === activeDocumentId; + } + + return false; + }; + /** * Remove tracked-change comments that no longer have a corresponding mark in the editor. * Also removes any replies linked to those removed tracked-change threads. * + * Pruning is scoped to the active editor document so replay in one document does not + * delete tracked-change comments from other open documents. + * * @param {Set} liveTrackedChangeIds IDs currently present in editor marks. + * @param {string | null} activeDocumentId Document currently being synced. * @returns {void} */ - const pruneStaleTrackedChangeComments = (liveTrackedChangeIds) => { - if (!(liveTrackedChangeIds instanceof Set)) return; + const pruneStaleTrackedChangeComments = (liveTrackedChangeIds, activeDocumentId) => { + if (!(liveTrackedChangeIds instanceof Set) || !activeDocumentId) return; const removedIds = new Set(); + const previousComments = [...commentsList.value]; commentsList.value = commentsList.value.filter((comment) => { if (!comment?.trackedChange) return true; + if (!belongsToDocument(comment, activeDocumentId)) return true; const commentId = comment.commentId != null ? String(comment.commentId) : null; const importedId = comment.importedId != null ? String(comment.importedId) : null; @@ -1001,6 +1034,8 @@ export const useCommentsStore = defineStore('comments', () => { while (didRemoveDescendants) { didRemoveDescendants = false; commentsList.value = commentsList.value.filter((comment) => { + if (!belongsToDocument(comment, activeDocumentId)) return true; + const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; const trackedChangeParentId = comment.trackedChangeParentId != null ? String(comment.trackedChangeParentId) : null; @@ -1020,7 +1055,15 @@ export const useCommentsStore = defineStore('comments', () => { } const activeCommentId = activeComment.value != null ? String(activeComment.value) : null; - if (activeCommentId && removedIds.has(activeCommentId)) { + const activeCommentBelongsToActiveDocument = previousComments.some((comment) => { + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + return ( + belongsToDocument(comment, activeDocumentId) && + ((commentId && commentId === activeCommentId) || (importedId && importedId === activeCommentId)) + ); + }); + if (activeCommentId && removedIds.has(activeCommentId) && activeCommentBelongsToActiveDocument) { activeComment.value = null; } }; @@ -1038,6 +1081,8 @@ export const useCommentsStore = defineStore('comments', () => { */ const syncTrackedChangeComments = ({ superdoc, editor }) => { if (!superdoc || !editor) return; + const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null; + if (!activeDocumentId) return; const trackedChanges = trackChangesHelpers.getTrackChanges(editor.state); const liveTrackedChangeIds = new Set(); @@ -1047,7 +1092,7 @@ export const useCommentsStore = defineStore('comments', () => { liveTrackedChangeIds.add(String(id)); }); - pruneStaleTrackedChangeComments(liveTrackedChangeIds); + pruneStaleTrackedChangeComments(liveTrackedChangeIds, activeDocumentId); createCommentForTrackChanges(editor, superdoc, trackedChanges); }; diff --git a/packages/superdoc/src/stores/comments-store.test.js b/packages/superdoc/src/stores/comments-store.test.js index 73294843ec..31e4887667 100644 --- a/packages/superdoc/src/stores/comments-store.test.js +++ b/packages/superdoc/src/stores/comments-store.test.js @@ -630,16 +630,16 @@ describe('comments-store', () => { groupChangesMock.mockReturnValue([]); store.commentsList = [ - { commentId: 'tc-stale', trackedChange: true }, - { commentId: 'tc-reply', parentCommentId: 'tc-stale' }, - { commentId: 'tc-import-reply', trackedChangeParentId: 'tc-stale' }, - { commentId: 'normal-1', commentText: 'Regular comment' }, + { commentId: 'tc-stale', trackedChange: true, fileId: 'doc-1' }, + { commentId: 'tc-reply', parentCommentId: 'tc-stale', fileId: 'doc-1' }, + { commentId: 'tc-import-reply', trackedChangeParentId: 'tc-stale', fileId: 'doc-1' }, + { commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }, ]; store.activeComment = 'tc-reply'; store.syncTrackedChangeComments({ superdoc: {}, editor }); - expect(store.commentsList).toEqual([{ commentId: 'normal-1', commentText: 'Regular comment' }]); + expect(store.commentsList).toEqual([{ commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }]); expect(store.activeComment).toBeNull(); expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); expect(editorDispatch).toHaveBeenCalledWith(tr); @@ -658,20 +658,56 @@ describe('comments-store', () => { groupChangesMock.mockReturnValue([{ insertedMark: { mark: { attrs: { id: 'tc-live' } } } }]); store.commentsList = [ - { commentId: 'tc-live', trackedChange: true, trackedChangeText: 'Existing' }, - { commentId: 'normal-1', commentText: 'Regular comment' }, + { commentId: 'tc-live', trackedChange: true, trackedChangeText: 'Existing', fileId: 'doc-1' }, + { commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }, ]; store.syncTrackedChangeComments({ superdoc: {}, editor }); expect(store.commentsList).toEqual([ - { commentId: 'tc-live', trackedChange: true, trackedChangeText: 'Existing' }, - { commentId: 'normal-1', commentText: 'Regular comment' }, + { commentId: 'tc-live', trackedChange: true, trackedChangeText: 'Existing', fileId: 'doc-1' }, + { commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }, ]); expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); expect(editorDispatch).toHaveBeenCalledWith(tr); }); + it('does not prune tracked-change comments from other documents during sync', () => { + const editorDispatch = vi.fn(); + const tr = { setMeta: vi.fn() }; + const editor = { + state: {}, + view: { state: { tr }, dispatch: editorDispatch }, + options: { documentId: 'doc-1' }, + }; + + __mockSuperdoc.documents.value = [ + { id: 'doc-1', type: 'docx' }, + { id: 'doc-2', type: 'docx' }, + ]; + + trackChangesHelpersMock.getTrackChanges.mockReturnValue([]); + groupChangesMock.mockReturnValue([]); + + store.commentsList = [ + { commentId: 'tc-stale-1', trackedChange: true, fileId: 'doc-1' }, + { commentId: 'tc-child-1', parentCommentId: 'tc-stale-1', fileId: 'doc-1' }, + { commentId: 'tc-stale-2', trackedChange: true, fileId: 'doc-2' }, + { commentId: 'tc-child-2', parentCommentId: 'tc-stale-2', fileId: 'doc-2' }, + ]; + store.activeComment = 'tc-child-2'; + + store.syncTrackedChangeComments({ superdoc: {}, editor }); + + expect(store.commentsList).toEqual([ + { commentId: 'tc-stale-2', trackedChange: true, fileId: 'doc-2' }, + { commentId: 'tc-child-2', parentCommentId: 'tc-stale-2', fileId: 'doc-2' }, + ]); + expect(store.activeComment).toBe('tc-child-2'); + expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); + expect(editorDispatch).toHaveBeenCalledWith(tr); + }); + it('should load comments with correct created time', () => { store.init({ readOnly: true, From 12275213bca3bc0f18d31f6594a20292eeecf364 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 17:42:40 -0300 Subject: [PATCH 094/125] fix(diffing): reuse transaction --- packages/super-editor/src/extensions/diffing/diffing.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index b287c0842f..aef38e1db9 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -48,22 +48,23 @@ export const Diffing = Extension.create({ ? this.editor.converter.comments : (this.editor.converter.comments = []) : []; + const tr = state.tr; const canApplyTrackedChanges = applyTrackedChanges && Boolean(this.editor.options.user); replayDiffs({ - tr: state.tr, + tr, diff, schema: state.schema, comments, editor: this.editor, }); if (canApplyTrackedChanges) { - state.tr.setMeta('forceTrackChanges', true); + tr.setMeta('forceTrackChanges', true); } - if (dispatch && state.tr.docChanged) { - dispatch(state.tr); + if (dispatch && tr.docChanged) { + dispatch(tr); } this.editor.emit('commentsUpdate', { type: 'replayCompleted' }); From 6bbe9c9bdc5a5464fe94bbcb4a7556f46a748244 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 17:44:21 -0300 Subject: [PATCH 095/125] fix(superdoc): match replay comment updates by importedId before commentId - prefer importedId when resolving existing comments for COMMENT_EVENTS.UPDATE - fall back to commentId only if imported-id lookup misses - prevent duplicate comment creation when replay updates carry a new runtime commentId for an existing imported thread - add regression test covering update reconciliation with stable importedId and changed commentId --- packages/superdoc/src/SuperDoc.test.js | 33 ++++++++++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 19 +++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index f42e28e99d..565d9c7e4b 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -492,6 +492,39 @@ describe('SuperDoc.vue', () => { expect(commentsStoreStub.syncTrackedChangeComments).not.toHaveBeenCalled(); }); + it('reconciles replay updates by importedId before commentId to avoid duplicate comments', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + const existingComment = { commentId: 'old-runtime-id', importedId: 'imp-1', commentText: 'Old text' }; + + commentsStoreStub.commentsList.value = [existingComment]; + commentsStoreStub.getComment.mockClear(); + commentsStoreStub.getComment.mockImplementation((id) => { + if (id === 'imp-1' || id === 'old-runtime-id') return existingComment; + return null; + }); + commentsStoreStub.addComment.mockClear(); + + options.onCommentsUpdate({ + type: 'update', + comment: { + commentId: 'new-runtime-id', + importedId: 'imp-1', + commentText: 'Updated text', + }, + }); + + expect(commentsStoreStub.getComment.mock.calls).toEqual([['imp-1']]); + expect(commentsStoreStub.addComment).not.toHaveBeenCalled(); + expect(commentsStoreStub.commentsList.value).toHaveLength(1); + expect(existingComment.commentId).toBe('new-runtime-id'); + expect(existingComment.importedId).toBe('imp-1'); + expect(existingComment.commentText).toBe('Updated text'); + }); + it('clears active comment when replay deletion removes the active reply', async () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index bb6382af58..5780ec0f2e 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -662,6 +662,22 @@ const onEditorCommentsUpdate = (params = {}) => { // Set the active comment in the store let { activeCommentId, type, comment: commentPayload } = params; const resolveCommentEventId = (payload) => payload?.commentId || payload?.importedId || null; + const resolveUpdateCommentMatch = (payload) => { + const candidateIds = [payload?.importedId, payload?.commentId].filter(Boolean); + for (const candidateId of candidateIds) { + const existingComment = getComment(candidateId); + if (existingComment) { + return { + id: candidateId, + existingComment, + }; + } + } + return { + id: candidateIds[0] || null, + existingComment: null, + }; + }; if (type === 'replayCompleted') { scheduleReplayTrackedChangeSync(); @@ -701,9 +717,8 @@ const onEditorCommentsUpdate = (params = {}) => { } if (COMMENT_EVENTS?.UPDATE && type === COMMENT_EVENTS.UPDATE && commentPayload) { - const id = resolveCommentEventId(commentPayload); + const { id, existingComment } = resolveUpdateCommentMatch(commentPayload); if (id) { - const existingComment = getComment(id); const resolvedText = commentPayload.commentText || commentPayload.text; if (existingComment) { From 6dd7e5e007006e33ff0d914021af3194d051bbd6 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 17:57:48 -0300 Subject: [PATCH 096/125] fix(diffing): honor applyTrackedChanges=false by setting skipTrackChanges on replay - set skipTrackChanges meta in replayDifferences when tracked replay is disabled - keep forceTrackChanges behavior when tracked replay is enabled - prevent replay from generating tracked marks when track changes mode is already active - add regression test covering replay with active track changes and applyTrackedChanges: false --- .../src/extensions/diffing/diffing.js | 2 ++ .../extensions/diffing/replayDiffs.test.js | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index aef38e1db9..66201de8c8 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -61,6 +61,8 @@ export const Diffing = Extension.create({ }); if (canApplyTrackedChanges) { tr.setMeta('forceTrackChanges', true); + } else { + tr.setMeta('skipTrackChanges', true); } if (dispatch && tr.docChanged) { diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 768f7c874c..53f5b5abed 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -91,6 +91,34 @@ const expectReplayMatchesFixture = async (beforeName, afterName) => { } }; +/** + * Replays diffs with applyTrackedChanges disabled while track changes mode is active, + * asserting replay does not create tracked marks. + * + * @param {string} beforeName DOCX fixture filename for the baseline. + * @param {string} afterName DOCX fixture filename for the updated doc. + * @returns {Promise} + */ +const expectReplaySkipsTrackingWhenDisabled = async (beforeName, afterName) => { + const testUser = { name: 'Test User', email: 'test@example.com' }; + const beforeEditor = await getEditorFromFixture(beforeName, testUser); + const afterEditor = await getEditorFromFixture(afterName); + + try { + expect(beforeEditor.commands.enableTrackChanges()).toBe(true); + + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const success = beforeEditor.commands.replayDifferences(diff, { applyTrackedChanges: false }); + + expect(success).toBe(true); + expect(getTrackChanges(beforeEditor.state)).toHaveLength(0); + expect(beforeEditor.state.doc.textContent).toBe(afterEditor.state.doc.textContent); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } +}; + /** * Replays diffs without providing replay options and asserts it does not throw. * @@ -268,6 +296,10 @@ describe('replayDifferences options', () => { it('accepts omitted options object', async () => { await expectReplayMatchesFixtureWithDefaultOptions('diff_before.docx', 'diff_after.docx'); }); + + it('does not create tracked marks when applyTrackedChanges is false and track changes is active', async () => { + await expectReplaySkipsTrackingWhenDisabled('diff_before3.docx', 'diff_after3.docx'); + }); }); describe('compareDocuments defaults', () => { it('does not emit comment delete diffs when updatedComments is omitted', async () => { From f5fccdfb1cff7b8154a372eba3055ea3d3574c52 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 18:14:16 -0300 Subject: [PATCH 097/125] fix(superdoc): handle replay delete events with importedId-first identity fallback - resolve delete targets from both importedId and commentId (importedId prioritized) - seed subtree removal with all resolved ids to match re-keyed replay comments - keep active comment clearing aligned with the expanded removal set - add regression test for stale runtime commentId + stable importedId delete payloads to prevent orphaned sidebar threads --- packages/superdoc/src/SuperDoc.test.js | 24 ++++++++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 14 ++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 565d9c7e4b..418420baaf 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -525,6 +525,30 @@ describe('SuperDoc.vue', () => { expect(existingComment.commentText).toBe('Updated text'); }); + it('removes replay-deleted comments when payload commentId is stale but importedId matches', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + commentsStoreStub.commentsList.value = [ + { commentId: 'live-runtime-id', importedId: 'imp-1', commentText: 'Parent' }, + { commentId: 'child-1', parentCommentId: 'live-runtime-id', commentText: 'Reply' }, + { commentId: 'other', commentText: 'Unrelated' }, + ]; + commentsStoreStub.activeComment.value = 'child-1'; + commentsStoreStub.setActiveComment.mockClear(); + + options.onCommentsUpdate({ + type: 'deleted', + comment: { commentId: 'stale-runtime-id', importedId: 'imp-1' }, + }); + + expect(commentsStoreStub.commentsList.value).toEqual([{ commentId: 'other', commentText: 'Unrelated' }]); + await nextTick(); + expect(commentsStoreStub.setActiveComment).toHaveBeenCalledWith(superdocStub, null); + }); + it('clears active comment when replay deletion removes the active reply', async () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 5780ec0f2e..1b4250e088 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -661,7 +661,10 @@ const onEditorCommentLocationsUpdate = (doc, { allCommentIds: activeThreadId, al const onEditorCommentsUpdate = (params = {}) => { // Set the active comment in the store let { activeCommentId, type, comment: commentPayload } = params; - const resolveCommentEventId = (payload) => payload?.commentId || payload?.importedId || null; + const resolveCommentEventIds = (payload) => { + const ids = [payload?.importedId, payload?.commentId].filter(Boolean).map((value) => String(value)); + return [...new Set(ids)]; + }; const resolveUpdateCommentMatch = (payload) => { const candidateIds = [payload?.importedId, payload?.commentId].filter(Boolean); for (const candidateId of candidateIds) { @@ -742,11 +745,10 @@ const onEditorCommentsUpdate = (params = {}) => { } if (COMMENT_EVENTS?.DELETED && type === COMMENT_EVENTS.DELETED && commentPayload) { - const id = resolveCommentEventId(commentPayload); - if (id) { - const targetId = String(id); + const targetIds = resolveCommentEventIds(commentPayload); + if (targetIds.length) { // Remove the entire thread subtree (parent + all descendants), not only direct replies. - const removedCommentIds = new Set([targetId]); + const removedCommentIds = new Set(targetIds); let expanded = true; while (expanded) { expanded = false; @@ -780,7 +782,7 @@ const onEditorCommentsUpdate = (params = {}) => { }); const activeCommentKey = activeComment.value != null ? String(activeComment.value) : null; - if (activeCommentKey && (activeCommentKey === targetId || removedCommentIds.has(activeCommentKey))) { + if (activeCommentKey && removedCommentIds.has(activeCommentKey)) { activeCommentId = null; } } From 4e8fcdf32c217cf43253356ea2bcdf35dd0e1105 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 3 Mar 2026 18:17:29 -0300 Subject: [PATCH 098/125] fix(diffing): prevent compareDocuments from dispatching read-only transactions - set preventDispatch meta in compareDocuments so CommandService skips dispatch - keep compare behavior read-only with no transaction/update side effects - add regression assertions that compare calls do not emit transaction events (with omitted and explicit comments inputs) --- packages/super-editor/src/extensions/diffing/diffing.js | 3 ++- .../super-editor/src/extensions/diffing/replayDiffs.test.js | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 66201de8c8..6e6c065819 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -22,7 +22,8 @@ export const Diffing = Extension.create({ */ compareDocuments: (updatedDocument, updatedComments) => - ({ state }) => { + ({ state, tr }) => { + tr.setMeta('preventDispatch', true); const currentComments = this.editor.converter?.comments ?? []; const nextComments = updatedComments === undefined ? currentComments : updatedComments; const diffs = computeDiff(state.doc, updatedDocument, state.schema, currentComments, nextComments); diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 53f5b5abed..1a6c2de3f4 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -307,14 +307,17 @@ describe('compareDocuments defaults', () => { const afterEditor = await getEditorFromFixture('diff_after8.docx'); try { + const emitSpy = vi.spyOn(beforeEditor, 'emit'); const omittedCommentsDiff = beforeEditor.commands.compareDocuments(afterEditor.state.doc); expect(omittedCommentsDiff.commentDiffs).toHaveLength(0); + expect(emitSpy).not.toHaveBeenCalledWith('transaction', expect.anything()); const explicitCommentsDiff = beforeEditor.commands.compareDocuments( afterEditor.state.doc, afterEditor.converter?.comments ?? [], ); expect(explicitCommentsDiff.commentDiffs.length).toBeGreaterThan(0); + expect(emitSpy).not.toHaveBeenCalledWith('transaction', expect.anything()); } finally { beforeEditor.destroy?.(); afterEditor.destroy?.(); From 31c366a5828479f9ddb8be35a41e926b4c3e02b2 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 10:23:12 -0300 Subject: [PATCH 099/125] fix(diffing): derive insertion anchors from old sequence context - refactor getInsertionPos to use only oldNodes + oldIdx and derive the previous node internally - remove redundant previousOldNodeInfo plumbing from generic and paragraph add-diff builders - keep depth-aware insertion behavior for deeper/same/shallower transitions - update diff utility and paragraph diff tests to match the new API and validate anchor resolution --- .../diffing/algorithm/diff-utils.test.ts | 17 +++++-- .../diffing/algorithm/diff-utils.ts | 47 ++++++++++++++----- .../diffing/algorithm/generic-diffing.test.js | 25 ++++++++++ .../diffing/algorithm/generic-diffing.ts | 12 ++--- .../algorithm/paragraph-diffing.test.js | 3 +- .../diffing/algorithm/paragraph-diffing.ts | 7 +-- 6 files changed, 86 insertions(+), 25 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts index 63ef88bc21..c76393fd9c 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.test.ts @@ -10,20 +10,29 @@ const createNodeInfo = ({ pos = 0, depth = 0, nodeSize = 1 } = {}) => ({ describe('getInsertionPos', () => { it('positions after previous node when depth matches', () => { const previous = createNodeInfo({ pos: 10, depth: 2, nodeSize: 5 }); - expect(getInsertionPos(2, previous)).toBe(15); + expect(getInsertionPos(2, [previous], 1)).toBe(15); }); it('falls back to previous position plus one when depth differs', () => { const previous = createNodeInfo({ pos: 10, depth: 1, nodeSize: 3 }); - expect(getInsertionPos(2, previous)).toBe(11); + expect(getInsertionPos(2, [previous], 1)).toBe(11); + }); + + it('walks backward to the nearest matching shallower depth anchor', () => { + const table = createNodeInfo({ pos: 0, depth: 0, nodeSize: 12 }); + const row = createNodeInfo({ pos: 1, depth: 1, nodeSize: 6 }); + const cell = createNodeInfo({ pos: 2, depth: 2, nodeSize: 4 }); + const oldNodes = [table, row, cell]; + + expect(getInsertionPos(0, oldNodes, 3)).toBe(12); }); it('returns zero when there is no previous node info', () => { - expect(getInsertionPos(0, undefined)).toBe(0); + expect(getInsertionPos(0, [], 0)).toBe(0); }); it('handles previous nodes lacking nodeSize safely', () => { const previous = { pos: 5, depth: 1, node: {} } as any; - expect(getInsertionPos(1, previous)).toBe(5); + expect(getInsertionPos(1, [previous], 1)).toBe(5); }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts index 0276dc42b6..411c50fc08 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/diff-utils.ts @@ -1,6 +1,6 @@ import type { Node as PMNode } from 'prosemirror-model'; -interface NodePositionInfo { +export interface NodePositionInfo { /** ProseMirror node reference. */ node: PMNode; /** Absolute position of the node in the document. */ @@ -12,19 +12,44 @@ interface NodePositionInfo { /** * Computes the insertion point for a node relative to the previous node in the old document tree. * - * When the previous node shares the same depth, the insertion - * is placed right after the previous node's position. Otherwise, the insertion - * is placed just after the previous node's opening position. + * Behavior by depth: + * - Same depth: insert after the previous node subtree. + * - Deeper depth: insert inside the previous node (at its content start). + * - Shallower depth: scan backward to the closest old node whose depth is + * less than or equal to `currentDepth`, then anchor from that node. * * @param currentDepth Depth of the node being inserted. - * @param previousNode Optional info about the preceding node from the old document. + * @param oldNodes Old-sequence context used to resolve insertion anchors. + * @param oldIdx Old-sequence insertion index (the insert happens before this index). * @returns Absolute document position where the new node should be inserted. */ -export function getInsertionPos(currentDepth: number, previousNode?: NodePositionInfo): number { - if (currentDepth === previousNode?.depth) { - const previousPos = previousNode?.pos ?? -1; - const previousSize = previousNode?.node.nodeSize ?? 0; - return previousPos >= 0 ? previousPos + previousSize : 0; +export function getInsertionPos(currentDepth: number, oldNodes: readonly NodePositionInfo[] = [], oldIdx = 0): number { + const previousNode = oldIdx > 0 ? oldNodes[oldIdx - 1] : undefined; + if (!previousNode) { + return 0; } - return (previousNode?.pos ?? -1) + 1; + + if (currentDepth > previousNode.depth) { + return previousNode.pos + 1; + } + + if (currentDepth === previousNode.depth) { + return previousNode.pos + (previousNode.node.nodeSize ?? 0); + } + + for (let cursor = oldIdx - 1; cursor >= 0; cursor -= 1) { + const candidateNode = oldNodes[cursor]; + if (!candidateNode) { + continue; + } + if (candidateNode.depth > currentDepth) { + continue; + } + if (candidateNode.depth === currentDepth) { + return candidateNode.pos + (candidateNode.node.nodeSize ?? 0); + } + return candidateNode.pos + 1; + } + + return 0; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js index f57bd11d9d..203a829bcd 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.test.js @@ -232,4 +232,29 @@ describe('diffParagraphs', () => { const addition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'heading'); expect(addition?.pos).toBe(expectedPos); }); + + it('inserts after the correct ancestor when adding a shallower node after nested content', () => { + const tableCell = buildSimpleNode('tableCell', {}, { nodeSize: 4 }); + const tableRow = buildSimpleNode('tableRow', { paraId: 'row-1' }, { nodeSize: 6, children: [tableCell] }); + const table = buildSimpleNode('table', {}, { nodeSize: 12, children: [tableRow] }); + const headingNode = buildSimpleNode('heading', { level: 1 }, { nodeSize: 3 }); + + const oldDoc = createDocFromNodes([ + { node: table, pos: 0, depth: 1 }, + { node: tableRow, pos: 1, depth: 2 }, + { node: tableCell, pos: 2, depth: 3 }, + ]); + const newDoc = createDocFromNodes([ + { node: table, pos: 0, depth: 1 }, + { node: tableRow, pos: 1, depth: 2 }, + { node: tableCell, pos: 2, depth: 3 }, + { node: headingNode, pos: 12, depth: 1 }, + ]); + + const diffs = diffNodes(normalizeNodes(oldDoc), normalizeNodes(newDoc)); + const addition = diffs.find((diff) => diff.action === 'added' && diff.nodeType === 'heading'); + + expect(addition).toBeDefined(); + expect(addition?.pos).toBe(12); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts index 4c7c36b146..2a2d2f73ee 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/generic-diffing.ts @@ -12,7 +12,7 @@ import { } from './paragraph-diffing'; import { diffSequences, reorderDiffOperations } from './sequence-diffing'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; -import { getInsertionPos } from './diff-utils'; +import { getInsertionPos, type NodePositionInfo } from './diff-utils'; type NodeJSON = ReturnType; @@ -90,8 +90,7 @@ export function diffNodes(oldNodes: NodeInfo[], newNodes: NodeInfo[]): NodeDiff[ reorderOperations: reorderDiffOperations, shouldProcessEqualAsModification, canTreatAsModification, - buildAdded: (nodeInfo, _oldIdx, previousOldNodeInfo) => - buildAddedDiff(nodeInfo, previousOldNodeInfo, addedNodesSet), + buildAdded: (nodeInfo, _oldIdx) => buildAddedDiff(nodeInfo, oldNodes, _oldIdx, addedNodesSet), buildDeleted: (nodeInfo) => buildDeletedDiff(nodeInfo, deletedNodesSet), buildModified: buildModifiedDiff, }); @@ -167,7 +166,8 @@ function canTreatAsModification(deletedNodeInfo: NodeInfo, insertedNodeInfo: Nod */ function buildAddedDiff( nodeInfo: NodeInfo, - previousOldNodeInfo: NodeInfo | undefined, + oldNodes: readonly NodePositionInfo[], + oldIdx: number, addedNodesSet: Set, ): NodeDiff | null { if (addedNodesSet.has(nodeInfo.node)) { @@ -175,7 +175,7 @@ function buildAddedDiff( } addedNodesSet.add(nodeInfo.node); if (isParagraphNodeInfo(nodeInfo)) { - return buildAddedParagraphDiff(nodeInfo, previousOldNodeInfo); + return buildAddedParagraphDiff(nodeInfo, oldNodes, oldIdx); } nodeInfo.node.descendants((childNode) => { addedNodesSet.add(childNode); @@ -185,7 +185,7 @@ function buildAddedDiff( action: 'added', nodeType: nodeInfo.node.type.name, nodeJSON: nodeInfo.node.toJSON(), - pos: getInsertionPos(nodeInfo.depth, previousOldNodeInfo), + pos: getInsertionPos(nodeInfo.depth, oldNodes, oldIdx), }; } diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js index 20db466b7e..b6f5749fe3 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.test.js @@ -127,8 +127,9 @@ describe('paragraph diff builders', () => { fullText: 'Hello', }); const previousNode = { pos: 10, depth: 0, node: { nodeSize: 4 } }; + const oldNodes = [previousNode]; - expect(buildAddedParagraphDiff(paragraph, previousNode)).toEqual({ + expect(buildAddedParagraphDiff(paragraph, oldNodes, 1)).toEqual({ action: 'added', nodeType: 'paragraph', nodeJSON: paragraph.node.toJSON(), diff --git a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts index 0632c2e022..bf785ab718 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/paragraph-diffing.ts @@ -1,7 +1,7 @@ import type { Node as PMNode } from 'prosemirror-model'; import { getInlineDiff, tokenizeInlineContent, type InlineDiffToken, type InlineDiffResult } from './inline-diffing'; import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; -import { getInsertionPos } from './diff-utils'; +import { getInsertionPos, type NodePositionInfo } from './diff-utils'; import { levenshteinDistance } from './similarity'; // Heuristics that prevent unrelated paragraphs from being paired as modifications. @@ -131,14 +131,15 @@ export function paragraphComparator(oldParagraph: ParagraphNodeInfo, newParagrap */ export function buildAddedParagraphDiff( paragraph: ParagraphNodeInfo, - previousOldNodeInfo?: Pick, + oldNodes?: readonly NodePositionInfo[], + oldIdx?: number, ): AddedParagraphDiff { return { action: 'added', nodeType: 'paragraph', nodeJSON: paragraph.node.toJSON(), text: paragraph.fullText, - pos: getInsertionPos(paragraph.depth, previousOldNodeInfo), + pos: getInsertionPos(paragraph.depth, oldNodes, oldIdx), }; } From b2070fffe3f8c6f939d0f8a722cf03c89bbf8e04 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 10:37:55 -0300 Subject: [PATCH 100/125] fix(superdoc): scope replay comment updates to active document - reuse getCommentDocumentId / belongsToDocument from comments store in replay update reconciliation - expose those helpers from comments-store to avoid duplicating document-scoping logic in SuperDoc.vue - constrain replay UPDATE comment matching to the active editor document when IDs collide - add regression coverage for same importedId across multiple documents so only the active document comment is updated --- packages/superdoc/src/SuperDoc.test.js | 53 +++++++++++++++---- packages/superdoc/src/SuperDoc.vue | 18 ++++++- .../superdoc/src/stores/comments-store.js | 2 + 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 418420baaf..19a9f369d6 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -182,6 +182,33 @@ const buildCommentsStore = () => ({ setActiveComment: vi.fn(), addComment: vi.fn(), getComment: vi.fn(() => null), + getCommentDocumentId: vi.fn((comment) => { + if (!comment) return null; + if (comment.fileId != null) return String(comment.fileId); + if (comment.documentId != null) return String(comment.documentId); + if (comment.selection?.documentId != null) return String(comment.selection.documentId); + return null; + }), + belongsToDocument: vi.fn((comment, activeDocumentId) => { + if (!activeDocumentId) return false; + const commentDocumentId = + comment?.fileId != null + ? String(comment.fileId) + : comment?.documentId != null + ? String(comment.documentId) + : comment?.selection?.documentId != null + ? String(comment.selection.documentId) + : null; + if (commentDocumentId) return commentDocumentId === String(activeDocumentId); + + const docs = superdocStoreStub?.documents?.value; + if (Array.isArray(docs) && docs.length === 1) { + const onlyDocumentId = docs[0]?.id != null ? String(docs[0].id) : null; + return onlyDocumentId === String(activeDocumentId); + } + + return false; + }), COMMENT_EVENTS: { ADD: 'add', UPDATE: 'update', @@ -498,15 +525,22 @@ describe('SuperDoc.vue', () => { await nextTick(); const options = wrapper.findComponent(SuperEditorStub).props('options'); - const existingComment = { commentId: 'old-runtime-id', importedId: 'imp-1', commentText: 'Old text' }; + const existingComment = { + commentId: 'old-runtime-id', + importedId: 'imp-1', + commentText: 'Old text', + fileId: 'doc-1', + }; + const otherDocumentComment = { + commentId: 'doc2-id', + importedId: 'imp-1', + commentText: 'Doc 2 text', + fileId: 'doc-2', + }; - commentsStoreStub.commentsList.value = [existingComment]; - commentsStoreStub.getComment.mockClear(); - commentsStoreStub.getComment.mockImplementation((id) => { - if (id === 'imp-1' || id === 'old-runtime-id') return existingComment; - return null; - }); + commentsStoreStub.commentsList.value = [existingComment, otherDocumentComment]; commentsStoreStub.addComment.mockClear(); + superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; options.onCommentsUpdate({ type: 'update', @@ -517,12 +551,13 @@ describe('SuperDoc.vue', () => { }, }); - expect(commentsStoreStub.getComment.mock.calls).toEqual([['imp-1']]); expect(commentsStoreStub.addComment).not.toHaveBeenCalled(); - expect(commentsStoreStub.commentsList.value).toHaveLength(1); + expect(commentsStoreStub.commentsList.value).toHaveLength(2); expect(existingComment.commentId).toBe('new-runtime-id'); expect(existingComment.importedId).toBe('imp-1'); expect(existingComment.commentText).toBe('Updated text'); + expect(otherDocumentComment.commentId).toBe('doc2-id'); + expect(otherDocumentComment.commentText).toBe('Doc 2 text'); }); it('removes replay-deleted comments when payload commentId is stale but importedId matches', async () => { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 1b4250e088..ef790cd3c0 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -93,6 +93,7 @@ const { syncTrackedChangeComments, addComment, getComment, + belongsToDocument, COMMENT_EVENTS, } = commentsStore; const { proxy } = getCurrentInstance(); @@ -666,9 +667,22 @@ const onEditorCommentsUpdate = (params = {}) => { return [...new Set(ids)]; }; const resolveUpdateCommentMatch = (payload) => { - const candidateIds = [payload?.importedId, payload?.commentId].filter(Boolean); + const candidateIds = [payload?.importedId, payload?.commentId].filter(Boolean).map((value) => String(value)); + const activeDocumentId = + proxy.$superdoc?.activeEditor?.options?.documentId != null + ? String(proxy.$superdoc.activeEditor.options.documentId) + : null; + for (const candidateId of candidateIds) { - const existingComment = getComment(candidateId); + const existingComment = commentsList.value.find((comment) => { + const commentId = comment?.commentId != null ? String(comment.commentId) : null; + const importedId = comment?.importedId != null ? String(comment.importedId) : null; + const isIdMatch = commentId === candidateId || importedId === candidateId; + if (!isIdMatch) return false; + if (!activeDocumentId || typeof belongsToDocument !== 'function') return true; + return belongsToDocument(comment, activeDocumentId); + }); + if (existingComment) { return { id: candidateId, diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index 710a05ff4e..394e1c05c4 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -1321,6 +1321,8 @@ export const useCommentsStore = defineStore('comments', () => { getCommentAnchoredText, getCommentAnchorData, resolveCommentPositionEntry, + getCommentDocumentId, + belongsToDocument, // Actions init, From dc6c94be3ff0df23e3e45daef5f2487305a3b114 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 10:45:53 -0300 Subject: [PATCH 101/125] fix(superdoc): scope replay thread deletions to active document - restrict replay DELETED handling to comments that belong to the active editor document - apply document scoping consistently across seed matching, subtree expansion, and final filtering - prevent cross-document comment/thread removal when IDs overlap across open docs - keep active-comment clearing document-aware using pre-delete comment snapshot - add regression test for overlapping IDs across documents during replay deletion --- packages/superdoc/src/SuperDoc.test.js | 29 +++++++ packages/superdoc/src/SuperDoc.vue | 101 +++++++++++++++++-------- 2 files changed, 98 insertions(+), 32 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 19a9f369d6..a1d039bcb9 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -633,6 +633,35 @@ describe('SuperDoc.vue', () => { expect(commentsStoreStub.setActiveComment).toHaveBeenCalledWith(superdocStub, null); }); + it('scopes replay deletion subtree to the active document when IDs overlap across documents', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + commentsStoreStub.commentsList.value = [ + { commentId: 'c-1', importedId: 'imp-1', fileId: 'doc-1', commentText: 'Doc 1 parent' }, + { commentId: 'c-2', parentCommentId: 'c-1', fileId: 'doc-1', commentText: 'Doc 1 child' }, + { commentId: 'c-1', importedId: 'imp-1', fileId: 'doc-2', commentText: 'Doc 2 parent' }, + { commentId: 'c-3', parentCommentId: 'c-1', fileId: 'doc-2', commentText: 'Doc 2 child' }, + ]; + commentsStoreStub.activeComment.value = 'c-3'; + commentsStoreStub.setActiveComment.mockClear(); + superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; + + options.onCommentsUpdate({ + type: 'deleted', + comment: { commentId: 'c-1', importedId: 'imp-1' }, + }); + + expect(commentsStoreStub.commentsList.value).toEqual([ + { commentId: 'c-1', importedId: 'imp-1', fileId: 'doc-2', commentText: 'Doc 2 parent' }, + { commentId: 'c-3', parentCommentId: 'c-1', fileId: 'doc-2', commentText: 'Doc 2 child' }, + ]); + await nextTick(); + expect(commentsStoreStub.setActiveComment).not.toHaveBeenCalledWith(superdocStub, null); + }); + it('passes slash menu and context menu options through to SuperEditor', async () => { const superdocStub = createSuperdocStub(); const slashMenuConfig = { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index ef790cd3c0..65cb920fd7 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -761,43 +761,80 @@ const onEditorCommentsUpdate = (params = {}) => { if (COMMENT_EVENTS?.DELETED && type === COMMENT_EVENTS.DELETED && commentPayload) { const targetIds = resolveCommentEventIds(commentPayload); if (targetIds.length) { - // Remove the entire thread subtree (parent + all descendants), not only direct replies. - const removedCommentIds = new Set(targetIds); - let expanded = true; - while (expanded) { - expanded = false; - commentsList.value.forEach((comment) => { - const commentId = comment.commentId != null ? String(comment.commentId) : null; - const importedId = comment.importedId != null ? String(comment.importedId) : null; - const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; - const trackedChangeParentId = - comment.trackedChangeParentId != null ? String(comment.trackedChangeParentId) : null; - - const isRemovedComment = - (commentId && removedCommentIds.has(commentId)) || (importedId && removedCommentIds.has(importedId)); - const isDescendantOfRemovedComment = - (parentCommentId && removedCommentIds.has(parentCommentId)) || - (trackedChangeParentId && removedCommentIds.has(trackedChangeParentId)); - if (!isRemovedComment && !isDescendantOfRemovedComment) return; - - const sizeBefore = removedCommentIds.size; - if (commentId) removedCommentIds.add(commentId); - if (importedId) removedCommentIds.add(importedId); - if (removedCommentIds.size > sizeBefore) { - expanded = true; - } - }); - } + const activeDocumentId = + proxy.$superdoc?.activeEditor?.options?.documentId != null + ? String(proxy.$superdoc.activeEditor.options.documentId) + : null; + const isInActiveDocument = (comment) => { + if (!activeDocumentId || typeof belongsToDocument !== 'function') return true; + return belongsToDocument(comment, activeDocumentId); + }; - commentsList.value = commentsList.value.filter((comment) => { + // Remove the entire thread subtree (parent + all descendants), not only direct replies. + const removedCommentIds = new Set(); + commentsList.value.forEach((comment) => { + if (!isInActiveDocument(comment)) return; const commentId = comment.commentId != null ? String(comment.commentId) : null; const importedId = comment.importedId != null ? String(comment.importedId) : null; - return !((commentId && removedCommentIds.has(commentId)) || (importedId && removedCommentIds.has(importedId))); + const matchesTarget = + (commentId && targetIds.includes(commentId)) || (importedId && targetIds.includes(importedId)); + if (!matchesTarget) return; + if (commentId) removedCommentIds.add(commentId); + if (importedId) removedCommentIds.add(importedId); }); - const activeCommentKey = activeComment.value != null ? String(activeComment.value) : null; - if (activeCommentKey && removedCommentIds.has(activeCommentKey)) { - activeCommentId = null; + if (removedCommentIds.size) { + let expanded = true; + while (expanded) { + expanded = false; + commentsList.value.forEach((comment) => { + if (!isInActiveDocument(comment)) return; + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + const parentCommentId = comment.parentCommentId != null ? String(comment.parentCommentId) : null; + const trackedChangeParentId = + comment.trackedChangeParentId != null ? String(comment.trackedChangeParentId) : null; + + const isRemovedComment = + (commentId && removedCommentIds.has(commentId)) || (importedId && removedCommentIds.has(importedId)); + const isDescendantOfRemovedComment = + (parentCommentId && removedCommentIds.has(parentCommentId)) || + (trackedChangeParentId && removedCommentIds.has(trackedChangeParentId)); + if (!isRemovedComment && !isDescendantOfRemovedComment) return; + + const sizeBefore = removedCommentIds.size; + if (commentId) removedCommentIds.add(commentId); + if (importedId) removedCommentIds.add(importedId); + if (removedCommentIds.size > sizeBefore) { + expanded = true; + } + }); + } + + const previousComments = [...commentsList.value]; + commentsList.value = commentsList.value.filter((comment) => { + if (!isInActiveDocument(comment)) return true; + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + return !( + (commentId && removedCommentIds.has(commentId)) || + (importedId && removedCommentIds.has(importedId)) + ); + }); + + const activeCommentKey = activeComment.value != null ? String(activeComment.value) : null; + const activeCommentModel = + activeCommentKey != null + ? previousComments.find((comment) => { + const commentId = comment.commentId != null ? String(comment.commentId) : null; + const importedId = comment.importedId != null ? String(comment.importedId) : null; + return commentId === activeCommentKey || importedId === activeCommentKey; + }) + : null; + const activeCommentInActiveDocument = activeCommentModel ? isInActiveDocument(activeCommentModel) : false; + if (activeCommentKey && removedCommentIds.has(activeCommentKey) && activeCommentInActiveDocument) { + activeCommentId = null; + } } } } From 4941d58a088b4729640578723e115b7659e91f64 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 11:12:06 -0300 Subject: [PATCH 102/125] fix(superdoc): preserve comment identity on replay updates - replace raw replay Object.assign with a safe field-level updater for existing comment models - update only an explicit allowlist of mutable replay fields and normalize commentText from payload text/commentText - preserve useComment identity invariants (commentId/importedId and constructor-captured metadata) - strengthen replay update test to assert model identity remains stable via getValues() after updates --- packages/superdoc/src/SuperDoc.test.js | 11 +++++--- packages/superdoc/src/SuperDoc.vue | 36 +++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index a1d039bcb9..17fe8cebb8 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -523,14 +523,17 @@ describe('SuperDoc.vue', () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); await nextTick(); + const { default: useComment } = await import('./components/CommentsLayer/use-comment.js'); const options = wrapper.findComponent(SuperEditorStub).props('options'); - const existingComment = { + const existingComment = useComment({ commentId: 'old-runtime-id', importedId: 'imp-1', commentText: 'Old text', fileId: 'doc-1', - }; + creatorEmail: 'ada@example.com', + creatorName: 'Ada', + }); const otherDocumentComment = { commentId: 'doc2-id', importedId: 'imp-1', @@ -553,8 +556,10 @@ describe('SuperDoc.vue', () => { expect(commentsStoreStub.addComment).not.toHaveBeenCalled(); expect(commentsStoreStub.commentsList.value).toHaveLength(2); - expect(existingComment.commentId).toBe('new-runtime-id'); + expect(existingComment.commentId).toBe('old-runtime-id'); expect(existingComment.importedId).toBe('imp-1'); + expect(existingComment.getValues().commentId).toBe('old-runtime-id'); + expect(existingComment.getValues().importedId).toBe('imp-1'); expect(existingComment.commentText).toBe('Updated text'); expect(otherDocumentComment.commentId).toBe('doc2-id'); expect(otherDocumentComment.commentText).toBe('Doc 2 text'); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 65cb920fd7..dff4940042 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -659,6 +659,37 @@ const onEditorCommentLocationsUpdate = (doc, { allCommentIds: activeThreadId, al flushPendingReplayTrackedChangeSync(); }; +// Replay updates should only patch mutable comment state. +// Identity and construction-time metadata are intentionally excluded. +const REPLAY_MUTABLE_COMMENT_FIELDS = new Set([ + 'commentText', + 'isInternal', + 'trackedChange', + 'trackedChangeType', + 'trackedChangeText', + 'deletedText', + 'resolvedTime', + 'resolvedByEmail', + 'resolvedByName', + 'importedAuthor', + 'docxCommentJSON', +]); + +const applyReplayUpdateToComment = (commentModel, payload, resolvedText) => { + if (!commentModel || !payload) return; + + Object.entries(payload).forEach(([key, value]) => { + if (value === undefined) return; + if (key === 'text') return; + if (!REPLAY_MUTABLE_COMMENT_FIELDS.has(key)) return; + commentModel[key] = value; + }); + + if (resolvedText !== undefined) { + commentModel.commentText = resolvedText; + } +}; + const onEditorCommentsUpdate = (params = {}) => { // Set the active comment in the store let { activeCommentId, type, comment: commentPayload } = params; @@ -739,10 +770,7 @@ const onEditorCommentsUpdate = (params = {}) => { const resolvedText = commentPayload.commentText || commentPayload.text; if (existingComment) { - Object.assign(existingComment, commentPayload); - if (!existingComment.commentText && resolvedText) { - existingComment.commentText = resolvedText; - } + applyReplayUpdateToComment(existingComment, commentPayload, resolvedText); } else { const normalizedPayload = { ...commentPayload }; if (!normalizedPayload.commentText && resolvedText) { From 6f74b3d0d9cc1517ce7fdf64144a50acfe1edda7 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 11:46:35 -0300 Subject: [PATCH 103/125] fix(diff-replay): include document identity in replayed comment events - add replay comment payload normalization to always emit commentId and preserve/add ownership metadata (documentId, fileId) - use editor.options.documentId as fallback when replay comment payload lacks document scope - keep existing payload documentId/fileId unchanged when already present - update replay editor typing in replayComments/replayDiffs to include optional options.documentId - add tests covering both fallback ownership injection and preservation of existing ownership fields --- .../diffing/replay/replay-comments.test.js | 76 +++++++++++++++++ .../diffing/replay/replay-comments.ts | 85 ++++++++++++++----- .../src/extensions/diffing/replayDiffs.ts | 7 +- 3 files changed, 147 insertions(+), 21 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js b/packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js index 045345a9bf..dfad8ae8b3 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/replay-comments.test.js @@ -242,6 +242,80 @@ const testDerivesCommentTextFromElements = () => { ); }; +/** + * Verifies replay events include file/document ownership derived from editor context. + * @returns {void} + */ +const testIncludesDocumentIdentityFromEditor = () => { + const comments = []; + const editor = { + emit: vi.fn(), + options: { documentId: 'doc-2' }, + }; + const diffs = [ + { + action: 'added', + nodeType: 'comment', + commentId: 'external-doc', + commentJSON: { id: 'external-doc' }, + text: 'Doc comment', + }, + ]; + + replayComments({ comments, commentDiffs: diffs, editor }); + + expect(editor.emit).toHaveBeenCalledWith( + 'commentsUpdate', + expect.objectContaining({ + type: 'add', + comment: expect.objectContaining({ + commentId: 'external-doc', + documentId: 'doc-2', + fileId: 'doc-2', + }), + }), + ); +}; + +/** + * Verifies replay keeps existing payload file/document ownership fields. + * @returns {void} + */ +const testPreservesExistingDocumentIdentity = () => { + const comments = []; + const editor = { + emit: vi.fn(), + options: { documentId: 'doc-2' }, + }; + const diffs = [ + { + action: 'added', + nodeType: 'comment', + commentId: 'external-owned', + commentJSON: { + id: 'external-owned', + fileId: 'doc-9', + documentId: 'doc-9', + }, + text: 'Owned comment', + }, + ]; + + replayComments({ comments, commentDiffs: diffs, editor }); + + expect(editor.emit).toHaveBeenCalledWith( + 'commentsUpdate', + expect.objectContaining({ + type: 'add', + comment: expect.objectContaining({ + commentId: 'external-owned', + documentId: 'doc-9', + fileId: 'doc-9', + }), + }), + ); +}; + /** * Runs the replayComments suite. * @returns {void} @@ -254,6 +328,8 @@ const runReplayCommentsSuite = () => { it('aggregates results across multiple diffs', testAggregatesMultipleDiffs); it('emits commentsUpdate events for replayed diffs', testEmitsCommentsUpdateEvents); it('derives comment text from elements for replayed additions', testDerivesCommentTextFromElements); + it('includes replay comment ownership metadata from editor document', testIncludesDocumentIdentityFromEditor); + it('preserves replay comment ownership metadata when already present', testPreservesExistingDocumentIdentity); }; describe('replayComments', runReplayCommentsSuite); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-comments.ts b/packages/super-editor/src/extensions/diffing/replay/replay-comments.ts index 877528d900..ecba4145ca 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-comments.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-comments.ts @@ -16,6 +16,54 @@ function findCommentIndexById( return comments.findIndex((comment) => resolveCommentId(comment) === commentId); } +type ReplayEditor = { + emit?: (event: string, payload: unknown) => void; + options?: { + documentId?: string | null; + }; +}; + +/** + * Builds a replay event payload with stable id and document ownership metadata. + * + * @param params.comment Source comment payload. + * @param params.commentId Resolved comment id from diff token. + * @param params.editor Optional editor used to infer active document ownership. + * @returns Normalized comment payload for commentsUpdate events. + */ +function buildReplayCommentEventPayload({ + comment, + commentId, + editor, +}: { + comment: import('../algorithm/comment-diffing').CommentInput; + commentId: string; + editor?: ReplayEditor; +}): import('../algorithm/comment-diffing').CommentInput { + const payload = { + ...comment, + }; + + if (!payload.commentId) { + payload.commentId = commentId; + } + + const editorDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null; + const payloadDocumentId = payload.documentId != null ? String(payload.documentId) : null; + const payloadFileId = payload.fileId != null ? String(payload.fileId) : null; + const documentId = payloadDocumentId ?? editorDocumentId; + const fileId = payloadFileId ?? documentId ?? editorDocumentId; + + if (!payload.documentId && documentId) { + payload.documentId = documentId; + } + if (!payload.fileId && fileId) { + payload.fileId = fileId; + } + + return payload; +} + /** * Replays one comment diff into a mutable comment store. * @@ -36,7 +84,7 @@ function replayCommentDiff({ }: { comments: import('../algorithm/comment-diffing').CommentInput[]; diff: import('../algorithm/comment-diffing').CommentDiff; - editor?: { emit?: (event: string, payload: unknown) => void }; + editor?: ReplayEditor; }): ReplayResult { const result: ReplayResult = { applied: 0, @@ -68,12 +116,11 @@ function replayCommentDiff({ comments.push(diff.commentJSON); result.applied += 1; - const payload = { - ...diff.commentJSON, - }; - if (!payload.commentId) { - payload.commentId = diff.commentId; - } + const payload = buildReplayCommentEventPayload({ + comment: diff.commentJSON, + commentId: diff.commentId, + editor, + }); const resolvedText = resolveCommentTextPayload({ comment: diff.commentJSON, fallbackText: diff.text }); if (!payload.commentText && resolvedText) { payload.commentText = resolvedText; @@ -94,12 +141,11 @@ function replayCommentDiff({ comments.splice(existingIndex, 1); result.applied += 1; - const payload = { - ...diff.commentJSON, - }; - if (!payload.commentId) { - payload.commentId = diff.commentId; - } + const payload = buildReplayCommentEventPayload({ + comment: diff.commentJSON, + commentId: diff.commentId, + editor, + }); editor?.emit?.('commentsUpdate', { type: comments_module_events.DELETED, comment: payload, @@ -116,12 +162,11 @@ function replayCommentDiff({ comments.splice(existingIndex, 1, diff.newCommentJSON); result.applied += 1; - const payload = { - ...diff.newCommentJSON, - }; - if (!payload.commentId) { - payload.commentId = diff.commentId; - } + const payload = buildReplayCommentEventPayload({ + comment: diff.newCommentJSON, + commentId: diff.commentId, + editor, + }); const resolvedText = resolveCommentTextPayload({ comment: diff.newCommentJSON, fallbackText: diff.newText }); if (!payload.commentText && resolvedText) { payload.commentText = resolvedText; @@ -217,7 +262,7 @@ export function replayComments({ }: { comments: import('../algorithm/comment-diffing').CommentInput[]; commentDiffs: import('../algorithm/comment-diffing').CommentDiff[]; - editor?: { emit?: (event: string, payload: unknown) => void }; + editor?: ReplayEditor; }): ReplayResult { const result: ReplayResult = { applied: 0, diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index 39dec5e6ab..18b208c95c 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -21,7 +21,12 @@ type ReplayDiffsParams = { diff: import('./computeDiff').DiffResult; schema: import('prosemirror-model').Schema; comments?: import('./algorithm/comment-diffing').CommentInput[]; - editor?: { emit?: (event: string, payload: unknown) => void }; + editor?: { + emit?: (event: string, payload: unknown) => void; + options?: { + documentId?: string | null; + }; + }; }; /** From 3be429e16e4979d8bfed5b709932bbd3ee70234a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 12:08:11 -0300 Subject: [PATCH 104/125] fix(comments-store): treat importedId as live in tracked-change prune - update tracked-change stale-prune liveness check to consider both commentId and importedId - prevent pruning live tracked-change threads when runtime commentId diverges but mark IDs still match importedId - keep existing descendant removal behavior unchanged - add regression test for replay/import flows where importedId remains stable while commentId changes --- .../superdoc/src/stores/comments-store.js | 5 ++- .../src/stores/comments-store.test.js | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index 394e1c05c4..4bea549617 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -1019,9 +1019,10 @@ export const useCommentsStore = defineStore('comments', () => { const commentId = comment.commentId != null ? String(comment.commentId) : null; const importedId = comment.importedId != null ? String(comment.importedId) : null; - const primaryId = commentId ?? importedId; + const hasLiveCommentId = Boolean(commentId && liveTrackedChangeIds.has(commentId)); + const hasLiveImportedId = Boolean(importedId && liveTrackedChangeIds.has(importedId)); - if (!primaryId || liveTrackedChangeIds.has(primaryId)) return true; + if ((!commentId && !importedId) || hasLiveCommentId || hasLiveImportedId) return true; if (commentId) removedIds.add(commentId); if (importedId) removedIds.add(importedId); diff --git a/packages/superdoc/src/stores/comments-store.test.js b/packages/superdoc/src/stores/comments-store.test.js index 31e4887667..4efd3a5305 100644 --- a/packages/superdoc/src/stores/comments-store.test.js +++ b/packages/superdoc/src/stores/comments-store.test.js @@ -672,6 +672,45 @@ describe('comments-store', () => { expect(editorDispatch).toHaveBeenCalledWith(tr); }); + it('keeps tracked-change comments when importedId is live even if commentId differs', () => { + const editorDispatch = vi.fn(); + const tr = { setMeta: vi.fn() }; + const editor = { + state: {}, + view: { state: { tr }, dispatch: editorDispatch }, + options: { documentId: 'doc-1' }, + }; + + trackChangesHelpersMock.getTrackChanges.mockReturnValue([{ mark: { attrs: { id: 'tc-live-imported' } } }]); + groupChangesMock.mockReturnValue([]); + + store.commentsList = [ + { + commentId: 'runtime-id-123', + importedId: 'tc-live-imported', + trackedChange: true, + trackedChangeText: 'Existing', + fileId: 'doc-1', + }, + { commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }, + ]; + + store.syncTrackedChangeComments({ superdoc: {}, editor }); + + expect(store.commentsList).toEqual([ + { + commentId: 'runtime-id-123', + importedId: 'tc-live-imported', + trackedChange: true, + trackedChangeText: 'Existing', + fileId: 'doc-1', + }, + { commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }, + ]); + expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); + expect(editorDispatch).toHaveBeenCalledWith(tr); + }); + it('does not prune tracked-change comments from other documents during sync', () => { const editorDispatch = vi.fn(); const tr = { setMeta: vi.fn() }; From f4381224997591caa38004e1a49ab0b1edda9414 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 13:35:18 -0300 Subject: [PATCH 105/125] fix(comments-store): dedupe tracked-change sync by commentId and importedId - seed tracked-change existingIds with both runtime commentId and stable importedId - prevent duplicate tracked-change thread creation when grouped mark id matches an existing imported id - add created sync IDs (id, params.changeId, params.importedId) back into dedupe set during sync pass - add regression test for mixed-ID replay/sync scenario where commentId diverges but importedId remains live --- .../superdoc/src/stores/comments-store.js | 15 +++++-- .../src/stores/comments-store.test.js | 39 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index 4bea549617..91cccc0a2d 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -921,8 +921,15 @@ export const useCommentsStore = defineStore('comments', () => { const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editor.state); const groupedChanges = groupChanges(trackedChanges); - // Build a Set of existing comment IDs for O(1) lookup - const existingIds = new Set(commentsList.value.map((c) => c.commentId)); + // Build a Set of existing tracked-change IDs for O(1) lookup. + // Include both runtime and imported IDs to avoid duplicate threads when + // replay/import flows remap commentId but marks still reference importedId. + const existingIds = new Set(); + commentsList.value.forEach((comment) => { + if (!comment?.trackedChange) return; + if (comment.commentId != null) existingIds.add(String(comment.commentId)); + if (comment.importedId != null) existingIds.add(String(comment.importedId)); + }); // Build a Map of change ID → tracked change entries for O(1) lookup per group. // This avoids re-scanning the entire document for each tracked change. @@ -959,7 +966,9 @@ export const useCommentsStore = defineStore('comments', () => { if (params) { handleTrackedChangeUpdate({ superdoc, params }); - existingIds.add(id); + existingIds.add(String(id)); + if (params.changeId != null) existingIds.add(String(params.changeId)); + if (params.importedId != null) existingIds.add(String(params.importedId)); } }); diff --git a/packages/superdoc/src/stores/comments-store.test.js b/packages/superdoc/src/stores/comments-store.test.js index 4efd3a5305..34dea91533 100644 --- a/packages/superdoc/src/stores/comments-store.test.js +++ b/packages/superdoc/src/stores/comments-store.test.js @@ -711,6 +711,45 @@ describe('comments-store', () => { expect(editorDispatch).toHaveBeenCalledWith(tr); }); + it('deduplicates tracked-change sync when grouped mark id matches existing importedId', () => { + const editorDispatch = vi.fn(); + const tr = { setMeta: vi.fn() }; + const editor = { + state: {}, + view: { state: { tr }, dispatch: editorDispatch }, + options: { documentId: 'doc-1' }, + }; + + trackChangesHelpersMock.getTrackChanges.mockReturnValue([{ mark: { attrs: { id: 'tc-live-imported' } } }]); + groupChangesMock.mockReturnValue([{ insertedMark: { mark: { attrs: { id: 'tc-live-imported' } } } }]); + + store.commentsList = [ + { + commentId: 'runtime-id-123', + importedId: 'tc-live-imported', + trackedChange: true, + trackedChangeText: 'Existing', + fileId: 'doc-1', + }, + { commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }, + ]; + + store.syncTrackedChangeComments({ superdoc: {}, editor }); + + expect(store.commentsList).toEqual([ + { + commentId: 'runtime-id-123', + importedId: 'tc-live-imported', + trackedChange: true, + trackedChangeText: 'Existing', + fileId: 'doc-1', + }, + { commentId: 'normal-1', commentText: 'Regular comment', fileId: 'doc-1' }, + ]); + expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); + expect(editorDispatch).toHaveBeenCalledWith(tr); + }); + it('does not prune tracked-change comments from other documents during sync', () => { const editorDispatch = vi.fn(); const tr = { setMeta: vi.fn() }; From 944921625cb67cc642973836be2e6bbc3d5f3b43 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 13:51:01 -0300 Subject: [PATCH 106/125] fix(comments): keep replayed docxCommentJSON in export payloads - make useComment store docxCommentJSON as reactive state instead of a construction-time constant - update getValues() to return the current docxCommentJSON value - ensure replay-updated imported comment structure is reflected in translateCommentsForExport output - add unit test verifying getValues() returns updated docxCommentJSON after mutation --- packages/superdoc/src/SuperDoc.test.js | 36 +++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 5 +++ .../components/CommentsLayer/use-comment.js | 4 +-- .../CommentsLayer/use-comment.test.js | 13 +++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 17fe8cebb8..a4515be75b 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -565,6 +565,42 @@ describe('SuperDoc.vue', () => { expect(otherDocumentComment.commentText).toBe('Doc 2 text'); }); + it('updates docxCommentJSON from replayed elements for imported comments', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + const { default: useComment } = await import('./components/CommentsLayer/use-comment.js'); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + const existingComment = useComment({ + commentId: 'old-runtime-id', + importedId: 'imp-1', + commentText: 'Old text', + fileId: 'doc-1', + docxCommentJSON: [{ type: 'paragraph', content: [{ type: 'text', text: 'old' }] }], + creatorEmail: 'ada@example.com', + creatorName: 'Ada', + }); + commentsStoreStub.commentsList.value = [existingComment]; + commentsStoreStub.addComment.mockClear(); + superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; + + const updatedElements = [{ type: 'paragraph', content: [{ type: 'text', text: 'new' }] }]; + options.onCommentsUpdate({ + type: 'update', + comment: { + commentId: 'new-runtime-id', + importedId: 'imp-1', + text: 'Updated text', + elements: updatedElements, + }, + }); + + expect(commentsStoreStub.addComment).not.toHaveBeenCalled(); + expect(existingComment.commentText).toBe('Updated text'); + expect(existingComment.docxCommentJSON).toEqual(updatedElements); + }); + it('removes replay-deleted comments when payload commentId is stale but importedId matches', async () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index dff4940042..86c7df66b9 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -678,9 +678,14 @@ const REPLAY_MUTABLE_COMMENT_FIELDS = new Set([ const applyReplayUpdateToComment = (commentModel, payload, resolvedText) => { if (!commentModel || !payload) return; + if (Array.isArray(payload.elements)) { + commentModel.docxCommentJSON = payload.elements; + } + Object.entries(payload).forEach(([key, value]) => { if (value === undefined) return; if (key === 'text') return; + if (key === 'elements') return; if (!REPLAY_MUTABLE_COMMENT_FIELDS.has(key)) return; commentModel[key] = value; }); diff --git a/packages/superdoc/src/components/CommentsLayer/use-comment.js b/packages/superdoc/src/components/CommentsLayer/use-comment.js index 10c80472f0..4a33a6396d 100644 --- a/packages/superdoc/src/components/CommentsLayer/use-comment.js +++ b/packages/superdoc/src/components/CommentsLayer/use-comment.js @@ -32,7 +32,7 @@ export default function useComment(params) { const creatorImage = params.creatorImage; const createdTime = params.createdTime || Date.now(); const importedAuthor = ref(params.importedAuthor || null); - const docxCommentJSON = params.docxCommentJSON || null; + const docxCommentJSON = ref(params.docxCommentJSON || null); const origin = params.origin; const threadingMethod = params.threadingMethod; const threadingStyleOverride = params.threadingStyleOverride; @@ -244,7 +244,7 @@ export default function useComment(params) { creatorImage, createdTime, importedAuthor: importedAuthor.value, - docxCommentJSON, + docxCommentJSON: docxCommentJSON.value, isInternal: isInternal.value, commentText: commentText.value, selection: selection ? selection.getValues() : null, diff --git a/packages/superdoc/src/components/CommentsLayer/use-comment.test.js b/packages/superdoc/src/components/CommentsLayer/use-comment.test.js index a26b3c5cfd..a02308d88f 100644 --- a/packages/superdoc/src/components/CommentsLayer/use-comment.test.js +++ b/packages/superdoc/src/components/CommentsLayer/use-comment.test.js @@ -27,4 +27,17 @@ describe('use-comment', () => { hasCommentsIds: true, }); }); + + it('returns the latest docxCommentJSON value from getValues()', () => { + const comment = useComment({ + commentId: 'comment-2', + docxCommentJSON: [{ type: 'paragraph', content: [{ type: 'text', text: 'old' }] }], + }); + + const updatedDocxCommentJSON = [{ type: 'paragraph', content: [{ type: 'text', text: 'new' }] }]; + comment.docxCommentJSON = updatedDocxCommentJSON; + + const values = comment.getValues(); + expect(values.docxCommentJSON).toEqual(updatedDocxCommentJSON); + }); }); From 009193ce67089b6e54da3b50120f23fca15db73b Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 14:21:08 -0300 Subject: [PATCH 107/125] fix(superdoc): preserve DOCX comment structure on replay add - add replay payload normalization for comment model creation (text -> commentText, elements -> docxCommentJSON) - apply normalization in replay ADD path before useComment(...) - reuse the same normalization in replay UPDATE fallback when creating missing comments - ensure replay-added imported comments keep DOCX-native body structure for export/ round-trip - add regression test verifying replay ADD maps elements into docxCommentJSON --- packages/superdoc/src/SuperDoc.test.js | 25 +++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 20 +++++++++------ .../superdoc/src/stores/comments-store.js | 2 +- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index a4515be75b..330e4a801c 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -601,6 +601,31 @@ describe('SuperDoc.vue', () => { expect(existingComment.docxCommentJSON).toEqual(updatedElements); }); + it('maps replay-added elements to docxCommentJSON for imported comments', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + commentsStoreStub.addComment.mockClear(); + + const addedElements = [{ type: 'paragraph', content: [{ type: 'text', text: 'added' }] }]; + options.onCommentsUpdate({ + type: 'add', + comment: { + commentId: 'new-add-id', + importedId: 'imp-add', + text: 'Added text', + elements: addedElements, + }, + }); + + expect(commentsStoreStub.addComment).toHaveBeenCalledTimes(1); + const [{ comment: addedComment }] = commentsStoreStub.addComment.mock.calls[0]; + expect(addedComment.commentText).toBe('Added text'); + expect(addedComment.docxCommentJSON).toEqual(addedElements); + }); + it('removes replay-deleted comments when payload commentId is stale but importedId matches', async () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 86c7df66b9..0fbd0ffa35 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -695,6 +695,17 @@ const applyReplayUpdateToComment = (commentModel, payload, resolvedText) => { } }; +const normalizeReplayCommentModelPayload = (payload = {}) => { + const normalizedPayload = { ...payload }; + if (!normalizedPayload.commentText && normalizedPayload.text) { + normalizedPayload.commentText = normalizedPayload.text; + } + if (!normalizedPayload.docxCommentJSON && Array.isArray(normalizedPayload.elements)) { + normalizedPayload.docxCommentJSON = normalizedPayload.elements; + } + return normalizedPayload; +}; + const onEditorCommentsUpdate = (params = {}) => { // Set the active comment in the store let { activeCommentId, type, comment: commentPayload } = params; @@ -737,9 +748,7 @@ const onEditorCommentsUpdate = (params = {}) => { } if (COMMENT_EVENTS?.ADD && type === COMMENT_EVENTS.ADD && commentPayload) { - if (!commentPayload.commentText && commentPayload.text) { - commentPayload.commentText = commentPayload.text; - } + commentPayload = normalizeReplayCommentModelPayload(commentPayload); const currentUser = proxy.$superdoc?.user; if (currentUser) { @@ -777,10 +786,7 @@ const onEditorCommentsUpdate = (params = {}) => { if (existingComment) { applyReplayUpdateToComment(existingComment, commentPayload, resolvedText); } else { - const normalizedPayload = { ...commentPayload }; - if (!normalizedPayload.commentText && resolvedText) { - normalizedPayload.commentText = resolvedText; - } + const normalizedPayload = normalizeReplayCommentModelPayload(commentPayload); const commentModel = useComment(normalizedPayload); addComment({ superdoc: proxy.$superdoc, comment: commentModel, skipEditorUpdate: true }); } diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index 91cccc0a2d..efd4651f32 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -754,7 +754,7 @@ export const useCommentsStore = defineStore('comments', () => { activeComment.value = null; superdocStore.selectionPosition = null; - superdoc.activeEditor?.commands.removeComment({ commentId: 'pending' }); + superdoc.activeEditor?.commands?.removeComment({ commentId: 'pending' }); }; /** From 7f227664713884b83ceb20503f1ea94cb8e1d122 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 14:57:40 -0300 Subject: [PATCH 108/125] fix(superdoc): replayed comment resolution persistence for export - map replay isDone updates to resolvedTime/resolvedBy* when payload resolved fields are null/missing - apply the same fallback during replay payload normalization and model updates - refactor shared isDone resolution fallback logic to avoid duplicated code - add regression test covering replay update payloads with isDone: true and null resolved fields, ensuring resolved state is persisted and can be exported --- packages/superdoc/src/SuperDoc.test.js | 55 ++++++++++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 21 ++++++++++ 2 files changed, 76 insertions(+) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 330e4a801c..286953e307 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -601,6 +601,61 @@ describe('SuperDoc.vue', () => { expect(existingComment.docxCommentJSON).toEqual(updatedElements); }); + it('maps replayed isDone updates to resolved fields when explicit resolved metadata is missing', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + const { default: useComment } = await import('./components/CommentsLayer/use-comment.js'); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + const existingComment = useComment({ + commentId: 'c-1', + importedId: 'imp-1', + commentText: 'Old text', + fileId: 'doc-1', + creatorEmail: 'ada@example.com', + creatorName: 'Ada', + resolvedTime: null, + resolvedByEmail: null, + resolvedByName: null, + }); + commentsStoreStub.commentsList.value = [existingComment]; + commentsStoreStub.addComment.mockClear(); + superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; + + options.onCommentsUpdate({ + type: 'update', + comment: { + commentId: 'c-1', + importedId: 'imp-1', + isDone: true, + resolvedTime: null, + resolvedByEmail: null, + resolvedByName: null, + creatorEmail: 'imported@example.com', + creatorName: 'Imported Author', + }, + }); + + expect(commentsStoreStub.addComment).not.toHaveBeenCalled(); + expect(existingComment.resolvedTime).not.toBeNull(); + expect(existingComment.resolvedByEmail).toBe('imported@example.com'); + expect(existingComment.resolvedByName).toBe('Imported Author'); + + options.onCommentsUpdate({ + type: 'update', + comment: { + commentId: 'c-1', + importedId: 'imp-1', + isDone: false, + }, + }); + + expect(existingComment.resolvedTime).toBeNull(); + expect(existingComment.resolvedByEmail).toBeNull(); + expect(existingComment.resolvedByName).toBeNull(); + }); + it('maps replay-added elements to docxCommentJSON for imported comments', async () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 0fbd0ffa35..c77bb4687e 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -675,6 +675,24 @@ const REPLAY_MUTABLE_COMMENT_FIELDS = new Set([ 'docxCommentJSON', ]); +const applyReplayIsDoneResolutionFallback = (target, payload = {}) => { + if (!target || payload.isDone === undefined) return; + if (payload.resolvedTime != null || payload.resolvedByEmail != null || payload.resolvedByName != null) return; + + // Imported replay payloads often use `isDone` while resolved fields remain null. + // When resolved fields are not explicitly populated, derive sidebar/export state from `isDone`. + if (payload.isDone) { + target.resolvedTime = target.resolvedTime || Date.now(); + target.resolvedByEmail = target.resolvedByEmail || payload.creatorEmail || null; + target.resolvedByName = target.resolvedByName || payload.creatorName || null; + return; + } + + target.resolvedTime = null; + target.resolvedByEmail = null; + target.resolvedByName = null; +}; + const applyReplayUpdateToComment = (commentModel, payload, resolvedText) => { if (!commentModel || !payload) return; @@ -693,6 +711,8 @@ const applyReplayUpdateToComment = (commentModel, payload, resolvedText) => { if (resolvedText !== undefined) { commentModel.commentText = resolvedText; } + + applyReplayIsDoneResolutionFallback(commentModel, payload); }; const normalizeReplayCommentModelPayload = (payload = {}) => { @@ -703,6 +723,7 @@ const normalizeReplayCommentModelPayload = (payload = {}) => { if (!normalizedPayload.docxCommentJSON && Array.isArray(normalizedPayload.elements)) { normalizedPayload.docxCommentJSON = normalizedPayload.elements; } + applyReplayIsDoneResolutionFallback(normalizedPayload, normalizedPayload); return normalizedPayload; }; From 6fdc3e92dc959668345962337576721bfd06a450 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Wed, 4 Mar 2026 15:18:09 -0300 Subject: [PATCH 109/125] fix(superdoc): scope replay update active comment id to matched document thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - return the matched comment’s concrete id (prefer commentId) from replay update matching - avoid cross-document active-thread misselection when importedId overlaps across open documents - update replay regression coverage to assert setActiveComment receives the active document’s thread id --- packages/superdoc/src/SuperDoc.test.js | 7 ++++++- packages/superdoc/src/SuperDoc.vue | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 286953e307..beda71b39b 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -541,8 +541,11 @@ describe('SuperDoc.vue', () => { fileId: 'doc-2', }; - commentsStoreStub.commentsList.value = [existingComment, otherDocumentComment]; + // Keep the non-active-document comment first to ensure active selection does + // not fall back to global importedId matching. + commentsStoreStub.commentsList.value = [otherDocumentComment, existingComment]; commentsStoreStub.addComment.mockClear(); + commentsStoreStub.setActiveComment.mockClear(); superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; options.onCommentsUpdate({ @@ -553,6 +556,7 @@ describe('SuperDoc.vue', () => { commentText: 'Updated text', }, }); + await nextTick(); expect(commentsStoreStub.addComment).not.toHaveBeenCalled(); expect(commentsStoreStub.commentsList.value).toHaveLength(2); @@ -563,6 +567,7 @@ describe('SuperDoc.vue', () => { expect(existingComment.commentText).toBe('Updated text'); expect(otherDocumentComment.commentId).toBe('doc2-id'); expect(otherDocumentComment.commentText).toBe('Doc 2 text'); + expect(commentsStoreStub.setActiveComment).toHaveBeenCalledWith(superdocStub, 'old-runtime-id'); }); it('updates docxCommentJSON from replayed elements for imported comments', async () => { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index c77bb4687e..5c398d4f07 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -752,8 +752,9 @@ const onEditorCommentsUpdate = (params = {}) => { }); if (existingComment) { + const matchedCommentId = existingComment?.commentId ?? existingComment?.importedId ?? candidateId; return { - id: candidateId, + id: matchedCommentId != null ? String(matchedCommentId) : null, existingComment, }; } From 916a3d13889b435ac8693cebbccefb02a409fcb9 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 5 Mar 2026 11:44:41 -0300 Subject: [PATCH 110/125] fix(superdoc): stop replay comment updates from forcing active-thread reselection - only sync active comment when activeCommentId is explicitly present in the event payload - avoid inferring active selection from replay add/update events to prevent repeated focus/unfocus churn - preserve explicit active clear behavior on replay deletions - update replay update test expectation to reflect non-selecting replay events --- packages/superdoc/src/SuperDoc.test.js | 2 +- packages/superdoc/src/SuperDoc.vue | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index beda71b39b..63d974275a 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -567,7 +567,7 @@ describe('SuperDoc.vue', () => { expect(existingComment.commentText).toBe('Updated text'); expect(otherDocumentComment.commentId).toBe('doc2-id'); expect(otherDocumentComment.commentText).toBe('Doc 2 text'); - expect(commentsStoreStub.setActiveComment).toHaveBeenCalledWith(superdocStub, 'old-runtime-id'); + expect(commentsStoreStub.setActiveComment).not.toHaveBeenCalled(); }); it('updates docxCommentJSON from replayed elements for imported comments', async () => { diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 5c398d4f07..847c9d644a 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -730,6 +730,10 @@ const normalizeReplayCommentModelPayload = (payload = {}) => { const onEditorCommentsUpdate = (params = {}) => { // Set the active comment in the store let { activeCommentId, type, comment: commentPayload } = params; + // Only sync active state when the event explicitly requests it. + // Replay add/update events often omit activeCommentId; inferring it here can + // cause repeated focus toggles while replay emits batched updates. + let shouldSyncActiveComment = Object.prototype.hasOwnProperty.call(params, 'activeCommentId'); const resolveCommentEventIds = (payload) => { const ids = [payload?.importedId, payload?.commentId].filter(Boolean).map((value) => String(value)); return [...new Set(ids)]; @@ -794,10 +798,6 @@ const onEditorCommentsUpdate = (params = {}) => { const commentModel = useComment(commentPayload); addComment({ superdoc: proxy.$superdoc, comment: commentModel, skipEditorUpdate: true }); } - - if (!activeCommentId && id) { - activeCommentId = id; - } } if (COMMENT_EVENTS?.UPDATE && type === COMMENT_EVENTS.UPDATE && commentPayload) { @@ -812,10 +812,6 @@ const onEditorCommentsUpdate = (params = {}) => { const commentModel = useComment(normalizedPayload); addComment({ superdoc: proxy.$superdoc, comment: commentModel, skipEditorUpdate: true }); } - - if (!activeCommentId) { - activeCommentId = id; - } } } @@ -895,6 +891,7 @@ const onEditorCommentsUpdate = (params = {}) => { const activeCommentInActiveDocument = activeCommentModel ? isInActiveDocument(activeCommentModel) : false; if (activeCommentKey && removedCommentIds.has(activeCommentKey) && activeCommentInActiveDocument) { activeCommentId = null; + shouldSyncActiveComment = true; } } } @@ -906,13 +903,13 @@ const onEditorCommentsUpdate = (params = {}) => { nextTick(() => { if (pendingComment.value) return; - if (activeCommentId !== undefined) { + if (shouldSyncActiveComment) { commentsStore.setActiveComment(proxy.$superdoc, activeCommentId); } // Briefly suppress click-outside so the same click that selected the comment // highlight in the editor doesn't immediately deactivate it via the sidebar. // Reset after the event loop settles so subsequent outside clicks work normally. - if (activeCommentId !== undefined) { + if (shouldSyncActiveComment) { isCommentHighlighted.value = true; setTimeout(() => { isCommentHighlighted.value = false; From 6fd5e45e95bb23aafb4c262869215245d2c77291 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 5 Mar 2026 12:05:27 -0300 Subject: [PATCH 111/125] test: add missing test documents --- .../src/tests/data/diffing/diff_after11.docx | Bin 0 -> 17790 bytes .../src/tests/data/diffing/diff_before11.docx | Bin 0 -> 17684 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/super-editor/src/tests/data/diffing/diff_after11.docx create mode 100644 packages/super-editor/src/tests/data/diffing/diff_before11.docx diff --git a/packages/super-editor/src/tests/data/diffing/diff_after11.docx b/packages/super-editor/src/tests/data/diffing/diff_after11.docx new file mode 100644 index 0000000000000000000000000000000000000000..e071cda265e0815266f64e5c8716c8fa37bc8de0 GIT binary patch literal 17790 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 Bqx1j( literal 0 HcmV?d00001 diff --git a/packages/super-editor/src/tests/data/diffing/diff_before11.docx b/packages/super-editor/src/tests/data/diffing/diff_before11.docx new file mode 100644 index 0000000000000000000000000000000000000000..92f5796398da23a93ab0a02c1f0b437d1485c119 GIT binary patch literal 17684 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 Date: Thu, 5 Mar 2026 12:17:42 -0300 Subject: [PATCH 112/125] test: adjust diff replay test --- .../src/extensions/diffing/replayDiffs.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 1a6c2de3f4..51996b7827 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -41,12 +41,12 @@ const isAcceptableRemainingDiff = (diff) => { } const attrsDiff = diff.attrsDiff; const modifiedAttrs = Object.keys(attrsDiff?.modified ?? {}); - const allowedMetadataAttrs = new Set(['sdBlockRev']); - const hasOnlySdBlockRevAttrsDiff = - modifiedAttrs.every((key) => allowedMetadataAttrs.has(key)) && + const allowedParagraphMetadataAttrs = new Set(['sdBlockRev', 'textId', 'rsidR']); + const hasOnlyAllowedParagraphAttrsDiff = + modifiedAttrs.every((key) => allowedParagraphMetadataAttrs.has(key)) && Object.keys(attrsDiff?.added ?? {}).length === 0 && Object.keys(attrsDiff?.deleted ?? {}).length === 0; - if (diff.oldText !== diff.newText || (attrsDiff && !hasOnlySdBlockRevAttrsDiff)) { + if (diff.oldText !== diff.newText || (attrsDiff && !hasOnlyAllowedParagraphAttrsDiff)) { return false; } return (diff.contentDiff || []).every((change) => { From 9afedd88e224788b4c5272768c4ab42d7a9bed59 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 5 Mar 2026 13:52:29 -0300 Subject: [PATCH 113/125] fix(superdoc): update replay comment parent linkage fields on thread remap --- packages/superdoc/src/SuperDoc.test.js | 38 ++++++++++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 3 ++ 2 files changed, 41 insertions(+) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 63d974275a..9d83a89708 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -606,6 +606,44 @@ describe('SuperDoc.vue', () => { expect(existingComment.docxCommentJSON).toEqual(updatedElements); }); + it('updates replayed parent linkage fields for existing comments', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + const { default: useComment } = await import('./components/CommentsLayer/use-comment.js'); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + const existingComment = useComment({ + commentId: 'reply-1', + importedId: 'imp-reply-1', + parentCommentId: 'parent-old', + trackedChangeParentId: 'tc-parent-old', + fileId: 'doc-1', + commentText: 'Reply', + creatorEmail: 'ada@example.com', + creatorName: 'Ada', + }); + commentsStoreStub.commentsList.value = [existingComment]; + commentsStoreStub.addComment.mockClear(); + superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; + + options.onCommentsUpdate({ + type: 'update', + comment: { + commentId: 'reply-1', + importedId: 'imp-reply-1', + parentCommentId: 'parent-new', + trackedChangeParentId: 'tc-parent-new', + threadingParentCommentId: 'thread-parent-new', + }, + }); + + expect(commentsStoreStub.addComment).not.toHaveBeenCalled(); + expect(existingComment.parentCommentId).toBe('parent-new'); + expect(existingComment.trackedChangeParentId).toBe('tc-parent-new'); + expect(existingComment.threadingParentCommentId).toBe('thread-parent-new'); + }); + it('maps replayed isDone updates to resolved fields when explicit resolved metadata is missing', async () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 847c9d644a..579953d767 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -664,6 +664,9 @@ const onEditorCommentLocationsUpdate = (doc, { allCommentIds: activeThreadId, al const REPLAY_MUTABLE_COMMENT_FIELDS = new Set([ 'commentText', 'isInternal', + 'parentCommentId', + 'trackedChangeParentId', + 'threadingParentCommentId', 'trackedChange', 'trackedChangeType', 'trackedChangeText', From aad7a87caaa3698e322cc3d05f493943154b569c Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 5 Mar 2026 13:58:18 -0300 Subject: [PATCH 114/125] fix(superdoc): scope replay add deduplication to active document context --- packages/superdoc/src/SuperDoc.test.js | 31 ++++++++++++++++++++++++++ packages/superdoc/src/SuperDoc.vue | 8 +++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/packages/superdoc/src/SuperDoc.test.js b/packages/superdoc/src/SuperDoc.test.js index 9d83a89708..60548a9032 100644 --- a/packages/superdoc/src/SuperDoc.test.js +++ b/packages/superdoc/src/SuperDoc.test.js @@ -724,6 +724,37 @@ describe('SuperDoc.vue', () => { expect(addedComment.docxCommentJSON).toEqual(addedElements); }); + it('does not drop replay add when same id exists only in another document', async () => { + const superdocStub = createSuperdocStub(); + const wrapper = await mountComponent(superdocStub); + await nextTick(); + + const options = wrapper.findComponent(SuperEditorStub).props('options'); + commentsStoreStub.commentsList.value = [ + { commentId: 'shared-id', importedId: 'shared-imported-id', fileId: 'doc-2', commentText: 'Doc 2 comment' }, + ]; + commentsStoreStub.getComment.mockImplementation((id) => + commentsStoreStub.commentsList.value.find((comment) => comment.commentId === id || comment.importedId === id), + ); + commentsStoreStub.addComment.mockClear(); + superdocStub.activeEditor = { options: { documentId: 'doc-1' } }; + + options.onCommentsUpdate({ + type: 'add', + comment: { + commentId: 'shared-id', + importedId: 'shared-imported-id', + commentText: 'Doc 1 replay add', + }, + }); + + expect(commentsStoreStub.addComment).toHaveBeenCalledTimes(1); + const [{ comment: addedComment }] = commentsStoreStub.addComment.mock.calls[0]; + expect(addedComment.commentId).toBe('shared-id'); + expect(addedComment.importedId).toBe('shared-imported-id'); + expect(addedComment.fileId).toBe('doc-1'); + }); + it('removes replay-deleted comments when payload commentId is stale but importedId matches', async () => { const superdocStub = createSuperdocStub(); const wrapper = await mountComponent(superdocStub); diff --git a/packages/superdoc/src/SuperDoc.vue b/packages/superdoc/src/SuperDoc.vue index 579953d767..f69783e47e 100644 --- a/packages/superdoc/src/SuperDoc.vue +++ b/packages/superdoc/src/SuperDoc.vue @@ -741,7 +741,7 @@ const onEditorCommentsUpdate = (params = {}) => { const ids = [payload?.importedId, payload?.commentId].filter(Boolean).map((value) => String(value)); return [...new Set(ids)]; }; - const resolveUpdateCommentMatch = (payload) => { + const resolveDocumentScopedCommentMatch = (payload) => { const candidateIds = [payload?.importedId, payload?.commentId].filter(Boolean).map((value) => String(value)); const activeDocumentId = proxy.$superdoc?.activeEditor?.options?.documentId != null @@ -796,15 +796,15 @@ const onEditorCommentsUpdate = (params = {}) => { commentPayload.fileId = primaryDocumentId; } - const id = commentPayload.commentId || commentPayload.importedId; - if (id && !getComment(id)) { + const { id, existingComment } = resolveDocumentScopedCommentMatch(commentPayload); + if (id && !existingComment) { const commentModel = useComment(commentPayload); addComment({ superdoc: proxy.$superdoc, comment: commentModel, skipEditorUpdate: true }); } } if (COMMENT_EVENTS?.UPDATE && type === COMMENT_EVENTS.UPDATE && commentPayload) { - const { id, existingComment } = resolveUpdateCommentMatch(commentPayload); + const { id, existingComment } = resolveDocumentScopedCommentMatch(commentPayload); if (id) { const resolvedText = commentPayload.commentText || commentPayload.text; From c4da40813fc343cd3b67b60c4b6f9c54666d278a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 5 Mar 2026 17:15:47 -0300 Subject: [PATCH 115/125] fix(track-changes): preserve property attrs for ReplaceAroundStep updates --- .../extensions/diffing/replayDiffs.test.js | 103 ++++++++++++++++++ .../trackChangesHelpers/replaceAroundStep.js | 11 ++ 2 files changed, 114 insertions(+) diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js index 51996b7827..da49c016b3 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.test.js +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.test.js @@ -238,6 +238,104 @@ const expectTrackedReplayMarksHaveIds = async (beforeName, afterName) => { } }; +/** + * Reads the first table style id found in a document. + * + * @param {import('prosemirror-model').Node} doc + * @returns {string | null} + */ +const getFirstTableStyleId = (doc) => { + let tableStyleId = null; + doc.descendants((node) => { + if (node.type.name !== 'table') { + return true; + } + tableStyleId = node.attrs?.tableStyleId ?? null; + return false; + }); + return tableStyleId; +}; + +/** + * Reads normalized table row properties from the first table in document order. + * + * @param {import('prosemirror-model').Node} doc + * @returns {Array | null>} + */ +const getFirstTableRowProperties = (doc) => { + const rows = []; + let collectedFromFirstTable = false; + + doc.descendants((node) => { + if (node.type.name === 'table') { + if (collectedFromFirstTable) { + return false; + } + collectedFromFirstTable = true; + return true; + } + if (collectedFromFirstTable && node.type.name === 'tableRow') { + rows.push(node.attrs?.tableRowProperties ?? null); + } + return true; + }); + + return rows; +}; + +/** + * Replays fixture diffs and asserts first-table style fidelity. + * + * @param {string} beforeName DOCX fixture filename for the baseline. + * @param {string} afterName DOCX fixture filename for the updated doc. + * @param {boolean} applyTrackedChanges Whether replay should run in tracked mode. + * @returns {Promise} + */ +const expectReplayPreservesTableStyle = async (beforeName, afterName, applyTrackedChanges) => { + const testUser = { name: 'Test User', email: 'test@example.com' }; + const beforeEditor = await getEditorFromFixture(beforeName, applyTrackedChanges ? testUser : undefined); + const afterEditor = await getEditorFromFixture(afterName); + + try { + const diff = beforeEditor.commands.compareDocuments(afterEditor.state.doc, afterEditor.converter?.comments ?? []); + const success = beforeEditor.commands.replayDifferences(diff, { applyTrackedChanges }); + + expect(success).toBe(true); + if (applyTrackedChanges) { + expect(beforeEditor.commands.acceptAllTrackedChanges()).toBe(true); + } + + expect(getFirstTableStyleId(beforeEditor.state.doc)).toBe(getFirstTableStyleId(afterEditor.state.doc)); + expect(getFirstTableRowProperties(beforeEditor.state.doc)).toEqual( + getFirstTableRowProperties(afterEditor.state.doc), + ); + + const remainingTableStyleDiffs = computeDiff( + beforeEditor.state.doc, + afterEditor.state.doc, + beforeEditor.schema, + ).docDiffs.filter( + (entry) => + entry.nodeType === 'table' && entry.action === 'modified' && Boolean(entry.attrsDiff?.modified?.tableStyleId), + ); + expect(remainingTableStyleDiffs).toHaveLength(0); + const remainingTableRowPropertyDiffs = computeDiff( + beforeEditor.state.doc, + afterEditor.state.doc, + beforeEditor.schema, + ).docDiffs.filter( + (entry) => + entry.nodeType === 'tableRow' && + entry.action === 'modified' && + Object.keys(entry.attrsDiff?.added ?? {}).some((key) => key.startsWith('tableRowProperties.')), + ); + expect(remainingTableRowPropertyDiffs).toHaveLength(0); + } finally { + beforeEditor.destroy?.(); + afterEditor.destroy?.(); + } +}; + /** * Fixture pairs used for replay coverage. * @returns {Array<[string, string]>} @@ -335,6 +433,11 @@ describe('replayDiffs tracked-change ids', () => { await expectTrackedReplayMarksHaveIds('diff_before8.docx', 'diff_after8.docx'); }); }); +describe('replayDiffs table style', () => { + it('replays table style changes when tracked replay is enabled', async () => { + await expectReplayPreservesTableStyle('diff_before16.docx', 'diff_after16.docx', true); + }); +}); describe('investigate replay issues', () => { it('investigate diff_before10.docx', async () => { const beforeEditor = await getEditorFromFixture('diff_before10.docx'); diff --git a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceAroundStep.js b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceAroundStep.js index 5f11e1fa3f..0eee67ccb8 100644 --- a/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceAroundStep.js +++ b/packages/super-editor/src/extensions/track-changes/trackChangesHelpers/replaceAroundStep.js @@ -83,6 +83,17 @@ export const replaceAroundStep = ({ originalStep, originalStepIndex, }) => { + // Diff replay uses forceTrackChanges for consistency, but structural metadata updates + // (e.g. table style setNodeMarkup) are encoded as ReplaceAroundStep and cannot be + // represented as tracked text deletions/insertions. Apply them directly so replay + // does not drop non-text formatting changes. + if (tr.getMeta('forceTrackChanges')) { + if (!newTr.maybeStep(step).failed) { + map.appendMap(step.getMap()); + } + return; + } + const inputType = tr.getMeta('inputType'); const isBackspace = inputType === 'deleteContentBackward'; From 1bd04861e7d8923af0f4da8f9767a0d26240e02a Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 6 Mar 2026 13:07:35 -0300 Subject: [PATCH 116/125] feat: implement diffing for styles --- .../diffing/algorithm/styles-diffing.test.ts | 96 +++++++++++++++++++ .../diffing/algorithm/styles-diffing.ts | 90 +++++++++++++++++ .../extensions/diffing/computeDiff.test.js | 40 ++++++++ .../src/extensions/diffing/computeDiff.ts | 11 ++- .../src/extensions/diffing/diffing.js | 15 ++- 5 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.test.ts create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.ts diff --git a/packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.test.ts new file mode 100644 index 0000000000..ff6e57bfd8 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.test.ts @@ -0,0 +1,96 @@ +import { describe, expect, it } from 'vitest'; +import type { StylesDocumentProperties } from '@superdoc/style-engine/ooxml'; +import { diffStyles } from './styles-diffing'; + +/** + * Builds a minimal style snapshot for diff tests. + */ +function createStyleSnapshot(overrides: Record = {}) { + return { + docDefaults: {}, + latentStyles: {}, + styles: {}, + ...overrides, + } as StylesDocumentProperties; +} + +describe('diffStyles', () => { + it('returns null when style snapshots are effectively equal', () => { + const oldStyles = createStyleSnapshot({ + styles: { + Normal: { styleId: 'Normal', type: 'paragraph', name: 'Normal' }, + }, + }); + const newStyles = createStyleSnapshot({ + styles: { + Normal: { styleId: 'Normal', type: 'paragraph', name: 'Normal' }, + }, + }); + + expect(diffStyles(oldStyles, newStyles)).toBeNull(); + }); + + it('captures added, removed, and modified style definitions', () => { + const oldStyles = createStyleSnapshot({ + styles: { + Normal: { styleId: 'Normal', type: 'paragraph', name: 'Normal' }, + Heading1: { styleId: 'Heading1', type: 'paragraph', name: 'Heading 1' }, + }, + }); + const newStyles = createStyleSnapshot({ + styles: { + Normal: { styleId: 'Normal', type: 'paragraph', name: 'Normal Updated' }, + Heading2: { styleId: 'Heading2', type: 'paragraph', name: 'Heading 2' }, + }, + }); + + const result = diffStyles(oldStyles, newStyles); + + expect(result).not.toBeNull(); + expect(result?.addedStyles).toHaveProperty('Heading2'); + expect(result?.removedStyles).toHaveProperty('Heading1'); + expect(result?.modifiedStyles).toHaveProperty('Normal'); + expect(result?.modifiedStyles.Normal.modified.name).toEqual({ + from: 'Normal', + to: 'Normal Updated', + }); + }); + + it('captures doc defaults and latent styles changes', () => { + const oldStyles = createStyleSnapshot({ + docDefaults: { + runProperties: { + bold: false, + }, + }, + latentStyles: { + defQFormat: false, + }, + }); + const newStyles = createStyleSnapshot({ + docDefaults: { + runProperties: { + bold: true, + }, + }, + latentStyles: { + defQFormat: true, + }, + }); + + const result = diffStyles(oldStyles, newStyles); + + expect(result).not.toBeNull(); + expect(result?.docDefaultsDiff?.modified['runProperties.bold']).toEqual({ + from: false, + to: true, + }); + expect(result?.latentStylesDiff?.modified.defQFormat).toEqual({ + from: false, + to: true, + }); + expect(result?.addedStyles).toEqual({}); + expect(result?.removedStyles).toEqual({}); + expect(result?.modifiedStyles).toEqual({}); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.ts new file mode 100644 index 0000000000..e72664bf8a --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/styles-diffing.ts @@ -0,0 +1,90 @@ +import type { StyleDefinition, StylesDocumentProperties } from '@superdoc/style-engine/ooxml'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; + +/** + * Structured diff for style document metadata and style definitions. + */ +export interface StylesDiff { + /** Diff for `docDefaults`. */ + docDefaultsDiff: AttributesDiff | null; + /** Diff for `latentStyles`. */ + latentStylesDiff: AttributesDiff | null; + /** Styles present only in the new style snapshot. */ + addedStyles: Record; + /** Styles present only in the old style snapshot. */ + removedStyles: Record; + /** Diffs for style definitions present in both snapshots. */ + modifiedStyles: Record; +} + +function hasOwnStyle(styleMap: Record, styleId: string): boolean { + return Object.prototype.hasOwnProperty.call(styleMap, styleId); +} + +/** + * Computes a diff between two style snapshots. + * + * @param oldStyles Previous style snapshot. + * @param newStyles Updated style snapshot. + * @returns Style diff or `null` when no changes are detected. + */ +export function diffStyles( + oldStyles: StylesDocumentProperties | null | undefined, + newStyles: StylesDocumentProperties | null | undefined, +): StylesDiff | null { + const oldStyleMap = oldStyles?.styles ?? {}; + const newStyleMap = newStyles?.styles ?? {}; + + const addedStyles: Record = {}; + const removedStyles: Record = {}; + const modifiedStyles: Record = {}; + + for (const [styleId, styleDef] of Object.entries(newStyleMap)) { + if (!hasOwnStyle(oldStyleMap, styleId)) { + addedStyles[styleId] = styleDef; + } + } + + for (const [styleId, styleDef] of Object.entries(oldStyleMap)) { + if (!hasOwnStyle(newStyleMap, styleId)) { + removedStyles[styleId] = styleDef; + continue; + } + + const attrsDiff = getAttributesDiff( + styleDef as unknown as Record, + newStyleMap[styleId] as unknown as Record, + ); + if (attrsDiff) { + modifiedStyles[styleId] = attrsDiff; + } + } + + const docDefaultsDiff = getAttributesDiff( + (oldStyles?.docDefaults ?? {}) as unknown as Record, + (newStyles?.docDefaults ?? {}) as unknown as Record, + ); + const latentStylesDiff = getAttributesDiff( + (oldStyles?.latentStyles ?? {}) as unknown as Record, + (newStyles?.latentStyles ?? {}) as unknown as Record, + ); + + const hasChanges = + Boolean(docDefaultsDiff) || + Boolean(latentStylesDiff) || + Object.keys(addedStyles).length > 0 || + Object.keys(removedStyles).length > 0 || + Object.keys(modifiedStyles).length > 0; + + if (!hasChanges) { + return null; + } + + return { + docDefaultsDiff, + latentStylesDiff, + addedStyles, + removedStyles, + modifiedStyles, + }; +} diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index 25ab7b5e4e..2cdb781720 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -376,4 +376,44 @@ describe('Diff', () => { expect(trackedMarkDiffs).toHaveLength(0); }); + + it('returns null style diffs when style snapshots are omitted', async () => { + const { doc, schema } = await getDocument('diff_before8.docx'); + const diff = computeDiff(doc, doc, schema); + + expect(diff.docDiffs).toHaveLength(0); + expect(diff.commentDiffs).toHaveLength(0); + expect(diff.stylesDiff).toBeNull(); + }); + + it('includes style diffs when old/new style snapshots differ', async () => { + const { doc, schema } = await getDocument('diff_before8.docx'); + const oldStyles = { + docDefaults: {}, + latentStyles: {}, + styles: { + Normal: { styleId: 'Normal', type: 'paragraph', name: 'Normal' }, + }, + }; + const newStyles = { + docDefaults: {}, + latentStyles: {}, + styles: { + Normal: { styleId: 'Normal', type: 'paragraph', name: 'Normal Updated' }, + Heading1: { styleId: 'Heading1', type: 'paragraph', name: 'Heading 1' }, + }, + }; + + const diff = computeDiff(doc, doc, schema, [], [], oldStyles, newStyles); + + expect(diff.docDiffs).toHaveLength(0); + expect(diff.commentDiffs).toHaveLength(0); + expect(diff.stylesDiff).not.toBeNull(); + expect(diff.stylesDiff?.addedStyles).toHaveProperty('Heading1'); + expect(diff.stylesDiff?.removedStyles).toEqual({}); + expect(diff.stylesDiff?.modifiedStyles.Normal.modified.name).toEqual({ + from: 'Normal', + to: 'Normal Updated', + }); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts index 2b1933e1cb..f1d19960ea 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.ts +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -1,6 +1,8 @@ import type { Node as PMNode, Schema } from 'prosemirror-model'; +import type { StylesDocumentProperties } from '@superdoc/style-engine/ooxml'; import { diffComments, type CommentInput, type CommentDiff } from './algorithm/comment-diffing'; import { diffNodes, normalizeNodes, type NodeDiff } from './algorithm/generic-diffing'; +import { diffStyles, type StylesDiff } from './algorithm/styles-diffing'; /** * Result payload for document diffing. @@ -10,6 +12,8 @@ export interface DiffResult { docDiffs: NodeDiff[]; /** Diffs computed from comment content and metadata. */ commentDiffs: CommentDiff[]; + /** Diffs computed from OOXML styles metadata. */ + stylesDiff: StylesDiff | null; } /** @@ -27,7 +31,9 @@ export interface DiffResult { * @param schema The schema used to interpret document nodes. * @param oldComments Comment list from the old document. * @param newComments Comment list from the new document. - * @returns Object containing document and comment diffs. + * @param oldStyles OOXML style snapshot from the old document. + * @param newStyles OOXML style snapshot from the new document. + * @returns Object containing document, comment, and style diffs. */ export function computeDiff( oldPmDoc: PMNode, @@ -35,9 +41,12 @@ export function computeDiff( schema: Schema, oldComments: CommentInput[] = [], newComments: CommentInput[] = [], + oldStyles: StylesDocumentProperties | null | undefined = null, + newStyles: StylesDocumentProperties | null | undefined = null, ): DiffResult { return { docDiffs: diffNodes(normalizeNodes(oldPmDoc), normalizeNodes(newPmDoc)), commentDiffs: diffComments(oldComments, newComments, schema), + stylesDiff: diffStyles(oldStyles, newStyles), }; } diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 6e6c065819..722e2d0d4b 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -18,15 +18,26 @@ export const Diffing = Extension.create({ * * @param {import('prosemirror-model').Node} updatedDocument * @param {import('./algorithm/comment-diffing.ts').CommentInput[]} [updatedComments] + * @param {import('@superdoc/style-engine/ooxml').StylesDocumentProperties | null} [updatedStyles] * @returns {import('./computeDiff.ts').DiffResult} */ compareDocuments: - (updatedDocument, updatedComments) => + (updatedDocument, updatedComments, updatedStyles) => ({ state, tr }) => { tr.setMeta('preventDispatch', true); const currentComments = this.editor.converter?.comments ?? []; const nextComments = updatedComments === undefined ? currentComments : updatedComments; - const diffs = computeDiff(state.doc, updatedDocument, state.schema, currentComments, nextComments); + const currentStyles = this.editor.converter?.translatedLinkedStyles ?? null; + const nextStyles = updatedStyles === undefined ? currentStyles : updatedStyles; + const diffs = computeDiff( + state.doc, + updatedDocument, + state.schema, + currentComments, + nextComments, + currentStyles, + nextStyles, + ); return diffs; }, From f8f49415206302f7499abcb64b54985407776c31 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 6 Mar 2026 14:37:21 -0300 Subject: [PATCH 117/125] feat: implement replay for style differences --- .../src/core/helpers/styles-xml-helpers.ts | 197 ++++++++++++++++++ .../diffing/replay/replay-style-utils.test.ts | 53 +++++ .../diffing/replay/replay-style-utils.ts | 158 ++++++++++++++ .../diffing/replay/replay-styles.test.ts | 140 +++++++++++++ .../diffing/replay/replay-styles.ts | 125 +++++++++++ .../src/extensions/diffing/replayDiffs.ts | 18 +- .../src/dev/components/SuperdocDev.vue | 3 +- 7 files changed, 690 insertions(+), 4 deletions(-) create mode 100644 packages/super-editor/src/core/helpers/styles-xml-helpers.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-style-utils.test.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-style-utils.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-styles.test.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-styles.ts diff --git a/packages/super-editor/src/core/helpers/styles-xml-helpers.ts b/packages/super-editor/src/core/helpers/styles-xml-helpers.ts new file mode 100644 index 0000000000..380c31eeb7 --- /dev/null +++ b/packages/super-editor/src/core/helpers/styles-xml-helpers.ts @@ -0,0 +1,197 @@ +import { translator as docDefaultsTranslator } from '../super-converter/v3/handlers/w/docDefaults/docDefaults-translator.js'; +import { translator as latentStylesTranslator } from '../super-converter/v3/handlers/w/latentStyles/latentStyles-translator.js'; +import { translator as styleTranslator } from '../super-converter/v3/handlers/w/style/style-translator.js'; +import type { StylesDiff } from '../../extensions/diffing/algorithm/styles-diffing'; +import type { XmlElement } from '../../document-api-adapters/helpers/sections-xml.js'; + +type ConverterWithStyles = { + convertedXml?: Record; + translatedLinkedStyles?: { + docDefaults?: Record; + latentStyles?: Record; + styles?: Record; + } | null; +}; + +/** + * Resolves the `w:styles` root element from `word/styles.xml`. + * + * @param converter Converter state containing converted XML parts. + * @returns Styles root element, or `null` when unavailable. + */ +function findStylesRoot(converter: ConverterWithStyles): XmlElement | null { + const stylesPart = converter?.convertedXml?.['word/styles.xml'] as XmlElement | undefined; + if (!stylesPart?.elements) { + return null; + } + const root = stylesPart.elements.find((element) => element.name === 'w:styles'); + if (!root) { + return null; + } + if (!root.elements) { + root.elements = []; + } + return root; +} + +/** + * Replaces or inserts singleton style child nodes (for example docDefaults). + * + * @param root `w:styles` root element. + * @param name XML node name to replace/insert. + * @param nextNode Next node value, or `undefined` to remove it. + */ +function replaceSingletonElement(root: XmlElement, name: string, nextNode: XmlElement | undefined): void { + if (!root.elements) { + root.elements = []; + } + const existingIndex = root.elements.findIndex((element) => element.name === name); + + if (!nextNode) { + if (existingIndex >= 0) { + root.elements.splice(existingIndex, 1); + } + return; + } + + if (existingIndex >= 0) { + root.elements[existingIndex] = nextNode; + return; + } + + const docDefaultsIndex = root.elements.findIndex((element) => element.name === 'w:docDefaults'); + const latentStylesIndex = root.elements.findIndex((element) => element.name === 'w:latentStyles'); + if (name === 'w:docDefaults') { + root.elements.unshift(nextNode); + return; + } + if (name === 'w:latentStyles') { + const insertIndex = docDefaultsIndex >= 0 ? docDefaultsIndex + 1 : 0; + root.elements.splice(insertIndex, 0, nextNode); + return; + } + const insertIndex = latentStylesIndex >= 0 ? latentStylesIndex + 1 : root.elements.length; + root.elements.splice(insertIndex, 0, nextNode); +} + +/** + * Extracts the style ID from a `w:style` node. + * + * @param node XML style node. + * @returns Style ID as string, or `null` when missing. + */ +function getStyleId(node: XmlElement): string | null { + const value = node?.attributes?.['w:styleId']; + return value == null ? null : String(value); +} + +/** + * Decodes a translated style definition back to a `w:style` XML node. + * + * @param styleDef Translated style definition object. + * @returns Decoded XML node, or `undefined` when decode fails. + */ +function decodeStyleNode(styleDef: unknown): XmlElement | undefined { + return styleTranslator.decode({ + node: { + attrs: { + style: styleDef, + }, + } as any, + }) as XmlElement | undefined; +} + +/** + * Synchronizes replayed style-diff mutations into `word/styles.xml`. + * + * This helper intentionally updates only style sections touched by the replay + * diff to avoid rewriting unrelated XML nodes. + * + * @param converter Converter state to mutate. + * @param stylesDiff Style diff payload used to determine XML updates. + * @returns `true` when the styles part was found and updated. + */ +export function syncStylesDiffToConvertedXml(converter: ConverterWithStyles, stylesDiff: StylesDiff | null): boolean { + if (!stylesDiff) { + return false; + } + + const root = findStylesRoot(converter); + if (!root) { + return false; + } + + const translated = converter.translatedLinkedStyles ?? {}; + const translatedStyles = translated.styles ?? {}; + + if (stylesDiff.docDefaultsDiff) { + const docDefaultsNode = docDefaultsTranslator.decode({ + node: { + attrs: { + docDefaults: translated.docDefaults, + }, + } as any, + }) as XmlElement | undefined; + replaceSingletonElement(root, 'w:docDefaults', docDefaultsNode); + } + + if (stylesDiff.latentStylesDiff) { + const latentStylesNode = latentStylesTranslator.decode({ + node: { + attrs: { + latentStyles: translated.latentStyles ?? {}, + }, + } as any, + }) as XmlElement | undefined; + replaceSingletonElement(root, 'w:latentStyles', latentStylesNode); + } + + const removedStyleIds = new Set(Object.keys(stylesDiff.removedStyles ?? {})); + if (removedStyleIds.size > 0 && root.elements) { + root.elements = root.elements.filter((element) => { + if (element.name !== 'w:style') { + return true; + } + const styleId = getStyleId(element); + return !styleId || !removedStyleIds.has(styleId); + }); + } + + const upsertStyleIds = [ + ...Object.keys(stylesDiff.modifiedStyles ?? {}), + ...Object.keys(stylesDiff.addedStyles ?? {}), + ]; + const uniqueUpsertStyleIds = [...new Set(upsertStyleIds)]; + if (uniqueUpsertStyleIds.length === 0) { + return true; + } + + if (!root.elements) { + root.elements = []; + } + + for (const styleId of uniqueUpsertStyleIds) { + const styleDef = translatedStyles[styleId]; + if (!styleDef) { + continue; + } + + const nextStyleNode = decodeStyleNode(styleDef); + if (!nextStyleNode) { + continue; + } + + const existingIndex = root.elements.findIndex( + (element) => element.name === 'w:style' && getStyleId(element) === String(styleId), + ); + + if (existingIndex >= 0) { + root.elements[existingIndex] = nextStyleNode; + continue; + } + + root.elements.push(nextStyleNode); + } + + return true; +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-style-utils.test.ts b/packages/super-editor/src/extensions/diffing/replay/replay-style-utils.test.ts new file mode 100644 index 0000000000..813ccb4c11 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-style-utils.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest'; +import { applyAttributesDiff } from './replay-style-utils'; + +describe('applyAttributesDiff', () => { + it('applies added/modified/deleted dotted-path changes and prunes empty parents', () => { + const target = { + section: { + removeA: 1, + removeB: 2, + }, + keep: 1, + }; + + const changed = applyAttributesDiff(target, { + added: { + 'added.branch.value': 'ok', + }, + deleted: { + 'section.removeA': 1, + 'section.removeB': 2, + }, + modified: { + keep: { + from: 1, + to: 2, + }, + 'nested.path': { + from: undefined, + to: true, + }, + }, + }); + + expect(changed).toBe(true); + expect(target).toEqual({ + keep: 2, + nested: { + path: true, + }, + added: { + branch: { + value: 'ok', + }, + }, + }); + }); + + it('returns false when diff is null', () => { + const target = { value: 1 }; + expect(applyAttributesDiff(target, null)).toBe(false); + expect(target).toEqual({ value: 1 }); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-style-utils.ts b/packages/super-editor/src/extensions/diffing/replay/replay-style-utils.ts new file mode 100644 index 0000000000..279c03ee0b --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-style-utils.ts @@ -0,0 +1,158 @@ +import type { AttributesDiff } from '../algorithm/attributes-diffing'; + +/** + * Creates a deep clone for object-like values while preserving primitives. + * + * @typeParam T Value type. + * @param value Value to clone. + * @returns Cloned value for objects, or the original primitive. + */ +function cloneValue(value: T): T { + if (value === null || typeof value !== 'object') { + return value; + } + return structuredClone(value); +} + +/** + * Checks whether a value is a plain record-like object. + * + * @param value Value to inspect. + * @returns `true` when value is a non-array object. + */ +function isRecord(value: unknown): value is Record { + return Boolean(value) && typeof value === 'object' && !Array.isArray(value); +} + +/** + * Ensures all parent segments in a dotted path exist as objects. + * + * @param target Root object. + * @param pathSegments Parent path segments. + * @returns The deepest parent object for subsequent writes. + */ +function ensureParentObject(target: Record, pathSegments: string[]): Record { + let current: Record = target; + + for (const segment of pathSegments) { + const next = current[segment]; + if (!isRecord(next)) { + current[segment] = {}; + } + current = current[segment] as Record; + } + + return current; +} + +/** + * Sets a value at a dotted path, creating intermediate parents when needed. + * + * @param target Root object to mutate. + * @param path Dotted path (for example `a.b.c`). + * @param value Value to assign. + */ +function setByPath(target: Record, path: string, value: unknown): void { + const segments = path.split('.').filter(Boolean); + if (segments.length === 0) { + return; + } + const leaf = segments.pop()!; + const parent = ensureParentObject(target, segments); + parent[leaf] = cloneValue(value); +} + +/** + * Removes now-empty parent objects after a leaf deletion. + * + * @param root Root object. + * @param segments Parent segments that lead to the removed leaf. + */ +function pruneEmptyParents(root: Record, segments: string[]): void { + for (let idx = segments.length - 1; idx >= 0; idx -= 1) { + const parentPath = segments.slice(0, idx); + const currentKey = segments[idx]; + const parent = + parentPath.length === 0 + ? root + : (parentPath.reduce | undefined>((acc, key) => { + if (!acc || !isRecord(acc[key])) { + return undefined; + } + return acc[key] as Record; + }, root) ?? undefined); + + if (!parent || !isRecord(parent[currentKey])) { + return; + } + + if (Object.keys(parent[currentKey] as Record).length === 0) { + delete parent[currentKey]; + continue; + } + + return; + } +} + +/** + * Deletes a value at a dotted path and prunes empty ancestors. + * + * @param target Root object to mutate. + * @param path Dotted path to remove. + */ +function deleteByPath(target: Record, path: string): void { + const segments = path.split('.').filter(Boolean); + if (segments.length === 0) { + return; + } + const leaf = segments.pop()!; + const parent = + segments.length === 0 + ? target + : (segments.reduce | undefined>((acc, key) => { + if (!acc || !isRecord(acc[key])) { + return undefined; + } + return acc[key] as Record; + }, target) ?? undefined); + + if (!parent) { + return; + } + + delete parent[leaf]; + pruneEmptyParents(target, segments); +} + +/** + * Applies an attributes diff payload to a target object in-place. + * + * @param target Target object to mutate. + * @param diff Attributes diff to apply. + * @returns `true` when at least one mutation was applied. + */ +export function applyAttributesDiff(target: Record, diff: AttributesDiff | null | undefined): boolean { + if (!diff) { + return false; + } + + let changed = false; + + for (const [path, value] of Object.entries(diff.added ?? {})) { + setByPath(target, path, value); + changed = true; + } + + for (const [path, value] of Object.entries(diff.modified ?? {})) { + setByPath(target, path, value.to); + changed = true; + } + + for (const path of Object.keys(diff.deleted ?? {})) { + deleteByPath(target, path); + changed = true; + } + + return changed; +} diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-styles.test.ts b/packages/super-editor/src/extensions/diffing/replay/replay-styles.test.ts new file mode 100644 index 0000000000..ac323ffe8e --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-styles.test.ts @@ -0,0 +1,140 @@ +import { describe, expect, it, vi } from 'vitest'; +import { replayStyles } from './replay-styles'; + +describe('replayStyles', () => { + it('replays style diffs, syncs styles.xml, and emits style update event', () => { + const converter = { + translatedLinkedStyles: { + docDefaults: { + runProperties: { + bold: false, + }, + }, + latentStyles: { + defQFormat: false, + }, + styles: { + Normal: { + styleId: 'Normal', + type: 'paragraph', + name: 'Normal', + }, + Gone: { + styleId: 'Gone', + type: 'paragraph', + name: 'Remove me', + }, + }, + }, + convertedXml: { + 'word/styles.xml': { + elements: [ + { + name: 'w:styles', + attributes: { + 'mc:Ignorable': 'w14', + }, + elements: [ + { name: 'w:docDefaults', elements: [] }, + { name: 'w:latentStyles', elements: [] }, + { name: 'w:style', attributes: { 'w:styleId': 'Normal' }, elements: [] }, + { name: 'w:style', attributes: { 'w:styleId': 'Gone' }, elements: [] }, + { name: 'w:customUnknown', attributes: { keep: 'yes' }, elements: [] }, + ], + }, + ], + }, + }, + promoteToGuid: vi.fn(() => 'guid-1'), + documentModified: false, + }; + const editor = { + converter, + emit: vi.fn(), + }; + + const result = replayStyles({ + stylesDiff: { + docDefaultsDiff: { + added: {}, + deleted: {}, + modified: { + 'runProperties.bold': { from: false, to: true }, + }, + }, + latentStylesDiff: { + added: {}, + deleted: {}, + modified: { + defQFormat: { from: false, to: true }, + }, + }, + addedStyles: { + Added: { + styleId: 'Added', + type: 'paragraph', + name: 'Added Style', + }, + }, + removedStyles: { + Gone: { + styleId: 'Gone', + type: 'paragraph', + name: 'Remove me', + }, + }, + modifiedStyles: { + Normal: { + added: { + 'runProperties.italic': true, + }, + deleted: {}, + modified: { + name: { from: 'Normal', to: 'Normal Updated' }, + }, + }, + }, + }, + editor, + }); + + expect(result.applied).toBe(1); + expect(result.skipped).toBe(0); + expect(editor.emit).toHaveBeenCalledWith('stylesDefaultsChanged'); + expect(converter.documentModified).toBe(true); + expect(converter.promoteToGuid).toHaveBeenCalledTimes(1); + + expect(converter.translatedLinkedStyles.docDefaults.runProperties.bold).toBe(true); + expect(converter.translatedLinkedStyles.latentStyles.defQFormat).toBe(true); + expect(converter.translatedLinkedStyles.styles.Gone).toBeUndefined(); + expect(converter.translatedLinkedStyles.styles.Added).toBeDefined(); + expect(converter.translatedLinkedStyles.styles.Normal.name).toBe('Normal Updated'); + expect(converter.translatedLinkedStyles.styles.Normal.runProperties.italic).toBe(true); + + const stylesRoot = converter.convertedXml['word/styles.xml'].elements[0]; + const styleIds = stylesRoot.elements + .filter((element) => element.name === 'w:style') + .map((element) => element.attributes?.['w:styleId']); + expect(styleIds).toContain('Normal'); + expect(styleIds).toContain('Added'); + expect(styleIds).not.toContain('Gone'); + expect(stylesRoot.elements.some((element) => element.name === 'w:customUnknown')).toBe(true); + }); + + it('skips when converter is not available', () => { + const result = replayStyles({ + stylesDiff: { + docDefaultsDiff: null, + latentStylesDiff: null, + addedStyles: {}, + removedStyles: {}, + modifiedStyles: {}, + }, + editor: undefined, + }); + + expect(result.applied).toBe(0); + expect(result.skipped).toBe(1); + expect(result.warnings[0]).toContain('converter is unavailable'); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-styles.ts b/packages/super-editor/src/extensions/diffing/replay/replay-styles.ts new file mode 100644 index 0000000000..34aa01cee6 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-styles.ts @@ -0,0 +1,125 @@ +import { syncStylesDiffToConvertedXml } from '../../../core/helpers/styles-xml-helpers'; +import { applyAttributesDiff } from './replay-style-utils'; +import { ReplayResult } from './replay-types'; + +type ReplayStyleEditor = { + emit?: (event: string, payload?: unknown) => void; + converter?: { + translatedLinkedStyles?: { + docDefaults?: Record; + latentStyles?: Record; + styles?: Record>; + } | null; + convertedXml?: Record; + documentModified?: boolean; + promoteToGuid?: () => string; + } | null; +}; + +/** + * Initializes the translated styles snapshot structure on the converter. + * + * @param editor Replay editor context. + * @returns Initialized translated styles object, or `null` when no converter exists. + */ +function ensureTranslatedStyles(editor: ReplayStyleEditor) { + const converter = editor.converter; + if (!converter) { + return null; + } + + if (!converter.translatedLinkedStyles) { + converter.translatedLinkedStyles = {}; + } + if (!converter.translatedLinkedStyles.docDefaults) { + converter.translatedLinkedStyles.docDefaults = {}; + } + if (!converter.translatedLinkedStyles.latentStyles) { + converter.translatedLinkedStyles.latentStyles = {}; + } + if (!converter.translatedLinkedStyles.styles) { + converter.translatedLinkedStyles.styles = {}; + } + return converter.translatedLinkedStyles; +} + +/** + * Replays style metadata diffs directly into the converter's translated style snapshot. + * + * The resulting style snapshot is then synchronized back into `word/styles.xml`. + * + * @param params Replay parameters. + * @param params.stylesDiff Style diff payload to apply. + * @param params.editor Editor context containing converter and emitter. + * @returns Replay summary with applied/skipped counts and warnings. + */ +export function replayStyles({ + stylesDiff, + editor, +}: { + stylesDiff: import('../algorithm/styles-diffing').StylesDiff | null; + editor?: ReplayStyleEditor; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + if (!stylesDiff) { + return result; + } + + if (!editor?.converter) { + result.skipped += 1; + result.warnings.push('Style replay skipped: editor converter is unavailable.'); + return result; + } + + const translated = ensureTranslatedStyles(editor); + if (!translated) { + result.skipped += 1; + result.warnings.push('Style replay skipped: translated style state is unavailable.'); + return result; + } + + let changed = false; + changed = applyAttributesDiff(translated.docDefaults!, stylesDiff.docDefaultsDiff) || changed; + changed = applyAttributesDiff(translated.latentStyles!, stylesDiff.latentStylesDiff) || changed; + + for (const styleId of Object.keys(stylesDiff.removedStyles ?? {})) { + if (Object.prototype.hasOwnProperty.call(translated.styles!, styleId)) { + delete translated.styles![styleId]; + changed = true; + } + } + + for (const [styleId, styleDef] of Object.entries(stylesDiff.addedStyles ?? {})) { + translated.styles![styleId] = structuredClone(styleDef as Record); + changed = true; + } + + for (const [styleId, diff] of Object.entries(stylesDiff.modifiedStyles ?? {})) { + const styleTarget = translated.styles?.[styleId]; + if (!styleTarget) { + result.skipped += 1; + result.warnings.push(`Style replay skipped for "${styleId}": style was not found in translated styles.`); + continue; + } + changed = applyAttributesDiff(styleTarget, diff) || changed; + } + + if (!changed) { + return result; + } + + syncStylesDiffToConvertedXml(editor.converter, stylesDiff); + editor.converter.documentModified = true; + if (typeof editor.converter.promoteToGuid === 'function') { + editor.converter.promoteToGuid(); + } + editor.emit?.('stylesDefaultsChanged'); + + result.applied += 1; + return result; +} diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index 18b208c95c..5ade87d21a 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -15,6 +15,7 @@ export type ReplayDiffsResult = { import { replayDocDiffs } from './replay/replay-doc'; import { replayComments } from './replay/replay-comments'; +import { replayStyles } from './replay/replay-styles'; type ReplayDiffsParams = { tr: import('prosemirror-state').Transaction; @@ -26,6 +27,16 @@ type ReplayDiffsParams = { options?: { documentId?: string | null; }; + converter?: { + translatedLinkedStyles?: { + docDefaults?: Record; + latentStyles?: Record; + styles?: Record>; + } | null; + convertedXml?: Record; + documentModified?: boolean; + promoteToGuid?: () => string; + } | null; }; }; @@ -43,11 +54,12 @@ type ReplayDiffsParams = { export function replayDiffs({ tr, diff, schema, comments = [], editor }: ReplayDiffsParams): ReplayDiffsResult { const docReplay = replayDocDiffs({ tr, docDiffs: diff.docDiffs, schema }); const commentsReplay = replayComments({ comments, commentDiffs: diff.commentDiffs, editor }); + const stylesReplay = replayStyles({ stylesDiff: diff.stylesDiff, editor }); return { tr, - appliedDiffs: docReplay.applied + commentsReplay.applied, - skippedDiffs: docReplay.skipped + commentsReplay.skipped, - warnings: [...docReplay.warnings, ...commentsReplay.warnings], + appliedDiffs: docReplay.applied + commentsReplay.applied + stylesReplay.applied, + skippedDiffs: docReplay.skipped + commentsReplay.skipped + stylesReplay.skipped, + warnings: [...docReplay.warnings, ...commentsReplay.warnings, ...stylesReplay.warnings], }; } diff --git a/packages/superdoc/src/dev/components/SuperdocDev.vue b/packages/superdoc/src/dev/components/SuperdocDev.vue index a60da28917..4824f80d51 100644 --- a/packages/superdoc/src/dev/components/SuperdocDev.vue +++ b/packages/superdoc/src/dev/components/SuperdocDev.vue @@ -283,7 +283,8 @@ const handleCompareFile = async (event) => { const compareDoc = compareEditor.state.doc; const compareComments = compareEditor.converter?.comments ?? []; - const diff = editor.commands.compareDocuments(compareDoc, compareComments); + const compareTranslatedLinkedStyles = compareEditor.converter?.translatedLinkedStyles; + const diff = editor.commands.compareDocuments(compareDoc, compareComments, compareTranslatedLinkedStyles); const userToApply = editor.options?.user ?? user; editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); } finally { From 0c4019003fe12f1e1e1bbfa44097d3448df18edb Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 6 Mar 2026 14:56:19 -0300 Subject: [PATCH 118/125] feat: implement diffing for numbering --- .../algorithm/numbering-diffing.test.ts | 93 +++++++++++++++++++ .../diffing/algorithm/numbering-diffing.ts | 24 +++++ .../extensions/diffing/computeDiff.test.js | 57 ++++++++++++ .../src/extensions/diffing/computeDiff.ts | 12 ++- .../src/extensions/diffing/diffing.js | 7 +- .../src/dev/components/SuperdocDev.vue | 8 +- 6 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.test.ts create mode 100644 packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.ts diff --git a/packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.test.ts b/packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.test.ts new file mode 100644 index 0000000000..ab48df2b0c --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it } from 'vitest'; +import type { NumberingProperties } from '@superdoc/style-engine/ooxml'; +import { diffNumbering } from './numbering-diffing'; + +/** + * Builds a minimal numbering snapshot for diff tests. + */ +function createNumberingSnapshot(overrides: Record = {}) { + return { + abstracts: {}, + definitions: {}, + ...overrides, + } as NumberingProperties; +} + +describe('diffNumbering', () => { + it('returns null when numbering snapshots are effectively equal', () => { + const oldNumbering = createNumberingSnapshot({ + abstracts: { + '1': { abstractNumId: 1, name: 'Default' }, + }, + definitions: { + '10': { numId: 10, abstractNumId: 1 }, + }, + }); + const newNumbering = createNumberingSnapshot({ + abstracts: { + '1': { abstractNumId: 1, name: 'Default' }, + }, + definitions: { + '10': { numId: 10, abstractNumId: 1 }, + }, + }); + + expect(diffNumbering(oldNumbering, newNumbering)).toBeNull(); + }); + + it('captures added and removed numbering definitions', () => { + const oldNumbering = createNumberingSnapshot({ + definitions: { + '10': { numId: 10, abstractNumId: 1 }, + }, + }); + const newNumbering = createNumberingSnapshot({ + definitions: { + '11': { numId: 11, abstractNumId: 2 }, + }, + }); + + const result = diffNumbering(oldNumbering, newNumbering); + + expect(result).not.toBeNull(); + expect(result?.added['definitions.11.numId']).toBe(11); + expect(result?.deleted['definitions.10.numId']).toBe(10); + }); + + it('captures modified nested numbering properties', () => { + const oldNumbering = createNumberingSnapshot({ + abstracts: { + '1': { + abstractNumId: 1, + levels: { + '0': { + ilvl: 0, + lvlText: '%1.', + }, + }, + }, + }, + }); + const newNumbering = createNumberingSnapshot({ + abstracts: { + '1': { + abstractNumId: 1, + levels: { + '0': { + ilvl: 0, + lvlText: '%1)', + }, + }, + }, + }, + }); + + const result = diffNumbering(oldNumbering, newNumbering); + + expect(result).not.toBeNull(); + expect(result?.modified['abstracts.1.levels.0.lvlText']).toEqual({ + from: '%1.', + to: '%1)', + }); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.ts new file mode 100644 index 0000000000..09b3e25bc6 --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/algorithm/numbering-diffing.ts @@ -0,0 +1,24 @@ +import type { NumberingProperties } from '@superdoc/style-engine/ooxml'; +import { getAttributesDiff, type AttributesDiff } from './attributes-diffing'; + +/** + * Structured diff for numbering document metadata and numbering definitions. + */ +export type NumberingDiff = AttributesDiff; + +/** + * Computes a diff between two numbering snapshots. + * + * @param oldNumbering Previous numbering snapshot. + * @param newNumbering Updated numbering snapshot. + * @returns Numbering diff or `null` when no changes are detected. + */ +export function diffNumbering( + oldNumbering: NumberingProperties | null | undefined, + newNumbering: NumberingProperties | null | undefined, +): NumberingDiff | null { + return getAttributesDiff( + (oldNumbering ?? {}) as unknown as Record, + (newNumbering ?? {}) as unknown as Record, + ); +} diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.test.js b/packages/super-editor/src/extensions/diffing/computeDiff.test.js index 2cdb781720..35fd762082 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.test.js +++ b/packages/super-editor/src/extensions/diffing/computeDiff.test.js @@ -384,6 +384,7 @@ describe('Diff', () => { expect(diff.docDiffs).toHaveLength(0); expect(diff.commentDiffs).toHaveLength(0); expect(diff.stylesDiff).toBeNull(); + expect(diff.numberingDiff).toBeNull(); }); it('includes style diffs when old/new style snapshots differ', async () => { @@ -409,6 +410,7 @@ describe('Diff', () => { expect(diff.docDiffs).toHaveLength(0); expect(diff.commentDiffs).toHaveLength(0); expect(diff.stylesDiff).not.toBeNull(); + expect(diff.numberingDiff).toBeNull(); expect(diff.stylesDiff?.addedStyles).toHaveProperty('Heading1'); expect(diff.stylesDiff?.removedStyles).toEqual({}); expect(diff.stylesDiff?.modifiedStyles.Normal.modified.name).toEqual({ @@ -416,4 +418,59 @@ describe('Diff', () => { to: 'Normal Updated', }); }); + + it('includes numbering diffs when old/new numbering snapshots differ', async () => { + const { doc, schema } = await getDocument('diff_before8.docx'); + const oldNumbering = { + abstracts: { + 1: { + abstractNumId: 1, + levels: { + 0: { + ilvl: 0, + lvlText: '%1.', + }, + }, + }, + }, + definitions: { + 10: { + numId: 10, + abstractNumId: 1, + }, + }, + }; + const newNumbering = { + abstracts: { + 1: { + abstractNumId: 1, + levels: { + 0: { + ilvl: 0, + lvlText: '%1)', + }, + }, + }, + }, + definitions: { + 11: { + numId: 11, + abstractNumId: 1, + }, + }, + }; + + const diff = computeDiff(doc, doc, schema, [], [], null, null, oldNumbering, newNumbering); + + expect(diff.docDiffs).toHaveLength(0); + expect(diff.commentDiffs).toHaveLength(0); + expect(diff.stylesDiff).toBeNull(); + expect(diff.numberingDiff).not.toBeNull(); + expect(diff.numberingDiff?.added).toHaveProperty('definitions.11.numId', 11); + expect(diff.numberingDiff?.deleted).toHaveProperty('definitions.10.numId', 10); + expect(diff.numberingDiff?.modified['abstracts.1.levels.0.lvlText']).toEqual({ + from: '%1.', + to: '%1)', + }); + }); }); diff --git a/packages/super-editor/src/extensions/diffing/computeDiff.ts b/packages/super-editor/src/extensions/diffing/computeDiff.ts index f1d19960ea..4f6c40b554 100644 --- a/packages/super-editor/src/extensions/diffing/computeDiff.ts +++ b/packages/super-editor/src/extensions/diffing/computeDiff.ts @@ -1,8 +1,9 @@ import type { Node as PMNode, Schema } from 'prosemirror-model'; -import type { StylesDocumentProperties } from '@superdoc/style-engine/ooxml'; +import type { NumberingProperties, StylesDocumentProperties } from '@superdoc/style-engine/ooxml'; import { diffComments, type CommentInput, type CommentDiff } from './algorithm/comment-diffing'; import { diffNodes, normalizeNodes, type NodeDiff } from './algorithm/generic-diffing'; import { diffStyles, type StylesDiff } from './algorithm/styles-diffing'; +import { diffNumbering, type NumberingDiff } from './algorithm/numbering-diffing'; /** * Result payload for document diffing. @@ -14,6 +15,8 @@ export interface DiffResult { commentDiffs: CommentDiff[]; /** Diffs computed from OOXML styles metadata. */ stylesDiff: StylesDiff | null; + /** Diffs computed from OOXML numbering metadata. */ + numberingDiff: NumberingDiff | null; } /** @@ -33,7 +36,9 @@ export interface DiffResult { * @param newComments Comment list from the new document. * @param oldStyles OOXML style snapshot from the old document. * @param newStyles OOXML style snapshot from the new document. - * @returns Object containing document, comment, and style diffs. + * @param oldNumbering OOXML numbering snapshot from the old document. + * @param newNumbering OOXML numbering snapshot from the new document. + * @returns Object containing document, comment, style, and numbering diffs. */ export function computeDiff( oldPmDoc: PMNode, @@ -43,10 +48,13 @@ export function computeDiff( newComments: CommentInput[] = [], oldStyles: StylesDocumentProperties | null | undefined = null, newStyles: StylesDocumentProperties | null | undefined = null, + oldNumbering: NumberingProperties | null | undefined = null, + newNumbering: NumberingProperties | null | undefined = null, ): DiffResult { return { docDiffs: diffNodes(normalizeNodes(oldPmDoc), normalizeNodes(newPmDoc)), commentDiffs: diffComments(oldComments, newComments, schema), stylesDiff: diffStyles(oldStyles, newStyles), + numberingDiff: diffNumbering(oldNumbering, newNumbering), }; } diff --git a/packages/super-editor/src/extensions/diffing/diffing.js b/packages/super-editor/src/extensions/diffing/diffing.js index 722e2d0d4b..4f679e327c 100644 --- a/packages/super-editor/src/extensions/diffing/diffing.js +++ b/packages/super-editor/src/extensions/diffing/diffing.js @@ -19,16 +19,19 @@ export const Diffing = Extension.create({ * @param {import('prosemirror-model').Node} updatedDocument * @param {import('./algorithm/comment-diffing.ts').CommentInput[]} [updatedComments] * @param {import('@superdoc/style-engine/ooxml').StylesDocumentProperties | null} [updatedStyles] + * @param {import('@superdoc/style-engine/ooxml').NumberingProperties | null} [updatedNumbering] * @returns {import('./computeDiff.ts').DiffResult} */ compareDocuments: - (updatedDocument, updatedComments, updatedStyles) => + (updatedDocument, updatedComments, updatedStyles, updatedNumbering) => ({ state, tr }) => { tr.setMeta('preventDispatch', true); const currentComments = this.editor.converter?.comments ?? []; const nextComments = updatedComments === undefined ? currentComments : updatedComments; const currentStyles = this.editor.converter?.translatedLinkedStyles ?? null; const nextStyles = updatedStyles === undefined ? currentStyles : updatedStyles; + const currentNumbering = this.editor.converter?.translatedNumbering ?? null; + const nextNumbering = updatedNumbering === undefined ? currentNumbering : updatedNumbering; const diffs = computeDiff( state.doc, updatedDocument, @@ -37,6 +40,8 @@ export const Diffing = Extension.create({ nextComments, currentStyles, nextStyles, + currentNumbering, + nextNumbering, ); return diffs; }, diff --git a/packages/superdoc/src/dev/components/SuperdocDev.vue b/packages/superdoc/src/dev/components/SuperdocDev.vue index 4824f80d51..7103b5c470 100644 --- a/packages/superdoc/src/dev/components/SuperdocDev.vue +++ b/packages/superdoc/src/dev/components/SuperdocDev.vue @@ -284,7 +284,13 @@ const handleCompareFile = async (event) => { const compareDoc = compareEditor.state.doc; const compareComments = compareEditor.converter?.comments ?? []; const compareTranslatedLinkedStyles = compareEditor.converter?.translatedLinkedStyles; - const diff = editor.commands.compareDocuments(compareDoc, compareComments, compareTranslatedLinkedStyles); + const compareTranslatedNumbering = compareEditor.converter?.translatedNumbering; + const diff = editor.commands.compareDocuments( + compareDoc, + compareComments, + compareTranslatedLinkedStyles, + compareTranslatedNumbering, + ); const userToApply = editor.options?.user ?? user; editor.commands.replayDifferences(diff, { user: userToApply, applyTrackedChanges: true }); } finally { From af03e4e5b959f110058949f1f15698684e2367a7 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 6 Mar 2026 15:52:41 -0300 Subject: [PATCH 119/125] feat: implement replay for numbering differences --- .../core/helpers/list-numbering-helpers.js | 79 +++++++++++++ .../diffing/replay/replay-numbering.test.ts | 108 ++++++++++++++++++ .../diffing/replay/replay-numbering.ts | 106 +++++++++++++++++ .../src/extensions/diffing/replayDiffs.ts | 21 +++- 4 files changed, 311 insertions(+), 3 deletions(-) create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-numbering.test.ts create mode 100644 packages/super-editor/src/extensions/diffing/replay/replay-numbering.ts diff --git a/packages/super-editor/src/core/helpers/list-numbering-helpers.js b/packages/super-editor/src/core/helpers/list-numbering-helpers.js index 40cbaa0bb9..243adf3092 100644 --- a/packages/super-editor/src/core/helpers/list-numbering-helpers.js +++ b/packages/super-editor/src/core/helpers/list-numbering-helpers.js @@ -326,6 +326,84 @@ export const removeLvlOverride = (editor, numId, ilvl) => { }); }; +/** + * Rebuild the raw numbering XML model from translated numbering definitions. + * + * This keeps `editor.converter.numbering` in sync with `editor.converter.translatedNumbering`, + * which is required for DOCX export paths that serialize from the raw XML model. + * + * @param {import('../Editor').Editor} editor + * @returns {{ updated: boolean, skipped: number }} + */ +export const rebuildRawNumberingFromTranslated = (editor) => { + const converter = editor?.converter; + if (!converter) { + return { updated: false, skipped: 0 }; + } + + const translated = converter.translatedNumbering || {}; + const translatedAbstracts = translated.abstracts || {}; + const translatedDefinitions = translated.definitions || {}; + + /** @type {Record} */ + const nextAbstracts = {}; + /** @type {Record} */ + const nextDefinitions = {}; + let skipped = 0; + + Object.entries(translatedAbstracts).forEach(([abstractId, abstractDef]) => { + if (!abstractDef || typeof abstractDef !== 'object') { + skipped += 1; + return; + } + + const decoded = wAbstractNumTranslator.decode({ + node: /** @type {any} */ ({ + attrs: { + abstractNum: abstractDef, + }, + }), + }); + + if (!decoded) { + skipped += 1; + return; + } + + nextAbstracts[abstractId] = decoded; + }); + + Object.entries(translatedDefinitions).forEach(([numId, numDef]) => { + if (!numDef || typeof numDef !== 'object') { + skipped += 1; + return; + } + + const decoded = wNumTranslator.decode({ + node: /** @type {any} */ ({ + attrs: { + num: numDef, + }, + }), + }); + + if (!decoded) { + skipped += 1; + return; + } + + nextDefinitions[numId] = decoded; + }); + + converter.numbering = { + ...(converter.numbering || {}), + abstracts: nextAbstracts, + definitions: nextDefinitions, + }; + + return { updated: true, skipped }; +}; + /** * Create a new w:num definition pointing to an existing abstractNumId. * @param {import('../Editor').Editor} editor @@ -382,6 +460,7 @@ export const ListHelpers = { // Numbering definition helpers createNumDefinition, setLvlRestartOnAbstract, + rebuildRawNumberingFromTranslated, // Schema helpers createNewList, diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-numbering.test.ts b/packages/super-editor/src/extensions/diffing/replay/replay-numbering.test.ts new file mode 100644 index 0000000000..31b98a7cad --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-numbering.test.ts @@ -0,0 +1,108 @@ +import { describe, expect, it, vi } from 'vitest'; +import { replayNumbering } from './replay-numbering'; + +describe('replayNumbering', () => { + it('applies numbering diffs and rebuilds the legacy numbering model', () => { + const converter = { + translatedNumbering: { + abstracts: { + '1': { + abstractNumId: 1, + levels: { + '0': { + ilvl: 0, + start: 1, + numFmt: { val: 'decimal' }, + lvlText: '%1.', + }, + }, + }, + }, + definitions: { + '10': { + numId: 10, + abstractNumId: 1, + }, + }, + }, + numbering: { + abstracts: {}, + definitions: {}, + }, + documentModified: false, + promoteToGuid: vi.fn(), + }; + const emit = vi.fn(); + + const result = replayNumbering({ + numberingDiff: { + added: { + 'definitions.11.numId': 11, + 'definitions.11.abstractNumId': 1, + }, + deleted: { + 'definitions.10.numId': 10, + 'definitions.10.abstractNumId': 1, + }, + modified: { + 'abstracts.1.levels.0.lvlText': { + from: '%1.', + to: '%1)', + }, + }, + }, + editor: { + converter, + emit, + }, + }); + + expect(result.applied).toBe(1); + expect(result.skipped).toBe(0); + expect(result.warnings).toEqual([]); + + expect(converter.translatedNumbering.definitions['10']).toBeUndefined(); + expect(converter.translatedNumbering.definitions['11']).toEqual({ + numId: 11, + abstractNumId: 1, + }); + expect(converter.translatedNumbering.abstracts['1'].levels['0'].lvlText).toBe('%1)'); + + expect(converter.numbering.definitions['10']).toBeUndefined(); + expect(converter.numbering.definitions['11']?.name).toBe('w:num'); + expect(converter.numbering.definitions['11']?.attributes?.['w:numId']).toBe('11'); + + const rawAbstract = converter.numbering.abstracts['1']; + const levelNode = rawAbstract?.elements?.find((element) => element.name === 'w:lvl'); + const lvlTextNode = levelNode?.elements?.find((element) => element.name === 'w:lvlText'); + expect(lvlTextNode?.attributes?.['w:val']).toBe('%1)'); + + expect(converter.documentModified).toBe(true); + expect(converter.promoteToGuid).toHaveBeenCalledTimes(1); + expect(emit).toHaveBeenCalledWith( + 'list-definitions-change', + expect.objectContaining({ + change: { type: 'replay-numbering' }, + }), + ); + }); + + it('skips replay when converter is unavailable', () => { + const result = replayNumbering({ + numberingDiff: { + added: {}, + deleted: {}, + modified: { + 'definitions.1.numId': { + from: 1, + to: 2, + }, + }, + }, + }); + + expect(result.applied).toBe(0); + expect(result.skipped).toBe(1); + expect(result.warnings).toEqual(['Numbering replay skipped: editor converter is unavailable.']); + }); +}); diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-numbering.ts b/packages/super-editor/src/extensions/diffing/replay/replay-numbering.ts new file mode 100644 index 0000000000..1d1a24352e --- /dev/null +++ b/packages/super-editor/src/extensions/diffing/replay/replay-numbering.ts @@ -0,0 +1,106 @@ +import type { NumberingProperties } from '@superdoc/style-engine/ooxml'; +import { rebuildRawNumberingFromTranslated } from '../../../core/helpers/list-numbering-helpers.js'; +import { applyAttributesDiff } from './replay-style-utils'; +import { ReplayResult } from './replay-types'; + +type ReplayNumberingEditor = { + emit?: (event: string, payload: unknown) => void; + converter?: { + translatedNumbering?: NumberingProperties | null; + numbering?: { + abstracts?: Record; + definitions?: Record; + } | null; + documentModified?: boolean; + promoteToGuid?: () => string; + } | null; +}; + +/** + * Initializes translated numbering containers on the converter. + * + * @param editor Replay editor context. + * @returns Initialized translated numbering object, or `null` when unavailable. + */ +function ensureTranslatedNumbering(editor: ReplayNumberingEditor): NumberingProperties | null { + const converter = editor.converter; + if (!converter) { + return null; + } + + if (!converter.translatedNumbering) { + converter.translatedNumbering = {}; + } + if (!converter.translatedNumbering.abstracts) { + converter.translatedNumbering.abstracts = {}; + } + if (!converter.translatedNumbering.definitions) { + converter.translatedNumbering.definitions = {}; + } + + return converter.translatedNumbering; +} + +/** + * Replays numbering metadata diffs into translated numbering and then rebuilds + * the legacy raw numbering model used by export. + * + * @param params Replay parameters. + * @param params.numberingDiff Numbering diff payload to apply. + * @param params.editor Editor context containing converter and emitter. + * @returns Replay summary with applied/skipped counts and warnings. + */ +export function replayNumbering({ + numberingDiff, + editor, +}: { + numberingDiff: import('../algorithm/numbering-diffing').NumberingDiff | null; + editor?: ReplayNumberingEditor; +}): ReplayResult { + const result: ReplayResult = { + applied: 0, + skipped: 0, + warnings: [], + }; + + if (!numberingDiff) { + return result; + } + + if (!editor?.converter) { + result.skipped += 1; + result.warnings.push('Numbering replay skipped: editor converter is unavailable.'); + return result; + } + + const translated = ensureTranslatedNumbering(editor); + if (!translated) { + result.skipped += 1; + result.warnings.push('Numbering replay skipped: translated numbering state is unavailable.'); + return result; + } + + const changed = applyAttributesDiff(translated as unknown as Record, numberingDiff); + if (!changed) { + return result; + } + + const { skipped } = rebuildRawNumberingFromTranslated(editor as any); + if (skipped > 0) { + result.warnings.push(`Numbering replay rebuilt with ${skipped} skipped translated numbering entries.`); + } + + editor.converter.documentModified = true; + if (typeof editor.converter.promoteToGuid === 'function') { + editor.converter.promoteToGuid(); + } + + editor.emit?.('list-definitions-change', { + change: { type: 'replay-numbering' }, + numbering: editor.converter.numbering, + editor, + }); + + result.applied += 1; + return result; +} diff --git a/packages/super-editor/src/extensions/diffing/replayDiffs.ts b/packages/super-editor/src/extensions/diffing/replayDiffs.ts index 5ade87d21a..5e64872bc7 100644 --- a/packages/super-editor/src/extensions/diffing/replayDiffs.ts +++ b/packages/super-editor/src/extensions/diffing/replayDiffs.ts @@ -16,6 +16,7 @@ export type ReplayDiffsResult = { import { replayDocDiffs } from './replay/replay-doc'; import { replayComments } from './replay/replay-comments'; import { replayStyles } from './replay/replay-styles'; +import { replayNumbering } from './replay/replay-numbering'; type ReplayDiffsParams = { tr: import('prosemirror-state').Transaction; @@ -33,6 +34,14 @@ type ReplayDiffsParams = { latentStyles?: Record; styles?: Record>; } | null; + translatedNumbering?: { + abstracts?: Record; + definitions?: Record; + } | null; + numbering?: { + abstracts?: Record; + definitions?: Record; + } | null; convertedXml?: Record; documentModified?: boolean; promoteToGuid?: () => string; @@ -55,11 +64,17 @@ export function replayDiffs({ tr, diff, schema, comments = [], editor }: ReplayD const docReplay = replayDocDiffs({ tr, docDiffs: diff.docDiffs, schema }); const commentsReplay = replayComments({ comments, commentDiffs: diff.commentDiffs, editor }); const stylesReplay = replayStyles({ stylesDiff: diff.stylesDiff, editor }); + const numberingReplay = replayNumbering({ numberingDiff: diff.numberingDiff, editor }); return { tr, - appliedDiffs: docReplay.applied + commentsReplay.applied + stylesReplay.applied, - skippedDiffs: docReplay.skipped + commentsReplay.skipped + stylesReplay.skipped, - warnings: [...docReplay.warnings, ...commentsReplay.warnings, ...stylesReplay.warnings], + appliedDiffs: docReplay.applied + commentsReplay.applied + stylesReplay.applied + numberingReplay.applied, + skippedDiffs: docReplay.skipped + commentsReplay.skipped + stylesReplay.skipped + numberingReplay.skipped, + warnings: [ + ...docReplay.warnings, + ...commentsReplay.warnings, + ...stylesReplay.warnings, + ...numberingReplay.warnings, + ], }; } From 194bfdaef3f52dd284c24914622352a68bf1d862 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 6 Mar 2026 16:09:32 -0300 Subject: [PATCH 120/125] fix(comments): scope tracked-change dedupe to active document --- .../superdoc/src/stores/comments-store.js | 32 ++++++++-- .../src/stores/comments-store.test.js | 64 ++++++++++++++++++- 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/packages/superdoc/src/stores/comments-store.js b/packages/superdoc/src/stores/comments-store.js index efd4651f32..e7256a87fb 100644 --- a/packages/superdoc/src/stores/comments-store.js +++ b/packages/superdoc/src/stores/comments-store.js @@ -467,6 +467,7 @@ export const useCommentsStore = defineStore('comments', () => { documentId, coords, } = params; + const normalizedDocumentId = documentId != null ? String(documentId) : null; const comment = getPendingComment({ documentId, @@ -487,8 +488,28 @@ export const useCommentsStore = defineStore('comments', () => { }, }); + const findTrackedChangeById = () => { + const normalizedChangeId = changeId != null ? String(changeId) : null; + if (!normalizedChangeId) return null; + + const matchesId = (trackedComment) => { + if (!trackedComment) return false; + const commentId = trackedComment.commentId != null ? String(trackedComment.commentId) : null; + const importedId = trackedComment.importedId != null ? String(trackedComment.importedId) : null; + return commentId === normalizedChangeId || importedId === normalizedChangeId; + }; + + if (normalizedDocumentId) { + return commentsList.value.find( + (trackedComment) => matchesId(trackedComment) && belongsToDocument(trackedComment, normalizedDocumentId), + ); + } + + return commentsList.value.find(matchesId); + }; + if (event === 'add') { - const existing = commentsList.value.find((c) => c.commentId === changeId); + const existing = findTrackedChangeById(); if (existing) { // Already exists (e.g. created during batch import) — update instead of duplicating // Partial resolution can turn a replacement into insert-only/delete-only, so @@ -509,7 +530,7 @@ export const useCommentsStore = defineStore('comments', () => { addComment({ superdoc, comment }); } else if (event === 'update') { // If we have an update event, simply update the composable comment - const existingTrackedChange = commentsList.value.find((comment) => comment.commentId === changeId); + const existingTrackedChange = findTrackedChangeById(); if (!existingTrackedChange) return; // Partial resolution can turn a replacement into insert-only/delete-only, so @@ -526,7 +547,7 @@ export const useCommentsStore = defineStore('comments', () => { syncCommentsToClients(superdoc, emitData); debounceEmit(changeId, emitData, superdoc); } else if (event === 'resolve') { - const existingTrackedChange = commentsList.value.find((comment) => comment.commentId === changeId); + const existingTrackedChange = findTrackedChangeById(); if (!existingTrackedChange || existingTrackedChange.resolvedTime) return; // Selection/toolbar reject emits tracked-change resolve events. Use the same @@ -920,6 +941,8 @@ export const useCommentsStore = defineStore('comments', () => { const createCommentForTrackChanges = (editor, superdoc, trackedChangesOverride = null) => { const trackedChanges = trackedChangesOverride ?? trackChangesHelpers.getTrackChanges(editor.state); const groupedChanges = groupChanges(trackedChanges); + const activeDocumentId = editor?.options?.documentId != null ? String(editor.options.documentId) : null; + if (!activeDocumentId) return; // Build a Set of existing tracked-change IDs for O(1) lookup. // Include both runtime and imported IDs to avoid duplicate threads when @@ -927,6 +950,7 @@ export const useCommentsStore = defineStore('comments', () => { const existingIds = new Set(); commentsList.value.forEach((comment) => { if (!comment?.trackedChange) return; + if (!belongsToDocument(comment, activeDocumentId)) return; if (comment.commentId != null) existingIds.add(String(comment.commentId)); if (comment.importedId != null) existingIds.add(String(comment.importedId)); }); @@ -940,7 +964,7 @@ export const useCommentsStore = defineStore('comments', () => { changesByIdMap.get(id).push(change); } - const documentId = editor.options.documentId; + const documentId = activeDocumentId; // Build comment params directly from grouped changes — no PM dispatch needed groupedChanges.forEach(({ insertedMark, deletionMark, formatMark }) => { diff --git a/packages/superdoc/src/stores/comments-store.test.js b/packages/superdoc/src/stores/comments-store.test.js index 34dea91533..9483f16bdf 100644 --- a/packages/superdoc/src/stores/comments-store.test.js +++ b/packages/superdoc/src/stores/comments-store.test.js @@ -76,6 +76,23 @@ vi.mock('@superdoc/super-editor', () => ({ trackChangesHelpers: { getTrackChanges: vi.fn(() => []), }, + createOrUpdateTrackedChangeComment: vi.fn(({ event, marks, documentId }) => { + const changeId = marks?.insertedMark?.attrs?.id ?? marks?.deletionMark?.attrs?.id ?? marks?.formatMark?.attrs?.id; + if (changeId == null) return; + return { + event, + changeId, + trackedChangeText: `tracked-${changeId}`, + trackedChangeType: 'insert', + deletedText: null, + authorEmail: 'alice@example.com', + author: 'Alice', + date: 123, + importedAuthor: null, + documentId, + coords: {}, + }; + }), TrackChangesBasePluginKey: 'TrackChangesBasePluginKey', CommentsPluginKey: 'CommentsPluginKey', getRichTextExtensions: vi.fn(() => []), @@ -88,13 +105,14 @@ import useComment from '@superdoc/components/CommentsLayer/use-comment'; import { syncCommentsToClients } from '../core/collaboration/helpers.js'; import { trackChangesHelpers } from '@superdoc/super-editor'; import { groupChanges } from '../helpers/group-changes.js'; -import { trackChangesHelpers } from '@superdoc/super-editor'; +import { trackChangesHelpers, createOrUpdateTrackedChangeComment } from '@superdoc/super-editor'; const useCommentMock = useComment; const syncCommentsToClientsMock = syncCommentsToClients; const getTrackChangesMock = trackChangesHelpers.getTrackChanges; const groupChangesMock = groupChanges; const trackChangesHelpersMock = trackChangesHelpers; +const createOrUpdateTrackedChangeCommentMock = createOrUpdateTrackedChangeComment; describe('comments-store', () => { let store; @@ -750,6 +768,50 @@ describe('comments-store', () => { expect(editorDispatch).toHaveBeenCalledWith(tr); }); + it('creates tracked-change comments for active document when another document has the same id', () => { + const editorDispatch = vi.fn(); + const tr = { setMeta: vi.fn() }; + const editor = { + state: {}, + view: { state: { tr }, dispatch: editorDispatch }, + options: { documentId: 'doc-1' }, + }; + const superdoc = { + config: { isInternal: false }, + emit: vi.fn(), + }; + + __mockSuperdoc.documents.value = [ + { id: 'doc-1', type: 'docx' }, + { id: 'doc-2', type: 'docx' }, + ]; + + trackChangesHelpersMock.getTrackChanges.mockReturnValue([{ mark: { attrs: { id: 'shared-id-1' } } }]); + groupChangesMock.mockReturnValue([{ insertedMark: { mark: { attrs: { id: 'shared-id-1' } } } }]); + + store.commentsList = [ + { + commentId: 'shared-id-1', + trackedChange: true, + trackedChangeText: 'Existing doc-2', + fileId: 'doc-2', + }, + ]; + + store.syncTrackedChangeComments({ superdoc, editor }); + + const matchingComments = store.commentsList.filter((comment) => comment.commentId === 'shared-id-1'); + expect(matchingComments).toHaveLength(2); + expect(matchingComments.map((comment) => comment.fileId).sort()).toEqual(['doc-1', 'doc-2']); + expect(matchingComments.find((comment) => comment.fileId === 'doc-2')?.trackedChangeText).toBe('Existing doc-2'); + expect(matchingComments.find((comment) => comment.fileId === 'doc-1')?.trackedChangeText).toBe( + 'tracked-shared-id-1', + ); + expect(createOrUpdateTrackedChangeCommentMock).toHaveBeenCalledTimes(1); + expect(tr.setMeta).toHaveBeenCalledWith('CommentsPluginKey', { type: 'force' }); + expect(editorDispatch).toHaveBeenCalledWith(tr); + }); + it('does not prune tracked-change comments from other documents during sync', () => { const editorDispatch = vi.fn(); const tr = { setMeta: vi.fn() }; From d1c6b626a83b591087381f197e85b35b243f24bb Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Fri, 6 Mar 2026 16:10:51 -0300 Subject: [PATCH 121/125] refactor(diffing): share deepEquals helper across replay modules --- .../diffing/algorithm/attributes-diffing.ts | 2 +- .../diffing/replay/marks-from-diff.test.js | 31 +++++++++++++++++++ .../diffing/replay/marks-from-diff.ts | 13 ++------ .../diffing/replay/replay-inline.ts | 14 ++------- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts index 3b823db626..c29fadb66e 100644 --- a/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts +++ b/packages/super-editor/src/extensions/diffing/algorithm/attributes-diffing.ts @@ -303,7 +303,7 @@ function isPlainObject(value: unknown): value is Record { * @param b Second value. * @returns True when both values are deeply equal. */ -function deepEquals(a: unknown, b: unknown): boolean { +export function deepEquals(a: unknown, b: unknown): boolean { if (a === b) { return true; } diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js index be1e0a0aa0..be402bf4a7 100644 --- a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.test.js @@ -107,6 +107,33 @@ const testModifiedMarksWithDuplicateTypeReplacement = () => { expect(marks.map((mark) => mark.attrs?.commentId)).toEqual(['a', 'c']); }; +/** + * Verifies modified mark matching is stable when attrs key order differs. + * @returns {void} + */ +const testModifiedMarksWithDifferentAttrKeyOrder = () => { + const schema = createSchema(); + const marks = marksFromDiff({ + schema, + action: 'modified', + oldMarks: [{ type: 'textStyle', attrs: { color: '#0000ff', fontFamily: 'Arial' } }], + marksDiff: { + added: [], + deleted: [], + modified: [ + { + name: 'textStyle', + oldAttrs: { fontFamily: 'Arial', color: '#0000ff' }, + newAttrs: { color: '#00ff00', fontFamily: 'Arial' }, + }, + ], + }, + }); + + expect(getMarkTypes(marks)).toEqual(['textStyle']); + expect(marks[0]?.attrs?.color).toBe('#00ff00'); +}; + /** * Verifies modified text falls back to explicit marks when no marksDiff is provided. * @returns {void} @@ -146,6 +173,10 @@ const runMarksFromDiffSuite = () => { it('applies marksDiff for modified text', testModifiedMarksFromDiff); it('removes a specific duplicate same-type mark', testModifiedMarksWithDuplicateTypeDeletion); it('replaces a specific duplicate same-type mark', testModifiedMarksWithDuplicateTypeReplacement); + it( + 'replaces marks when attrs contain the same data with different key ordering', + testModifiedMarksWithDifferentAttrKeyOrder, + ); it('falls back to marks for modified text', testModifiedMarksFallback); it('returns no marks for deleted text', testDeletedMarks); }; diff --git a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts index 53e2da2be6..f64150ee86 100644 --- a/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts +++ b/packages/super-editor/src/extensions/diffing/replay/marks-from-diff.ts @@ -1,3 +1,5 @@ +import { deepEquals } from '../algorithm/attributes-diffing'; + /** * Builds a mark set from inline diff metadata. * @@ -110,14 +112,3 @@ const buildMarksFromJSON = ( return resolvedMarks; }; - -/** - * Checks deep equality using JSON serialization for mark attrs payloads. - * - * @param left First attrs object. - * @param right Second attrs object. - * @returns True when both attrs payloads serialize identically. - */ -const deepEquals = (left: unknown, right: unknown): boolean => { - return JSON.stringify(left) === JSON.stringify(right); -}; diff --git a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts index 765303cffc..e5e8087d81 100644 --- a/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts +++ b/packages/super-editor/src/extensions/diffing/replay/replay-inline.ts @@ -1,6 +1,7 @@ import { Fragment, Slice } from 'prosemirror-model'; import { ReplaceStep, AddMarkStep, RemoveMarkStep } from 'prosemirror-transform'; +import { deepEquals } from '../algorithm/attributes-diffing'; import { applyAttrsDiff } from './replay-attrs'; import { marksFromDiff } from './marks-from-diff'; import { ReplayResult } from './replay-types'; @@ -291,7 +292,7 @@ const applyRunAttrsDiffInRange = ( const failures: string[] = []; runEntries.forEach(({ pos, node }) => { const updatedAttrs = applyAttrsDiff({ attrs: node.attrs, diff }); - if (isDeepEqual(updatedAttrs, node.attrs)) { + if (deepEquals(updatedAttrs, node.attrs)) { return; } @@ -351,17 +352,6 @@ const filterAttributesDiffByPath = ( return hasChanges ? filtered : null; }; -/** - * Performs deep equality using JSON serialization for attribute payloads. - * - * @param left First value to compare. - * @param right Second value to compare. - * @returns True when both values serialize identically. - */ -const isDeepEqual = (left: unknown, right: unknown): boolean => { - return JSON.stringify(left) === JSON.stringify(right); -}; - /** * Extracts mark JSON entries from the inline node at a given position. * From 42aa5f2a6162a4bb1356c2013e098e3a822a086e Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Tue, 10 Mar 2026 09:48:40 -0300 Subject: [PATCH 122/125] chore: add diffing example --- examples/features/README.md | 1 + examples/features/diffing/index.html | 12 + examples/features/diffing/package.json | 18 + examples/features/diffing/src/App.vue | 508 + examples/features/diffing/src/main.ts | 4 + examples/features/diffing/tsconfig.json | 11 + examples/features/diffing/vite.config.ts | 6 + package.json | 5 +- pnpm-lock.yaml | 27007 +++++++++++++++------ pnpm-workspace.yaml | 1 + 10 files changed, 19485 insertions(+), 8088 deletions(-) create mode 100644 examples/features/diffing/index.html create mode 100644 examples/features/diffing/package.json create mode 100644 examples/features/diffing/src/App.vue create mode 100644 examples/features/diffing/src/main.ts create mode 100644 examples/features/diffing/tsconfig.json create mode 100644 examples/features/diffing/vite.config.ts diff --git a/examples/features/README.md b/examples/features/README.md index c173f6b36a..fd6e8bdb53 100644 --- a/examples/features/README.md +++ b/examples/features/README.md @@ -5,6 +5,7 @@ Focused examples that each demonstrate a single SuperDoc feature. | Example | Description | Docs | |---------|-------------|------| | [track-changes](./track-changes) | Accept/reject workflow with suggesting mode | [Track Changes](https://docs.superdoc.dev/extensions/track-changes) | +| [diffing](./diffing) | Compare two DOCX files and replay directional diffs as tracked changes | - | | [ai-redlining](./ai-redlining) | LLM-powered document review with tracked changes | [AI Agents](https://docs.superdoc.dev/getting-started/ai-agents) | | [comments](./comments) | Threaded comments with resolve workflow and event log | [Comments](https://docs.superdoc.dev/modules/comments) | | [custom-toolbar](./custom-toolbar) | Custom button groups, excluded items, and custom buttons | [Toolbar](https://docs.superdoc.dev/modules/toolbar) | diff --git a/examples/features/diffing/index.html b/examples/features/diffing/index.html new file mode 100644 index 0000000000..8093fe14f2 --- /dev/null +++ b/examples/features/diffing/index.html @@ -0,0 +1,12 @@ + + + + + + SuperDoc Diffing Example + + +
+ + + diff --git a/examples/features/diffing/package.json b/examples/features/diffing/package.json new file mode 100644 index 0000000000..c42eb2b150 --- /dev/null +++ b/examples/features/diffing/package.json @@ -0,0 +1,18 @@ +{ + "name": "superdoc-diffing-example", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "dependencies": { + "superdoc": "workspace:*", + "vue": "^3.5.0" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.2.0", + "typescript": "^5.7.0", + "vite": "^6.2.0" + } +} diff --git a/examples/features/diffing/src/App.vue b/examples/features/diffing/src/App.vue new file mode 100644 index 0000000000..250c236138 --- /dev/null +++ b/examples/features/diffing/src/App.vue @@ -0,0 +1,508 @@ + + + + + + diff --git a/examples/features/diffing/src/main.ts b/examples/features/diffing/src/main.ts new file mode 100644 index 0000000000..684d04215d --- /dev/null +++ b/examples/features/diffing/src/main.ts @@ -0,0 +1,4 @@ +import { createApp } from 'vue'; +import App from './App.vue'; + +createApp(App).mount('#app'); diff --git a/examples/features/diffing/tsconfig.json b/examples/features/diffing/tsconfig.json new file mode 100644 index 0000000000..2cac755e47 --- /dev/null +++ b/examples/features/diffing/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src"] +} diff --git a/examples/features/diffing/vite.config.ts b/examples/features/diffing/vite.config.ts new file mode 100644 index 0000000000..1ebc4fc7dd --- /dev/null +++ b/examples/features/diffing/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; + +export default defineConfig({ + plugins: [vue()], +}); diff --git a/package.json b/package.json index 99701faafc..86da2903b0 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,6 @@ "devDependencies": { "@clack/prompts": "^1.0.1", "@commitlint/cli": "catalog:", - "concurrently": "catalog:", "@commitlint/config-conventional": "catalog:", "@eslint/js": "catalog:", "@semantic-release/changelog": "catalog:", @@ -97,6 +96,7 @@ "@typescript-eslint/eslint-plugin": "catalog:", "@typescript-eslint/parser": "catalog:", "@vitest/coverage-v8": "catalog:", + "concurrently": "catalog:", "eslint": "catalog:", "eslint-config-prettier": "catalog:", "eslint-import-resolver-typescript": "catalog:", @@ -136,5 +136,8 @@ "@vue/shared": "3.5.25", "vite": "npm:rolldown-vite@7.3.1" } + }, + "dependencies": { + "superdoc": "link:../../../packages/superdoc" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1cadcb7b6d..8985e1050b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -311,6 +311,10 @@ patchedDependencies: importers: .: + dependencies: + superdoc: + specifier: link:../../../packages/superdoc + version: link:../../../packages/superdoc devDependencies: '@clack/prompts': specifier: ^1.0.1 @@ -344,7 +348,7 @@ importers: version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) concurrently: specifier: 'catalog:' version: 9.2.1 @@ -356,10 +360,10 @@ importers: version: 9.1.2(eslint@9.39.2(jiti@2.6.1)) eslint-import-resolver-typescript: specifier: 'catalog:' - version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-import-x: specifier: 'catalog:' - version: 4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) + version: 4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsdoc: specifier: 'catalog:' version: 54.7.0(eslint@9.39.2(jiti@2.6.1)) @@ -404,10 +408,10 @@ importers: version: 6.2.5(typanion@3.14.0) vite-plugin-node-polyfills: specifier: 'catalog:' - version: 0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: canvas: specifier: 3.2.1 @@ -562,6 +566,468 @@ importers: specifier: ^14.2.0 version: 14.2.5 + examples/advanced/grading-papers-comments-annotations: + dependencies: + pdfjs-dist: + specifier: ^5.4.296 + version: 5.4.624 + react: + specifier: ^19.0.0 + version: 19.2.4 + react-dom: + specifier: ^19.0.0 + version: 19.2.4(react@19.2.4) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + '@vitejs/plugin-react': + specifier: ^4.0.4 + version: 4.7.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/collaboration/hocuspocus: + dependencies: + '@hocuspocus/provider': + specifier: ^2.13.6 + version: 2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + '@hocuspocus/server': + specifier: ^2.13.6 + version: 2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + react: + specifier: ^19.2.1 + version: 19.2.4 + react-dom: + specifier: ^19.2.1 + version: 19.2.4(react@19.2.4) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + yjs: + specifier: 13.6.19 + version: 13.6.19 + devDependencies: + '@types/react': + specifier: ^19.2.7 + version: 19.2.11 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.11) + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + concurrently: + specifier: ^9.0.0 + version: 9.2.1 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/collaboration/liveblocks: + dependencies: + '@liveblocks/client': + specifier: ^3.11.0 + version: 3.15.1(@types/json-schema@7.0.15) + '@liveblocks/node': + specifier: ^3.11.0 + version: 3.15.1(@types/json-schema@7.0.15) + '@liveblocks/yjs': + specifier: ^3.11.0 + version: 3.15.1(@types/json-schema@7.0.15)(yjs@13.6.19) + react: + specifier: ^19.2.1 + version: 19.2.4 + react-dom: + specifier: ^19.2.1 + version: 19.2.4(react@19.2.4) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + yjs: + specifier: 13.6.19 + version: 13.6.19 + devDependencies: + '@types/react': + specifier: ^19.2.7 + version: 19.2.11 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.11) + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/collaboration/node-sdk: + dependencies: + '@superdoc-dev/sdk': + specifier: latest + version: 1.0.0-alpha.39 + + examples/collaboration/superdoc-yjs: + dependencies: + '@fastify/websocket': + specifier: ^11.1.0 + version: 11.2.0 + '@superdoc-dev/superdoc-yjs-collaboration': + specifier: ^1.0.0 + version: 1.0.2 + fastify: + specifier: ^5.3.3 + version: 5.8.2 + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + vue: + specifier: 3.5.25 + version: 3.5.25(typescript@5.9.3) + y-protocols: + specifier: ^1.0.6 + version: 1.0.7(yjs@13.6.19) + y-websocket: + specifier: ^3.0.0 + version: 3.0.0(yjs@13.6.19) + yjs: + specifier: 13.6.19 + version: 13.6.19 + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.2.2 + version: 5.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + concurrently: + specifier: ^9.0.0 + version: 9.2.1 + tsx: + specifier: ^4.20.6 + version: 4.21.0 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/features/ai-redlining: + dependencies: + react: + specifier: ^19.2.1 + version: 19.2.4 + react-dom: + specifier: ^19.2.1 + version: 19.2.4(react@19.2.4) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + '@types/react': + specifier: ^19.2.7 + version: 19.2.11 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.11) + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/features/comments: + dependencies: + react: + specifier: ^19.2.1 + version: 19.2.4 + react-dom: + specifier: ^19.2.1 + version: 19.2.4(react@19.2.4) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + '@types/react': + specifier: ^19.2.7 + version: 19.2.11 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.11) + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/features/custom-toolbar: + dependencies: + react: + specifier: ^19.2.1 + version: 19.2.4 + react-dom: + specifier: ^19.2.1 + version: 19.2.4(react@19.2.4) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + '@types/react': + specifier: ^19.2.7 + version: 19.2.11 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.11) + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/features/diffing: + dependencies: + superdoc: + specifier: workspace:* + version: link:../../../packages/superdoc + vue: + specifier: 3.5.25 + version: 3.5.25(typescript@5.9.3) + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.2.0 + version: 5.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + typescript: + specifier: ^5.7.0 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/features/track-changes: + dependencies: + react: + specifier: ^19.2.1 + version: 19.2.4 + react-dom: + specifier: ^19.2.1 + version: 19.2.4(react@19.2.4) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + '@types/react': + specifier: ^19.2.7 + version: 19.2.11 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.11) + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/getting-started/angular: + dependencies: + '@angular/common': + specifier: ^21.1.4 + version: 21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/compiler': + specifier: ^21.1.4 + version: 21.2.2 + '@angular/core': + specifier: ^21.1.4 + version: 21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': + specifier: ^21.1.4 + version: 21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)) + '@angular/platform-browser-dynamic': + specifier: ^21.1.4 + version: 21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/compiler@21.2.2)(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))) + rxjs: + specifier: ~7.8.2 + version: 7.8.2 + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + tslib: + specifier: ^2.8.1 + version: 2.8.1 + zone.js: + specifier: ~0.16.0 + version: 0.16.1 + devDependencies: + '@angular-devkit/build-angular': + specifier: ^21.1.4 + version: 21.2.1(@angular/compiler-cli@21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3))(@angular/compiler@21.2.2)(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)))(@types/node@22.19.8)(chokidar@5.0.0)(jiti@2.6.1)(tailwindcss@4.2.1)(tsx@4.21.0)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + '@angular/cli': + specifier: ^21.1.4 + version: 21.2.1(@types/node@22.19.8)(chokidar@5.0.0) + '@angular/compiler-cli': + specifier: ^21.1.4 + version: 21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3) + typescript: + specifier: ~5.9.3 + version: 5.9.3 + + examples/getting-started/laravel: + dependencies: + concurrently: + specifier: ^9.0.0 + version: 9.2.1 + laravel-vite-plugin: + specifier: ^2.0 + version: 2.1.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/getting-started/nextjs: + dependencies: + '@superdoc-dev/react': + specifier: ^1.0.0-rc.1 + version: 1.0.0-rc.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + next: + specifier: 16.1.6 + version: 16.1.6(@playwright/test@1.58.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.3) + react: + specifier: ^19.2.0 + version: 19.2.4 + react-dom: + specifier: ^19.2.0 + version: 19.2.4(react@19.2.4) + devDependencies: + '@tailwindcss/postcss': + specifier: ^4 + version: 4.2.1 + '@types/node': + specifier: ^20 + version: 20.19.37 + '@types/react': + specifier: ^19 + version: 19.2.11 + '@types/react-dom': + specifier: ^19 + version: 19.2.3(@types/react@19.2.11) + eslint: + specifier: ^9 + version: 9.39.2(jiti@2.6.1) + eslint-config-next: + specifier: 16.1.6 + version: 16.1.6(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + tailwindcss: + specifier: ^4 + version: 4.2.1 + typescript: + specifier: ^5 + version: 5.9.3 + + examples/getting-started/nuxt: + dependencies: + nuxt: + specifier: ^4.3.1 + version: 4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2) + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + vue: + specifier: 3.5.25 + version: 3.5.25(typescript@5.9.3) + + examples/getting-started/react: + dependencies: + '@superdoc-dev/react': + specifier: ^1.0.0-rc.1 + version: 1.0.0-rc.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.5.4)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + react: + specifier: ^19.2.0 + version: 19.2.4 + react-dom: + specifier: ^19.2.0 + version: 19.2.4(react@19.2.4) + devDependencies: + '@types/react': + specifier: ^18.3.0 + version: 18.3.28 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.7(@types/react@18.3.28) + '@vitejs/plugin-react': + specifier: ^4.3.0 + version: 4.7.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ~5.5.0 + version: 5.5.4 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/getting-started/vanilla: + dependencies: + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/getting-started/vue: + dependencies: + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + vue: + specifier: 3.5.25 + version: 3.5.25(typescript@5.9.3) + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.2.0 + version: 5.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + typescript: + specifier: ^5.7.0 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@7.3.1 + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + examples/headless/ai-redlining: + dependencies: + superdoc: + specifier: latest + version: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + devDependencies: + '@types/node': + specifier: ^22.15.0 + version: 22.19.8 + tsx: + specifier: ^4.21.0 + version: 4.21.0 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + packages/ai: devDependencies: '@types/node': @@ -575,7 +1041,7 @@ importers: version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-vue': specifier: 'catalog:' - version: 6.0.2(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + version: 6.0.2(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) @@ -599,7 +1065,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vue: specifier: 3.5.25 version: 3.5.25(typescript@5.9.3) @@ -624,7 +1090,7 @@ importers: version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) concurrently: specifier: 'catalog:' version: 9.2.1 @@ -648,7 +1114,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/document-api: {} @@ -671,7 +1137,7 @@ importers: version: 19.2.3(@types/react@19.2.11) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) eslint-plugin-react: specifier: 'catalog:' version: 7.37.5(eslint@9.39.2(jiti@2.6.1)) @@ -695,13 +1161,13 @@ importers: version: 5.9.3 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-dts: specifier: 'catalog:' - version: 4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) + version: 4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/esign/demo: dependencies: @@ -732,13 +1198,13 @@ importers: version: 19.2.3(@types/react@19.2.11) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) typescript: specifier: 'catalog:' version: 5.9.3 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/esign/demo/server: dependencies: @@ -763,7 +1229,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/layout-bridge: dependencies: @@ -800,7 +1266,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/layout-engine: dependencies: @@ -861,7 +1327,7 @@ importers: devDependencies: vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/pm-adapter: dependencies: @@ -901,7 +1367,7 @@ importers: version: link:../painters/dom vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/style-engine: dependencies: @@ -917,7 +1383,7 @@ importers: version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/layout-engine/tests: dependencies: @@ -975,7 +1441,7 @@ importers: version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) eslint: specifier: 'catalog:' version: 9.39.2(jiti@2.6.1) @@ -993,13 +1459,13 @@ importers: version: 5.9.3 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-dts: specifier: 'catalog:' - version: 4.5.4(@types/node@22.19.2)(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) + version: 4.5.4(@types/node@22.19.2)(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/sdk: {} @@ -1183,7 +1649,7 @@ importers: version: 4.0.4 '@vitejs/plugin-vue': specifier: 'catalog:' - version: 6.0.2(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + version: 6.0.2(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) '@vue/test-utils': specifier: 'catalog:' version: 2.4.6 @@ -1210,13 +1676,13 @@ importers: version: 5.9.3 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-node-polyfills: specifier: 'catalog:' - version: 0.25.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1) + version: 0.25.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) y-protocols: specifier: 'catalog:' version: 1.0.7(yjs@13.6.19) @@ -1274,7 +1740,7 @@ importers: version: link:../super-editor '@vitejs/plugin-vue': specifier: 'catalog:' - version: 6.0.2(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + version: 6.0.2(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) '@vue/test-utils': specifier: 'catalog:' version: 2.4.6 @@ -1313,16 +1779,16 @@ importers: version: 5.9.3 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-dts: specifier: 'catalog:' - version: 4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) + version: 4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) vite-plugin-node-polyfills: specifier: 'catalog:' - version: 0.25.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1) + version: 0.25.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) ws: specifier: ^8.18.3 version: 8.19.0 @@ -1358,7 +1824,7 @@ importers: version: 19.2.3(@types/react@19.2.11) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) eslint-plugin-react: specifier: 'catalog:' version: 7.37.5(eslint@9.39.2(jiti@2.6.1)) @@ -1382,13 +1848,13 @@ importers: version: 5.9.3 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-plugin-dts: specifier: 'catalog:' - version: 4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) + version: 4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3) vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/template-builder/demo: dependencies: @@ -1413,19 +1879,19 @@ importers: version: 19.2.3(@types/react@19.2.11) '@vitejs/plugin-react': specifier: 'catalog:' - version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) typescript: specifier: 'catalog:' version: 5.9.3 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages/word-layout: devDependencies: vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) shared/common: devDependencies: @@ -1434,13 +1900,13 @@ importers: version: 22.19.2 '@vitejs/plugin-vue': specifier: 'catalog:' - version: 6.0.2(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + version: 6.0.2(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) typescript: specifier: 'catalog:' version: 5.9.3 vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vue: specifier: 3.5.25 version: 3.5.25(typescript@5.9.3) @@ -1465,7 +1931,7 @@ importers: version: 1.58.1 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) tests/doc-api-stories: dependencies: @@ -1475,7 +1941,7 @@ importers: devDependencies: vitest: specifier: 'catalog:' - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) tests/visual: dependencies: @@ -1500,7 +1966,7 @@ importers: version: 4.21.0 vite: specifier: npm:rolldown-vite@7.3.1 - version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -1514,6 +1980,62 @@ packages: resolution: {integrity: sha512-HTgrrTgZ9Jgeo6Z3oqbQ7lifOVvRR14vaDuBGPPUxk9Thm+vObaO4QfYYYWw4Zo5CWQDBEfsinFA6Gre+AqwNQ==} engines: {node: '>=18'} + '@algolia/abtesting@1.14.1': + resolution: {integrity: sha512-Dkj0BgPiLAaim9sbQ97UKDFHJE/880wgStAM18U++NaJ/2Cws34J5731ovJifr6E3Pv4T2CqvMXf8qLCC417Ew==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-abtesting@5.48.1': + resolution: {integrity: sha512-LV5qCJdj+/m9I+Aj91o+glYszrzd7CX6NgKaYdTOj4+tUYfbS62pwYgUfZprYNayhkQpVFcrW8x8ZlIHpS23Vw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.48.1': + resolution: {integrity: sha512-/AVoMqHhPm14CcHq7mwB+bUJbfCv+jrxlNvRjXAuO+TQa+V37N8k1b0ijaRBPdmSjULMd8KtJbQyUyabXOu6Kg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.48.1': + resolution: {integrity: sha512-VXO+qu2Ep6ota28ktvBm3sG53wUHS2n7bgLWmce5jTskdlCD0/JrV4tnBm1l7qpla1CeoQb8D7ShFhad+UoSOw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.48.1': + resolution: {integrity: sha512-zl+Qyb0nLg+Y5YvKp1Ij+u9OaPaKg2/EPzTwKNiVyOHnQJlFxmXyUZL1EInczAZsEY8hVpPCLtNfhMhfxluXKQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.48.1': + resolution: {integrity: sha512-r89Qf9Oo9mKWQXumRu/1LtvVJAmEDpn8mHZMc485pRfQUMAwSSrsnaw1tQ3sszqzEgAr1c7rw6fjBI+zrAXTOw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.48.1': + resolution: {integrity: sha512-TPKNPKfghKG/bMSc7mQYD9HxHRUkBZA4q1PEmHgICaSeHQscGqL4wBrKkhfPlDV1uYBKW02pbFMUhsOt7p4ZpA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.48.1': + resolution: {integrity: sha512-4Fu7dnzQyQmMFknYwTiN/HxPbH4DyxvQ1m+IxpPp5oslOgz8m6PG5qhiGbqJzH4HiT1I58ecDiCAC716UyVA8Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/ingestion@1.48.1': + resolution: {integrity: sha512-/RFq3TqtXDUUawwic/A9xylA2P3LDMO8dNhphHAUOU51b1ZLHrmZ6YYJm3df1APz7xLY1aht6okCQf+/vmrV9w==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.48.1': + resolution: {integrity: sha512-Of0jTeAZRyRhC7XzDSjJef0aBkgRcvRAaw0ooYRlOw57APii7lZdq+layuNdeL72BRq1snaJhoMMwkmLIpJScw==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.48.1': + resolution: {integrity: sha512-bE7JcpFXzxF5zHwj/vkl2eiCBvyR1zQ7aoUdO+GDXxGp0DGw7nI0p8Xj6u8VmRQ+RDuPcICFQcCwRIJT5tDJFw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.48.1': + resolution: {integrity: sha512-MK3wZ2koLDnvH/AmqIF1EKbJlhRS5j74OZGkLpxI4rYvNi9Jn/C7vb5DytBnQ4KUWts7QsmbdwHkxY5txQHXVw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.48.1': + resolution: {integrity: sha512-2oDT43Y5HWRSIQMPQI4tA/W+TN/N2tjggZCUsqQV440kxzzoPGsvv9QP1GhQ4CoDa+yn6ygUsGp6Dr+a9sPPSg==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.48.1': + resolution: {integrity: sha512-xcaCqbhupVWhuBP1nwbk1XNvwrGljozutEiLx06mvqDf3o8cHyEgQSHS4fKJM+UAggaWVnnFW+Nne5aQ8SUJXg==} + engines: {node: '>= 14.0.0'} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -1522,11 +2044,192 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@ark/schema@0.55.0': - resolution: {integrity: sha512-IlSIc0FmLKTDGr4I/FzNHauMn0MADA6bCjT1wauu4k6MyxhC1R9gz0olNpIRvK7lGGDwtc/VO0RUDNvVQW5WFg==} + '@angular-devkit/architect@0.2102.1': + resolution: {integrity: sha512-x2Qqz6oLYvEh9UBUG0AP1A4zROO/VP+k+zM9+4c2uZw1uqoBQFmutqgzncjVU7cR9R0RApgx9JRZHDFtQru68w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true - '@ark/schema@0.56.0': - resolution: {integrity: sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==} + '@angular-devkit/build-angular@21.2.1': + resolution: {integrity: sha512-HZQggWPHepDIzQeYVjcC1m3HeIEKBYVKPfb2uZBcPxigHvZMeB0JD49QrgDeSOQulIGkAnJoPf/IDRqQpvWzqg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + '@angular/compiler-cli': ^21.0.0 + '@angular/core': ^21.0.0 + '@angular/localize': ^21.0.0 + '@angular/platform-browser': ^21.0.0 + '@angular/platform-server': ^21.0.0 + '@angular/service-worker': ^21.0.0 + '@angular/ssr': ^21.2.1 + '@web/test-runner': ^0.20.0 + browser-sync: ^3.0.2 + jest: ^30.2.0 + jest-environment-jsdom: ^30.2.0 + karma: ^6.3.0 + ng-packagr: ^21.0.0 + protractor: ^7.0.0 + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + typescript: '>=5.9 <6.0' + peerDependenciesMeta: + '@angular/core': + optional: true + '@angular/localize': + optional: true + '@angular/platform-browser': + optional: true + '@angular/platform-server': + optional: true + '@angular/service-worker': + optional: true + '@angular/ssr': + optional: true + '@web/test-runner': + optional: true + browser-sync: + optional: true + jest: + optional: true + jest-environment-jsdom: + optional: true + karma: + optional: true + ng-packagr: + optional: true + protractor: + optional: true + tailwindcss: + optional: true + + '@angular-devkit/build-webpack@0.2102.1': + resolution: {integrity: sha512-iBBMHegwjaAGnSoB5i9ynzCTCdYcLCgGhA2Wmi09DHJPSVFXw23H0nZUeNaRpo2V0hPRrMiyE3dlmaRJC42/yA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + webpack: ^5.30.0 + webpack-dev-server: ^5.0.2 + + '@angular-devkit/core@21.2.1': + resolution: {integrity: sha512-TpXGjERqVPN8EPt7LdmWAwh0oNQ/6uWFutzGZiXhJy81n1zb1O1XrqhRAmvP1cAo5O+na6IV2JkkCmxL6F8GUg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + chokidar: ^5.0.0 + peerDependenciesMeta: + chokidar: + optional: true + + '@angular-devkit/schematics@21.2.1': + resolution: {integrity: sha512-CWoamHaasAHMjHcYqxbj0tMnoXxdGotcAz2SpiuWtH28Lnf5xfbTaJn/lwdMP8Wdh4tgA+uYh2l45A5auCwmkw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + + '@angular/build@21.2.1': + resolution: {integrity: sha512-cUpLNHJp9taII/FOcJHHfQYlMcZSRaf6eIxgSNS6Xfx1CeGoJNDN+J8+GFk+H1CPJt1EvbfyZ+dE5DbsgTD/QQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + '@angular/compiler': ^21.0.0 + '@angular/compiler-cli': ^21.0.0 + '@angular/core': ^21.0.0 + '@angular/localize': ^21.0.0 + '@angular/platform-browser': ^21.0.0 + '@angular/platform-server': ^21.0.0 + '@angular/service-worker': ^21.0.0 + '@angular/ssr': ^21.2.1 + karma: ^6.4.0 + less: ^4.2.0 + ng-packagr: ^21.0.0 + postcss: ^8.4.0 + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + tslib: ^2.3.0 + typescript: '>=5.9 <6.0' + vitest: ^4.0.8 + peerDependenciesMeta: + '@angular/core': + optional: true + '@angular/localize': + optional: true + '@angular/platform-browser': + optional: true + '@angular/platform-server': + optional: true + '@angular/service-worker': + optional: true + '@angular/ssr': + optional: true + karma: + optional: true + less: + optional: true + ng-packagr: + optional: true + postcss: + optional: true + tailwindcss: + optional: true + vitest: + optional: true + + '@angular/cli@21.2.1': + resolution: {integrity: sha512-5SRfMTgwFj1zXOpfeZWHsxZBni0J4Xz7/CbewG47D6DmbstOrSdgt6eNzJ62R650t0G9dpri2YvToZgImtbjOQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + hasBin: true + + '@angular/common@21.2.2': + resolution: {integrity: sha512-xpVYV+MgqWzdjTCFxe3uJGpFOc84YrO4H4oX9HkzI5yQ5OLkQlndtq+OAUK8e330iacg4XHArft3SNDj1LaFfg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/core': 21.2.2 + rxjs: ^6.5.3 || ^7.4.0 + + '@angular/compiler-cli@21.2.2': + resolution: {integrity: sha512-TFg2wXUZ1FdUikNyR27PxuCXuqqlJhL6Mr/cBYuc4HbtBfgKw5FLffbI/iLubBEs55W5ApuYpBVuXKGoZp9SRQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@angular/compiler': 21.2.2 + typescript: '>=5.9 <6.1' + peerDependenciesMeta: + typescript: + optional: true + + '@angular/compiler@21.2.2': + resolution: {integrity: sha512-k7P0EH8I/Iwf2uRalSqhfokFbItTwdH7CmBJ7RKTRIH4FcrQcnqHetNKUMCOYXZtnlHIAnTpG+C+T4+6GTpYFg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@angular/core@21.2.2': + resolution: {integrity: sha512-ljiyiFjR6dgK27CNlOcMrjsDPYKFf2Rl89WLwGEGMOj0cJg/PSLQqpW/fbSkSB3SDgwG/WhXQ4Wrw525OKMupg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/compiler': 21.2.2 + rxjs: ^6.5.3 || ^7.4.0 + zone.js: ~0.15.0 || ~0.16.0 + peerDependenciesMeta: + '@angular/compiler': + optional: true + zone.js: + optional: true + + '@angular/platform-browser-dynamic@21.2.2': + resolution: {integrity: sha512-xhagOxT/2Z66DNR/2mXp94yRXod3AZCpeyeIgluiuUWyDyBzqn1dd7Kdkpae5FYkoDDbYqWvjbGgtoFrRhm0+A==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/common': 21.2.2 + '@angular/compiler': 21.2.2 + '@angular/core': 21.2.2 + '@angular/platform-browser': 21.2.2 + + '@angular/platform-browser@21.2.2': + resolution: {integrity: sha512-6cHfHi/lRCUPNGO0eJeYRIpu8vM+CMMS2Wv/psOUwvl/5+RC92hfBEZxzQiF/5X9A170bJabaMFQC5fA7pkF2g==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@angular/animations': 21.2.2 + '@angular/common': 21.2.2 + '@angular/core': 21.2.2 + peerDependenciesMeta: + '@angular/animations': + optional: true + + '@ark/schema@0.55.0': + resolution: {integrity: sha512-IlSIc0FmLKTDGr4I/FzNHauMn0MADA6bCjT1wauu4k6MyxhC1R9gz0olNpIRvK7lGGDwtc/VO0RUDNvVQW5WFg==} + + '@ark/schema@0.56.0': + resolution: {integrity: sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==} '@ark/util@0.55.0': resolution: {integrity: sha512-aWFNK7aqSvqFtVsl1xmbTjGbg91uqtJV7Za76YGNEwIO4qLjMfyY8flmmbhooYMuqPCO2jyxu8hve943D+w3bA==} @@ -1775,14 +2478,39 @@ packages: resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.28.6': resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.7': + resolution: {integrity: sha512-6Fqi8MtQ/PweQ9xvux65emkLQ83uB+qAVtfHkC9UodyHMIZdxNI01HjLCLUtybElp2KY2XNE0nOgyP1E1vXw9w==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.28.6': resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} @@ -1793,10 +2521,34 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.28.6': resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -1809,6 +2561,10 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + engines: {node: '>=6.9.0'} + '@babel/helpers@7.28.6': resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} engines: {node: '>=6.9.0'} @@ -1818,10289 +2574,15556 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-transform-react-jsx-self@7.27.1': - resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/plugin-transform-react-jsx-source@7.27.1': - resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 - '@babel/runtime@7.28.6': - resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@bcoe/v8-coverage@1.0.2': - resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} - engines: {node: '>=18'} + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@canvas/image-data@1.1.0': - resolution: {integrity: sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==} + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@clack/core@1.0.0': - resolution: {integrity: sha512-Orf9Ltr5NeiEuVJS8Rk2XTw3IxNC2Bic3ash7GgYeA8LJ/zmSNpSQ/m5UAhe03lA6KFgklzZ5KTHs4OAMA/SAQ==} + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@clack/core@1.1.0': - resolution: {integrity: sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==} + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@clack/prompts@1.0.0': - resolution: {integrity: sha512-rWPXg9UaCFqErJVQ+MecOaWsozjaxol4yjnmYcGNipAWzdaWa2x+VJmKfGq7L0APwBohQOYdHC+9RO4qRXej+A==} + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@clack/prompts@1.1.0': - resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==} + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/cli@19.8.1': - resolution: {integrity: sha512-LXUdNIkspyxrlV6VDHWBmCZRtkEVRpBKxi2Gtw3J54cGWhLCTouVD/Q6ZSaSvd2YaDObWK8mDjrz3TIKtaQMAA==} - engines: {node: '>=v18'} - hasBin: true + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/config-conventional@19.8.1': - resolution: {integrity: sha512-/AZHJL6F6B/G959CsMAzrPKKZjeEiAVifRyEwXxcT6qtqbPwGw+iQxmNS+Bu+i09OCtdNRW6pNpBvgPrtMr9EQ==} - engines: {node: '>=v18'} + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/config-validator@19.8.1': - resolution: {integrity: sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==} - engines: {node: '>=v18'} + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/ensure@19.8.1': - resolution: {integrity: sha512-mXDnlJdvDzSObafjYrOSvZBwkD01cqB4gbnnFuVyNpGUM5ijwU/r/6uqUmBXAAOKRfyEjpkGVZxaDsCVnHAgyw==} - engines: {node: '>=v18'} + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/execute-rule@19.8.1': - resolution: {integrity: sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==} - engines: {node: '>=v18'} + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 - '@commitlint/format@19.8.1': - resolution: {integrity: sha512-kSJj34Rp10ItP+Eh9oCItiuN/HwGQMXBnIRk69jdOwEW9llW9FlyqcWYbHPSGofmjsqeoxa38UaEA5tsbm2JWw==} - engines: {node: '>=v18'} + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/is-ignored@19.8.1': - resolution: {integrity: sha512-AceOhEhekBUQ5dzrVhDDsbMaY5LqtN8s1mqSnT2Kz1ERvVZkNihrs3Sfk1Je/rxRNbXYFzKZSHaPsEJJDJV8dg==} - engines: {node: '>=v18'} + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/lint@19.8.1': - resolution: {integrity: sha512-52PFbsl+1EvMuokZXLRlOsdcLHf10isTPlWwoY1FQIidTsTvjKXVXYb7AvtpWkDzRO2ZsqIgPK7bI98x8LRUEw==} - engines: {node: '>=v18'} + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/load@19.8.1': - resolution: {integrity: sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==} - engines: {node: '>=v18'} + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/message@19.8.1': - resolution: {integrity: sha512-+PMLQvjRXiU+Ae0Wc+p99EoGEutzSXFVwQfa3jRNUZLNW5odZAyseb92OSBTKCu+9gGZiJASt76Cj3dLTtcTdg==} - engines: {node: '>=v18'} + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/parse@19.8.1': - resolution: {integrity: sha512-mmAHYcMBmAgJDKWdkjIGq50X4yB0pSGpxyOODwYmoexxxiUCy5JJT99t1+PEMK7KtsCtzuWYIAXYAiKR+k+/Jw==} - engines: {node: '>=v18'} + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@commitlint/read@19.8.1': - resolution: {integrity: sha512-03Jbjb1MqluaVXKHKRuGhcKWtSgh3Jizqy2lJCRbRrnWpcM06MYm8th59Xcns8EqBYvo0Xqb+2DoZFlga97uXQ==} - engines: {node: '>=v18'} + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/resolve-extends@19.8.1': - resolution: {integrity: sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==} - engines: {node: '>=v18'} + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/rules@19.8.1': - resolution: {integrity: sha512-Hnlhd9DyvGiGwjfjfToMi1dsnw1EXKGJNLTcsuGORHz6SS9swRgkBsou33MQ2n51/boIDrbsg4tIBbRpEWK2kw==} - engines: {node: '>=v18'} + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/to-lines@19.8.1': - resolution: {integrity: sha512-98Mm5inzbWTKuZQr2aW4SReY6WUukdWXuZhrqf1QdKPZBCCsXuG87c+iP0bwtD6DBnmVVQjgp4whoHRVixyPBg==} - engines: {node: '>=v18'} + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/top-level@19.8.1': - resolution: {integrity: sha512-Ph8IN1IOHPSDhURCSXBz44+CIu+60duFwRsg6HqaISFHQHbmBtxVw4ZrFNIYUzEP7WwrNPxa2/5qJ//NK1FGcw==} - engines: {node: '>=v18'} + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@commitlint/types@19.8.1': - resolution: {integrity: sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==} - engines: {node: '>=v18'} + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@css-render/plugin-bem@0.15.14': - resolution: {integrity: sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==} + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} + engines: {node: '>=6.9.0'} peerDependencies: - css-render: ~0.15.14 + '@babel/core': ^7.0.0-0 - '@css-render/vue3-ssr@0.15.14': - resolution: {integrity: sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==} + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} peerDependencies: - vue: 3.5.25 + '@babel/core': ^7.0.0-0 - '@csstools/color-helpers@5.1.0': - resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} - engines: {node: '>=18'} + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@csstools/css-calc@2.1.4': - resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} - engines: {node: '>=18'} + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 + '@babel/core': ^7.0.0-0 - '@csstools/css-color-parser@3.1.0': - resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} - engines: {node: '>=18'} + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.5 - '@csstools/css-tokenizer': ^3.0.4 + '@babel/core': ^7.0.0-0 - '@csstools/css-parser-algorithms@3.0.5': - resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} - engines: {node: '>=18'} + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} peerDependencies: - '@csstools/css-tokenizer': ^3.0.4 + '@babel/core': ^7.0.0-0 - '@csstools/css-syntax-patches-for-csstree@1.0.26': - resolution: {integrity: sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==} + '@babel/plugin-transform-modules-systemjs@7.29.0': + resolution: {integrity: sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@csstools/css-tokenizer@3.0.4': - resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} - engines: {node: '>=18'} + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@cypress/request@3.0.9': - resolution: {integrity: sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==} - engines: {node: '>= 6'} + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@emnapi/core@1.8.1': - resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@emotion/hash@0.8.0': - resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@es-joy/jsdoccomment@0.56.0': - resolution: {integrity: sha512-c6EW+aA1w2rjqOMjbL93nZlwxp6c1Ln06vTYs5FjRRhmJXK8V/OrSXdT+pUr4aRYgjCgu8/OkiZr0tzeVrRSbw==} - engines: {node: '>=20.11.0'} + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/aix-ppc64@0.27.2': - resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-arm64@0.27.2': - resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-arm@0.27.2': - resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/android-x64@0.27.2': - resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/darwin-arm64@0.27.2': - resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/darwin-x64@0.27.2': - resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] + '@babel/plugin-transform-runtime@7.29.0': + resolution: {integrity: sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/freebsd-arm64@0.27.2': - resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/freebsd-x64@0.27.2': - resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-arm64@0.27.2': - resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-arm@0.27.2': - resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-ia32@0.27.2': - resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] + '@babel/preset-env@7.29.0': + resolution: {integrity: sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@esbuild/linux-loong64@0.27.2': - resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} + engines: {node: '>=6.9.0'} - '@esbuild/linux-mips64el@0.27.2': - resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} - '@esbuild/linux-ppc64@0.27.2': - resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.27.2': - resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] + '@bomb.sh/tab@0.0.12': + resolution: {integrity: sha512-dYRwg4MqfHR5/BcTy285XOGRhjQFmNpaJBZ0tl2oU+RY595MQ5ApTF6j3OvauPAooHL6cfoOZMySQrOQztT8RQ==} + hasBin: true + peerDependencies: + cac: ^6.7.14 + citty: ^0.1.6 + commander: ^13.1.0 + peerDependenciesMeta: + cac: + optional: true + citty: + optional: true + commander: + optional: true - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] + '@canvas/image-data@1.1.0': + resolution: {integrity: sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==} - '@esbuild/linux-s390x@0.27.2': - resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] + '@clack/core@1.0.0': + resolution: {integrity: sha512-Orf9Ltr5NeiEuVJS8Rk2XTw3IxNC2Bic3ash7GgYeA8LJ/zmSNpSQ/m5UAhe03lA6KFgklzZ5KTHs4OAMA/SAQ==} - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] + '@clack/core@1.1.0': + resolution: {integrity: sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==} - '@esbuild/linux-x64@0.27.2': - resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] + '@clack/prompts@1.0.0': + resolution: {integrity: sha512-rWPXg9UaCFqErJVQ+MecOaWsozjaxol4yjnmYcGNipAWzdaWa2x+VJmKfGq7L0APwBohQOYdHC+9RO4qRXej+A==} - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] + '@clack/prompts@1.1.0': + resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==} - '@esbuild/netbsd-arm64@0.27.2': - resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] + '@cloudflare/kv-asset-handler@0.4.2': + resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} + engines: {node: '>=18.0.0'} - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} - '@esbuild/netbsd-x64@0.27.2': - resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] + '@commitlint/cli@19.8.1': + resolution: {integrity: sha512-LXUdNIkspyxrlV6VDHWBmCZRtkEVRpBKxi2Gtw3J54cGWhLCTouVD/Q6ZSaSvd2YaDObWK8mDjrz3TIKtaQMAA==} + engines: {node: '>=v18'} + hasBin: true - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] + '@commitlint/config-conventional@19.8.1': + resolution: {integrity: sha512-/AZHJL6F6B/G959CsMAzrPKKZjeEiAVifRyEwXxcT6qtqbPwGw+iQxmNS+Bu+i09OCtdNRW6pNpBvgPrtMr9EQ==} + engines: {node: '>=v18'} - '@esbuild/openbsd-arm64@0.27.2': - resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] + '@commitlint/config-validator@19.8.1': + resolution: {integrity: sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==} + engines: {node: '>=v18'} - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] + '@commitlint/ensure@19.8.1': + resolution: {integrity: sha512-mXDnlJdvDzSObafjYrOSvZBwkD01cqB4gbnnFuVyNpGUM5ijwU/r/6uqUmBXAAOKRfyEjpkGVZxaDsCVnHAgyw==} + engines: {node: '>=v18'} - '@esbuild/openbsd-x64@0.27.2': - resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] + '@commitlint/execute-rule@19.8.1': + resolution: {integrity: sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==} + engines: {node: '>=v18'} - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] + '@commitlint/format@19.8.1': + resolution: {integrity: sha512-kSJj34Rp10ItP+Eh9oCItiuN/HwGQMXBnIRk69jdOwEW9llW9FlyqcWYbHPSGofmjsqeoxa38UaEA5tsbm2JWw==} + engines: {node: '>=v18'} - '@esbuild/openharmony-arm64@0.27.2': - resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] + '@commitlint/is-ignored@19.8.1': + resolution: {integrity: sha512-AceOhEhekBUQ5dzrVhDDsbMaY5LqtN8s1mqSnT2Kz1ERvVZkNihrs3Sfk1Je/rxRNbXYFzKZSHaPsEJJDJV8dg==} + engines: {node: '>=v18'} - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] + '@commitlint/lint@19.8.1': + resolution: {integrity: sha512-52PFbsl+1EvMuokZXLRlOsdcLHf10isTPlWwoY1FQIidTsTvjKXVXYb7AvtpWkDzRO2ZsqIgPK7bI98x8LRUEw==} + engines: {node: '>=v18'} - '@esbuild/sunos-x64@0.27.2': - resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] + '@commitlint/load@19.8.1': + resolution: {integrity: sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==} + engines: {node: '>=v18'} - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] + '@commitlint/message@19.8.1': + resolution: {integrity: sha512-+PMLQvjRXiU+Ae0Wc+p99EoGEutzSXFVwQfa3jRNUZLNW5odZAyseb92OSBTKCu+9gGZiJASt76Cj3dLTtcTdg==} + engines: {node: '>=v18'} - '@esbuild/win32-arm64@0.27.2': - resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] + '@commitlint/parse@19.8.1': + resolution: {integrity: sha512-mmAHYcMBmAgJDKWdkjIGq50X4yB0pSGpxyOODwYmoexxxiUCy5JJT99t1+PEMK7KtsCtzuWYIAXYAiKR+k+/Jw==} + engines: {node: '>=v18'} - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] + '@commitlint/read@19.8.1': + resolution: {integrity: sha512-03Jbjb1MqluaVXKHKRuGhcKWtSgh3Jizqy2lJCRbRrnWpcM06MYm8th59Xcns8EqBYvo0Xqb+2DoZFlga97uXQ==} + engines: {node: '>=v18'} - '@esbuild/win32-ia32@0.27.2': - resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] + '@commitlint/resolve-extends@19.8.1': + resolution: {integrity: sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==} + engines: {node: '>=v18'} - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] + '@commitlint/rules@19.8.1': + resolution: {integrity: sha512-Hnlhd9DyvGiGwjfjfToMi1dsnw1EXKGJNLTcsuGORHz6SS9swRgkBsou33MQ2n51/boIDrbsg4tIBbRpEWK2kw==} + engines: {node: '>=v18'} - '@esbuild/win32-x64@0.27.2': - resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] + '@commitlint/to-lines@19.8.1': + resolution: {integrity: sha512-98Mm5inzbWTKuZQr2aW4SReY6WUukdWXuZhrqf1QdKPZBCCsXuG87c+iP0bwtD6DBnmVVQjgp4whoHRVixyPBg==} + engines: {node: '>=v18'} - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@commitlint/top-level@19.8.1': + resolution: {integrity: sha512-Ph8IN1IOHPSDhURCSXBz44+CIu+60duFwRsg6HqaISFHQHbmBtxVw4ZrFNIYUzEP7WwrNPxa2/5qJ//NK1FGcw==} + engines: {node: '>=v18'} - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@commitlint/types@19.8.1': + resolution: {integrity: sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==} + engines: {node: '>=v18'} - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@css-render/plugin-bem@0.15.14': + resolution: {integrity: sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==} + peerDependencies: + css-render: ~0.15.14 - '@eslint/config-helpers@0.4.2': - resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@css-render/vue3-ssr@0.15.14': + resolution: {integrity: sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==} + peerDependencies: + vue: 3.5.25 - '@eslint/core@0.17.0': - resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} - '@eslint/eslintrc@3.3.3': - resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 - '@eslint/js@9.39.2': - resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 - '@eslint/object-schema@2.1.7': - resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 - '@eslint/plugin-kit@0.4.1': - resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@csstools/css-syntax-patches-for-csstree@1.0.26': + resolution: {integrity: sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==} - '@floating-ui/core@1.7.4': - resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} - '@floating-ui/dom@1.7.5': - resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} + '@cypress/request@3.0.9': + resolution: {integrity: sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==} + engines: {node: '>= 6'} - '@floating-ui/react-dom@2.1.7': - resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' + '@discoveryjs/json-ext@0.6.3': + resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} + engines: {node: '>=14.17.0'} - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@dxup/nuxt@0.3.2': + resolution: {integrity: sha512-2f2usP4oLNsIGjPprvABe3f3GWuIhIDp0169pGLFxTDRI5A4d4sBbGpR+tD9bGZCT+1Btb6Q2GKlyv3LkDCW5g==} - '@hocuspocus/common@2.15.3': - resolution: {integrity: sha512-Rzh1HF0a2o/tf90A3w2XNdXd9Ym3aQzMDfD3lAUONCX9B9QOdqdyiORrj6M25QEaJrEIbXFy8LtAFcL0wRdWzA==} + '@dxup/unimport@0.1.2': + resolution: {integrity: sha512-/B8YJGPzaYq1NbsQmwgP8EZqg40NpTw4ZB3suuI0TplbxKHeK94jeaawLmVhCv+YwUnOpiWEz9U6SeThku/8JQ==} - '@hocuspocus/provider@2.15.3': - resolution: {integrity: sha512-oadN05m+KL4ylNKVo5YspNG4MXkT2Y+FUFzrgigpQeTjQibkPUwCNmUnkUxMgrGRgxb+O0lJCfirFIJMxedctA==} - peerDependencies: - y-protocols: ^1.0.6 - yjs: ^13.6.8 + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - '@hocuspocus/server@2.15.3': - resolution: {integrity: sha512-Ju4ty4/7JtmvivcP7gKReOLf8KrFwN7Yx/5VhXYh4TRULy4kSo2fsDVUaluPp0neZa6PbVhizJuzlOim73IEbQ==} - peerDependencies: - y-protocols: ^1.0.6 - yjs: ^13.6.8 + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - '@hono/node-server@1.19.9': - resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} - engines: {node: '>=18.14.1'} - peerDependencies: - hono: ^4 + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} + '@emotion/hash@0.8.0': + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} - engines: {node: '>=18.18.0'} + '@es-joy/jsdoccomment@0.56.0': + resolution: {integrity: sha512-c6EW+aA1w2rjqOMjbL93nZlwxp6c1Ln06vTYs5FjRRhmJXK8V/OrSXdT+pUr4aRYgjCgu8/OkiZr0tzeVrRSbw==} + engines: {node: '>=20.11.0'} - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@img/colour@1.0.0': - resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} cpu: [arm64] - os: [darwin] + os: [android] - '@img/sharp-darwin-arm64@0.34.5': - resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} cpu: [arm64] - os: [darwin] + os: [android] - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} cpu: [x64] - os: [darwin] + os: [android] - '@img/sharp-darwin-x64@0.34.5': - resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.4': - resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.4': - resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} cpu: [arm64] - os: [linux] + os: [freebsd] - '@img/sharp-libvips-linux-arm64@1.2.4': - resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} cpu: [arm64] - os: [linux] + os: [freebsd] - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} - cpu: [arm] - os: [linux] + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] - '@img/sharp-libvips-linux-arm@1.2.4': - resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} - cpu: [arm] - os: [linux] + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] - '@img/sharp-libvips-linux-ppc64@1.2.4': - resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} - cpu: [ppc64] - os: [linux] + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] - '@img/sharp-libvips-linux-riscv64@1.2.4': - resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} - cpu: [riscv64] - os: [linux] + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} - cpu: [s390x] + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.4': - resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} - cpu: [s390x] + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} - cpu: [x64] + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.4': - resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} - cpu: [x64] + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} - cpu: [arm64] + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} - cpu: [arm64] + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} - cpu: [x64] + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} - cpu: [x64] + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] os: [linux] - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] os: [linux] - '@img/sharp-linux-arm64@0.34.5': - resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] os: [linux] - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] os: [linux] - '@img/sharp-linux-arm@0.34.5': - resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] os: [linux] - '@img/sharp-linux-ppc64@0.34.5': - resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@img/sharp-linux-riscv64@0.34.5': - resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [riscv64] + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] os: [linux] - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] os: [linux] - '@img/sharp-linux-s390x@0.34.5': - resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] os: [linux] - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] os: [linux] - '@img/sharp-linux-x64@0.34.5': - resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.5': - resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] os: [linux] - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.5': - resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] - '@img/sharp-wasm32@0.34.5': - resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] - '@img/sharp-win32-arm64@0.34.5': - resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} cpu: [arm64] - os: [win32] + os: [netbsd] - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] - '@img/sharp-win32-ia32@0.34.5': - resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} cpu: [x64] - os: [win32] + os: [netbsd] - '@img/sharp-win32-x64@0.34.5': - resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} cpu: [x64] - os: [win32] + os: [netbsd] - '@inquirer/ansi@1.0.2': - resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] - '@inquirer/checkbox@4.3.2': - resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [arm64] + os: [openbsd] - '@inquirer/confirm@5.1.21': - resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [arm64] + os: [openbsd] - '@inquirer/core@10.3.2': - resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [x64] + os: [openbsd] - '@inquirer/editor@4.2.23': - resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [x64] + os: [openbsd] - '@inquirer/expand@4.0.23': - resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [x64] + os: [openbsd] - '@inquirer/external-editor@1.0.3': - resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [arm64] + os: [openharmony] - '@inquirer/figures@1.0.15': - resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] - '@inquirer/input@4.3.1': - resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [arm64] + os: [openharmony] - '@inquirer/number@3.0.23': - resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [x64] + os: [sunos] - '@inquirer/password@4.0.23': - resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [x64] + os: [sunos] - '@inquirer/prompts@7.9.0': - resolution: {integrity: sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==} + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [x64] + os: [sunos] - '@inquirer/rawlist@4.1.11': - resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [arm64] + os: [win32] - '@inquirer/search@3.2.2': - resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [arm64] + os: [win32] - '@inquirer/select@4.4.2': - resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + cpu: [arm64] + os: [win32] - '@inquirer/type@3.0.10': - resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.1': - resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} - engines: {node: 20 || >=22} + cpu: [ia32] + os: [win32] - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@jsep-plugin/assignment@1.3.0': - resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} - engines: {node: '>= 10.16.0'} - peerDependencies: - jsep: ^0.4.0||^1.0.0 + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@jsep-plugin/regex@1.0.4': - resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} - engines: {node: '>= 10.16.0'} - peerDependencies: - jsep: ^0.4.0||^1.0.0 + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@jsep-plugin/ternary@1.1.4': - resolution: {integrity: sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==} - engines: {node: '>= 10.16.0'} - peerDependencies: - jsep: ^0.4.0||^1.0.0 + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@juggle/resize-observer@3.4.0': - resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + '@eslint/eslintrc@3.3.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@leichtgewicht/ip-codec@2.0.5': - resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@lifeomic/attempt@3.1.0': - resolution: {integrity: sha512-QZqem4QuAnAyzfz+Gj5/+SLxqwCAw2qmt7732ZXodr6VDWGeYLG6w1i/vYLa55JQM9wRuBKLmXmiZ2P0LtE5rw==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@mdx-js/mdx@3.1.1': - resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@mdx-js/react@3.1.1': - resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} - peerDependencies: - '@types/react': '>=16' - react: '>=16' + '@fastify/ajv-compiler@4.0.5': + resolution: {integrity: sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==} - '@microsoft/api-extractor-model@7.32.2': - resolution: {integrity: sha512-Ussc25rAalc+4JJs9HNQE7TuO9y6jpYQX9nWD1DhqUzYPBr3Lr7O9intf+ZY8kD5HnIqeIRJX7ccCT0QyBy2Ww==} + '@fastify/error@4.2.0': + resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==} - '@microsoft/api-extractor@7.56.1': - resolution: {integrity: sha512-wX9ugJFqhsEWwt+UFTAkvXcBOzSQ1FeKe0ZdwEDKtjsf20Ec2frmCDXPjQwPtSNrpXUy1yQgyaF6YJVuC8gMtg==} - hasBin: true + '@fastify/fast-json-stringify-compiler@5.0.3': + resolution: {integrity: sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==} - '@microsoft/tsdoc-config@0.18.0': - resolution: {integrity: sha512-8N/vClYyfOH+l4fLkkr9+myAoR6M7akc8ntBJ4DJdWH2b09uVfr71+LTMpNyG19fNqWDg8KEDZhx5wxuqHyGjw==} + '@fastify/forwarded@3.0.1': + resolution: {integrity: sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==} - '@microsoft/tsdoc@0.16.0': - resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} + '@fastify/merge-json-schemas@0.2.1': + resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} - '@mintlify/cli@4.0.935': - resolution: {integrity: sha512-mY0T3QOdDNuZlb4qx6GEAq0nSkWQGCn0Ug5kjQH3GjZFeeROm0EDYzoXlwAgLL/DkFEU9GpWmO3kU8EvetXtBw==} - engines: {node: '>=18.0.0'} - hasBin: true + '@fastify/proxy-addr@5.1.0': + resolution: {integrity: sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==} - '@mintlify/common@1.0.661': - resolution: {integrity: sha512-/Hdiblzaomp+AWStQ4smhVMgesQhffzQjC9aYBnmLReNdh2Js+ccQFUaWL3TNIxwiS2esaZvsHSV/D+zyRS3hg==} + '@fastify/websocket@11.2.0': + resolution: {integrity: sha512-3HrDPbAG1CzUCqnslgJxppvzaAZffieOVbLp1DAy1huCSynUWPifSvfdEDUR8HlJLp3sp1A36uOM2tJogADS8w==} - '@mintlify/common@1.0.713': - resolution: {integrity: sha512-0Ir8BLMVfADPi04/O5jDDemL+dxpNqHgx/JDQALuCFS4ANqHk7C9ES7ifsnt/rjmiiX7kuXSFqoAZrt1WMTLaA==} + '@floating-ui/core@1.7.4': + resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} - '@mintlify/link-rot@3.0.872': - resolution: {integrity: sha512-2KDAD+hTmRZZCq0XCvvG+p/xSn5gtHCkHYA8Zfd2mhHceHCofNikvjffpYKx96eqaNCLhbeUYVnLlquBs820oQ==} - engines: {node: '>=18.0.0'} + '@floating-ui/dom@1.7.5': + resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} - '@mintlify/mdx@3.0.4': - resolution: {integrity: sha512-tJhdpnM5ReJLNJ2fuDRIEr0zgVd6id7/oAIfs26V46QlygiLsc8qx4Rz3LWIX51rUXW/cfakjj0EATxIciIw+g==} + '@floating-ui/react-dom@2.1.7': + resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} peerDependencies: - '@radix-ui/react-popover': ^1.1.15 - react: ^18.3.1 - react-dom: ^18.3.1 + react: '>=16.8.0' + react-dom: '>=16.8.0' - '@mintlify/models@0.0.255': - resolution: {integrity: sha512-LIUkfA7l7ypHAAuOW74ZJws/NwNRqlDRD/U466jarXvvSlGhJec/6J4/I+IEcBvWDnc9anLFKmnGO04jPKgAsg==} - engines: {node: '>=18.0.0'} + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - '@mintlify/models@0.0.268': - resolution: {integrity: sha512-8HDPI3luABg5p/VTVYAOqabqOtcK2jdBuRTYOJiV39QqjQY29Q7kWH697PUokN6CO9uP2CCkPG5O5Gi7QxflWA==} - engines: {node: '>=18.0.0'} + '@gar/promise-retry@1.0.2': + resolution: {integrity: sha512-Lm/ZLhDZcBECta3TmCQSngiQykFdfw+QtI1/GYMsZd4l3nG+P8WLB16XuS7WaBGLQ+9E+cOcWQsth9cayuGt8g==} + engines: {node: ^20.17.0 || >=22.9.0} - '@mintlify/openapi-parser@0.0.8': - resolution: {integrity: sha512-9MBRq9lS4l4HITYCrqCL7T61MOb20q9IdU7HWhqYMNMM1jGO1nHjXasFy61yZ8V6gMZyyKQARGVoZ0ZrYN48Og==} - engines: {node: '>=18'} + '@harperfast/extended-iterable@1.0.3': + resolution: {integrity: sha512-sSAYhQca3rDWtQUHSAPeO7axFIUJOI6hn1gjRC5APVE1a90tuyT8f5WIgRsFhhWA7htNkju2veB9eWL6YHi/Lw==} - '@mintlify/prebuild@1.0.849': - resolution: {integrity: sha512-GlFRJYrS7sIByZXKLa91VeCGruMunbwoxGbWRF5gAiknkuhng9SuX7zB7yTa0J3ApmLO3oZG5baWfzflcQY01w==} + '@hocuspocus/common@2.15.3': + resolution: {integrity: sha512-Rzh1HF0a2o/tf90A3w2XNdXd9Ym3aQzMDfD3lAUONCX9B9QOdqdyiORrj6M25QEaJrEIbXFy8LtAFcL0wRdWzA==} - '@mintlify/previewing@4.0.905': - resolution: {integrity: sha512-3PjzszHkvswA742dofEDohINUnlbmi4gnKP9xWK7wA+dLszKJ56BYjm6VCWJjpG3PuO4oPFIS9vI1YRCEM8kRQ==} - engines: {node: '>=18.0.0'} + '@hocuspocus/provider@2.15.3': + resolution: {integrity: sha512-oadN05m+KL4ylNKVo5YspNG4MXkT2Y+FUFzrgigpQeTjQibkPUwCNmUnkUxMgrGRgxb+O0lJCfirFIJMxedctA==} + peerDependencies: + y-protocols: ^1.0.6 + yjs: ^13.6.8 - '@mintlify/scraping@4.0.522': - resolution: {integrity: sha512-PL2k52WT5S5OAgnT2K13bP7J2El6XwiVvQlrLvxDYw5KMMV+y34YVJI8ZscKb4trjitWDgyK0UTq2KN6NQgn6g==} - engines: {node: '>=18.0.0'} - hasBin: true + '@hocuspocus/server@2.15.3': + resolution: {integrity: sha512-Ju4ty4/7JtmvivcP7gKReOLf8KrFwN7Yx/5VhXYh4TRULy4kSo2fsDVUaluPp0neZa6PbVhizJuzlOim73IEbQ==} + peerDependencies: + y-protocols: ^1.0.6 + yjs: ^13.6.8 - '@mintlify/scraping@4.0.574': - resolution: {integrity: sha512-FN2MM8uxBi2Foxpua0UIDLYo4YvcJE/NMwOGfbQ/HWx73eWhsA0LI+uhqpq8ZYqgc4awVif1oKc7OcuEhtY7Kg==} - engines: {node: '>=18.0.0'} - hasBin: true + '@hono/node-server@1.19.9': + resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 - '@mintlify/validation@0.1.555': - resolution: {integrity: sha512-11QVUReL4N5u8wSCgZt4RN7PA0jYQoMEBZ5IrUp5pgb5ZJBOoGV/vPsQrxPPa1cxsUDAuToNhtGxRQtOav/w8w==} + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} - '@mintlify/validation@0.1.585': - resolution: {integrity: sha512-32mezT7v1dmPQa2DyGDYf0t+HHUbmpShJVnMrxxhXyMHvKUqOu4ENoRCAxRbfc4OLPxAFRB4qEEq2toID+tOHw==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} - '@modelcontextprotocol/sdk@1.26.0': - resolution: {integrity: sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==} + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} engines: {node: '>=18'} - peerDependencies: - '@cfworker/json-schema': ^4.1.1 - zod: ^3.25 || ^4.0 - peerDependenciesMeta: - '@cfworker/json-schema': - optional: true - '@napi-rs/canvas-android-arm64@0.1.91': - resolution: {integrity: sha512-SLLzXXgSnfct4zy/BVAfweZQkYkPJsNsJ2e5DOE8DFEHC6PufyUrwb12yqeu2So2IOIDpWJJaDAxKY/xpy6MYQ==} - engines: {node: '>= 10'} + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] - os: [android] + os: [darwin] - '@napi-rs/canvas-darwin-arm64@0.1.91': - resolution: {integrity: sha512-bzdbCjIjw3iRuVFL+uxdSoMra/l09ydGNX9gsBxO/zg+5nlppscIpj6gg+nL6VNG85zwUarDleIrUJ+FWHvmuA==} - engines: {node: '>= 10'} + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@napi-rs/canvas-darwin-x64@0.1.91': - resolution: {integrity: sha512-q3qpkpw0IsG9fAS/dmcGIhCVoNxj8ojbexZKWwz3HwxlEWsLncEQRl4arnxrwbpLc2nTNTyj4WwDn7QR5NDAaA==} - engines: {node: '>= 10'} + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.91': - resolution: {integrity: sha512-Io3g8wJZVhK8G+Fpg1363BE90pIPqg+ZbeehYNxPWDSzbgwU3xV0l8r/JBzODwC7XHi1RpFEk+xyUTMa2POj6w==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] - '@napi-rs/canvas-linux-arm64-gnu@0.1.91': - resolution: {integrity: sha512-HBnto+0rxx1bQSl8bCWA9PyBKtlk2z/AI32r3cu4kcNO+M/5SD4b0v1MWBWZyqMQyxFjWgy3ECyDjDKMC6tY1A==} - engines: {node: '>= 10'} + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-arm64-musl@0.1.91': - resolution: {integrity: sha512-/eJtVe2Xw9A86I4kwXpxxoNagdGclu12/NSMsfoL8q05QmeRCbfjhg1PJS7ENAuAvaiUiALGrbVfeY1KU1gztQ==} - engines: {node: '>= 10'} + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-riscv64-gnu@0.1.91': - resolution: {integrity: sha512-floNK9wQuRWevUhhXRcuis7h0zirdytVxPgkonWO+kQlbvxV7gEUHGUFQyq4n55UHYFwgck1SAfJ1HuXv/+ppQ==} - engines: {node: '>= 10'} + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] - '@napi-rs/canvas-linux-x64-gnu@0.1.91': - resolution: {integrity: sha512-c3YDqBdf7KETuZy2AxsHFMsBBX1dWT43yFfWUq+j1IELdgesWtxf/6N7csi3VPf6VA3PmnT9EhMyb+M1wfGtqw==} - engines: {node: '>= 10'} + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] - '@napi-rs/canvas-linux-x64-musl@0.1.91': - resolution: {integrity: sha512-RpZ3RPIwgEcNBHSHSX98adm+4VP8SMT5FN6250s5jQbWpX/XNUX5aLMfAVJS/YnDjS1QlsCgQxFOPU0aCCWgag==} - engines: {node: '>= 10'} + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] - '@napi-rs/canvas-win32-arm64-msvc@0.1.91': - resolution: {integrity: sha512-gF8MBp4X134AgVurxqlCdDA2qO0WaDdi9o6Sd5rWRVXRhWhYQ6wkdEzXNLIrmmros0Tsp2J0hQzx4ej/9O8trQ==} - engines: {node: '>= 10'} + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} cpu: [arm64] - os: [win32] + os: [linux] - '@napi-rs/canvas-win32-x64-msvc@0.1.91': - resolution: {integrity: sha512-++gtW9EV/neKI8TshD8WFxzBYALSPag2kFRahIJV+LYsyt5kBn21b1dBhEUDHf7O+wiZmuFCeUa7QKGHnYRZBA==} - engines: {node: '>= 10'} + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} cpu: [x64] - os: [win32] + os: [linux] - '@napi-rs/canvas@0.1.91': - resolution: {integrity: sha512-eeIe1GoB74P1B0Nkw6pV8BCQ3hfCfvyYr4BntzlCsnFXzVJiPMDnLeIx3gVB0xQMblHYnjK/0nCLvirEhOjr5g==} - engines: {node: '>= 10'} + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] - '@octokit/auth-token@6.0.0': - resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} - engines: {node: '>= 20'} + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] - '@octokit/core@7.0.6': - resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} - engines: {node: '>= 20'} + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] - '@octokit/endpoint@11.0.2': - resolution: {integrity: sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==} - engines: {node: '>= 20'} - - '@octokit/graphql@9.0.3': - resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} - engines: {node: '>= 20'} - - '@octokit/openapi-types@26.0.0': - resolution: {integrity: sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==} - - '@octokit/openapi-types@27.0.0': - resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] - '@octokit/plugin-paginate-rest@13.2.1': - resolution: {integrity: sha512-Tj4PkZyIL6eBMYcG/76QGsedF0+dWVeLhYprTmuFVVxzDW7PQh23tM0TP0z+1MvSkxB29YFZwnUX+cXfTiSdyw==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] - '@octokit/plugin-retry@8.0.3': - resolution: {integrity: sha512-vKGx1i3MC0za53IzYBSBXcrhmd+daQDzuZfYDd52X5S0M2otf3kVZTVP8bLA3EkU0lTvd1WEC2OlNNa4G+dohA==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=7' + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] - '@octokit/plugin-throttling@11.0.3': - resolution: {integrity: sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': ^7.0.0 + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] - '@octokit/request-error@7.1.0': - resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} - engines: {node: '>= 20'} + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] - '@octokit/request@10.0.7': - resolution: {integrity: sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==} - engines: {node: '>= 20'} + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] - '@octokit/types@15.0.2': - resolution: {integrity: sha512-rR+5VRjhYSer7sC51krfCctQhVTmjyUMAaShfPB8mscVa8tSoLyon3coxQmXu0ahJoLVWl8dSGD/3OGZlFV44Q==} + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] - '@octokit/types@16.0.0': - resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] - '@one-ini/wasm@0.1.1': - resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] - '@openapi-contrib/openapi-schema-to-json-schema@3.2.0': - resolution: {integrity: sha512-Gj6C0JwCr8arj0sYuslWXUBSP/KnUlEGnPW4qxlXvAl543oaNQgMgIgkQUA6vs5BCCvwTEiL8m/wdWzfl4UvSw==} + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] - '@oxc-project/runtime@0.101.0': - resolution: {integrity: sha512-t3qpfVZIqSiLQ5Kqt/MC4Ge/WCOGrrcagAdzTcDaggupjiGxUx4nJF2v6wUCXWSzWHn5Ns7XLv13fCJEwCOERQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] - '@oxc-project/types@0.101.0': - resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==} + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] - '@pinojs/redact@0.4.0': - resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] - '@playwright/test@1.58.1': - resolution: {integrity: sha512-6LdVIUERWxQMmUSSQi0I53GgCBYgM2RpGngCPY7hSeju+VrKjq3lvs7HpJoPbDiY5QM5EYRtRX5fvrinnMAz3w==} + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} - hasBin: true - - '@pnpm/config.env-replace@1.1.0': - resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} - engines: {node: '>=12.22.0'} - - '@pnpm/network.ca-file@1.0.2': - resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} - engines: {node: '>=12.22.0'} - - '@pnpm/npm-conf@3.0.2': - resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} - engines: {node: '>=12'} - - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - - '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@puppeteer/browsers@2.3.0': - resolution: {integrity: sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==} + '@inquirer/checkbox@4.3.2': + resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} engines: {node: '>=18'} - hasBin: true - - '@radix-ui/primitive@1.1.3': - resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - - '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': + '@types/node': optional: true - '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': + '@types/node': optional: true - '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + '@inquirer/editor@4.2.23': + resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + '@inquirer/expand@4.0.23': + resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': + '@types/node': optional: true - '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-id@1.1.1': - resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/input@4.3.1': + resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': + '@types/node': optional: true - '@radix-ui/react-popover@1.1.15': - resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + '@inquirer/number@3.0.23': + resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-popper@1.2.8': - resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + '@inquirer/password@4.0.23': + resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + '@inquirer/prompts@7.10.1': + resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + '@inquirer/prompts@7.9.0': + resolution: {integrity: sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + '@inquirer/rawlist@4.1.11': + resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': + '@types/node': optional: true - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + '@inquirer/search@3.2.2': + resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': + '@types/node': optional: true - '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + '@inquirer/select@4.4.2': + resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': + '@types/node': optional: true - '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + '@types/node': '>=18' peerDependenciesMeta: - '@types/react': + '@types/node': optional: true - '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + '@ioredis/commands@1.5.1': + resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==} + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.1': + resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} + engines: {node: 20 || >=22} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsep-plugin/assignment@1.3.0': + resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} + engines: {node: '>= 10.16.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + jsep: ^0.4.0||^1.0.0 - '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + '@jsep-plugin/regex@1.0.4': + resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} + engines: {node: '>= 10.16.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + jsep: ^0.4.0||^1.0.0 - '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + '@jsep-plugin/ternary@1.1.4': + resolution: {integrity: sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==} + engines: {node: '>= 10.16.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + jsep: ^0.4.0||^1.0.0 - '@radix-ui/react-use-rect@1.1.1': - resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + tslib: '2' - '@radix-ui/react-use-size@1.1.1': - resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + '@jsonjoy.com/base64@17.67.0': + resolution: {integrity: sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==} + engines: {node: '>=10.0'} peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + tslib: '2' - '@radix-ui/rect@1.1.1': - resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-android-arm64@1.0.0-beta.53': - resolution: {integrity: sha512-Ok9V8o7o6YfSdTTYA/uHH30r3YtOxLD6G3wih/U9DO0ucBBFq8WPt/DslU53OgfteLRHITZny9N/qCUxMf9kjQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] + '@jsonjoy.com/buffers@17.67.0': + resolution: {integrity: sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-darwin-arm64@1.0.0-beta.53': - resolution: {integrity: sha512-yIsKqMz0CtRnVa6x3Pa+mzTihr4Ty+Z6HfPbZ7RVbk1Uxnco4+CUn7Qbm/5SBol1JD/7nvY8rphAgyAi7Lj6Vg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-darwin-x64@1.0.0-beta.53': - resolution: {integrity: sha512-GTXe+mxsCGUnJOFMhfGWmefP7Q9TpYUseHvhAhr21nCTgdS8jPsvirb0tJwM3lN0/u/cg7bpFNa16fQrjKrCjQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] + '@jsonjoy.com/codegen@17.67.0': + resolution: {integrity: sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-freebsd-x64@1.0.0-beta.53': - resolution: {integrity: sha512-9Tmp7bBvKqyDkMcL4e089pH3RsjD3SUungjmqWtyhNOxoQMh0fSmINTyYV8KXtE+JkxYMPWvnEt+/mfpVCkk8w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] + '@jsonjoy.com/fs-core@4.56.11': + resolution: {integrity: sha512-wThHjzUp01ImIjfCwhs+UnFkeGPFAymwLEkOtenHewaKe2pTP12p6r1UuwikA9NEvNf9Vlck92r8fb8n/MWM5w==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': - resolution: {integrity: sha512-a1y5fiB0iovuzdbjUxa7+Zcvgv+mTmlGGC4XydVIsyl48eoxgaYkA3l9079hyTyhECsPq+mbr0gVQsFU11OJAQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] + '@jsonjoy.com/fs-fsa@4.56.11': + resolution: {integrity: sha512-ZYlF3XbMayyp97xEN8ZvYutU99PCHjM64mMZvnCseXkCJXJDVLAwlF8Q/7q/xiWQRsv3pQBj1WXHd9eEyYcaCQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': - resolution: {integrity: sha512-bpIGX+ov9PhJYV+wHNXl9rzq4F0QvILiURn0y0oepbQx+7stmQsKA0DhPGwmhfvF856wq+gbM8L92SAa/CBcLg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] + '@jsonjoy.com/fs-node-builtins@4.56.11': + resolution: {integrity: sha512-CNmt3a0zMCIhniFLXtzPWuUxXFU+U+2VyQiIrgt/rRVeEJNrMQUABaRbVxR0Ouw1LyR9RjaEkPM6nYpED+y43A==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': - resolution: {integrity: sha512-bGe5EBB8FVjHBR1mOLOPEFg1Lp3//7geqWkU5NIhxe+yH0W8FVrQ6WRYOap4SUTKdklD/dC4qPLREkMMQ855FA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] + '@jsonjoy.com/fs-node-to-fsa@4.56.11': + resolution: {integrity: sha512-5OzGdvJDgZVo+xXWEYo72u81zpOWlxlbG4d4nL+hSiW+LKlua/dldNgPrpWxtvhgyntmdFQad2UTxFyGjJAGhA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': - resolution: {integrity: sha512-qL+63WKVQs1CMvFedlPt0U9PiEKJOAL/bsHMKUDS6Vp2Q+YAv/QLPu8rcvkfIMvQ0FPU2WL0aX4eWwF6e/GAnA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] + '@jsonjoy.com/fs-node-utils@4.56.11': + resolution: {integrity: sha512-JADOZFDA3wRfsuxkT0+MYc4F9hJO2PYDaY66kRTG6NqGX3+bqmKu66YFYAbII/tEmQWPZeHoClUB23rtQM9UPg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': - resolution: {integrity: sha512-VGl9JIGjoJh3H8Mb+7xnVqODajBmrdOOb9lxWXdcmxyI+zjB2sux69br0hZJDTyLJfvBoYm439zPACYbCjGRmw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] + '@jsonjoy.com/fs-node@4.56.11': + resolution: {integrity: sha512-D65YrnP6wRuZyEWoSFnBJSr5zARVpVBGctnhie4rCsMuGXNzX7IHKaOt85/Aj7SSoG1N2+/xlNjWmkLvZ2H3Tg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': - resolution: {integrity: sha512-B4iIserJXuSnNzA5xBLFUIjTfhNy7d9sq4FUMQY3GhQWGVhS2RWWzzDnkSU6MUt7/aHUrep0CdQfXUJI9D3W7A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] + '@jsonjoy.com/fs-print@4.56.11': + resolution: {integrity: sha512-rnaKRgCRIn8JGTjxhS0JPE38YM3Pj/H7SW4/tglhIPbfKEkky7dpPayNKV2qy25SZSL15oFVgH/62dMZ/z7cyA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': - resolution: {integrity: sha512-BUjAEgpABEJXilGq/BPh7jeU3WAJ5o15c1ZEgHaDWSz3LB881LQZnbNJHmUiM4d1JQWMYYyR1Y490IBHi2FPJg==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] + '@jsonjoy.com/fs-snapshot@4.56.11': + resolution: {integrity: sha512-IIldPX+cIRQuUol9fQzSS3hqyECxVpYMJQMqdU3dCKZFRzEl1rkIkw4P6y7Oh493sI7YdxZlKr/yWdzEWZ1wGQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': - resolution: {integrity: sha512-s27uU7tpCWSjHBnxyVXHt3rMrQdJq5MHNv3BzsewCIroIw3DJFjMH1dzCPPMUFxnh1r52Nf9IJ/eWp6LDoyGcw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': - resolution: {integrity: sha512-cjWL/USPJ1g0en2htb4ssMjIycc36RvdQAx1WlXnS6DpULswiUTVXPDesTifSKYSyvx24E0YqQkEm0K/M2Z/AA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] + '@jsonjoy.com/json-pack@17.67.0': + resolution: {integrity: sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/pluginutils@1.0.0-beta.50': - resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==} + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/pluginutils@1.0.0-beta.53': - resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + '@jsonjoy.com/json-pointer@17.67.0': + resolution: {integrity: sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rolldown/pluginutils@1.0.0-rc.2': - resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - '@rollup/plugin-inject@5.0.5': - resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} - engines: {node: '>=14.0.0'} + '@jsonjoy.com/util@17.67.0': + resolution: {integrity: sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==} + engines: {node: '>=10.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + tslib: '2' - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@juggle/resize-observer@3.4.0': + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} - '@rollup/rollup-android-arm-eabi@4.57.1': - resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} - cpu: [arm] - os: [android] + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} - '@rollup/rollup-android-arm64@4.57.1': - resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} - cpu: [arm64] - os: [android] + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - '@rollup/rollup-darwin-arm64@4.57.1': - resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} - cpu: [arm64] - os: [darwin] + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@rollup/rollup-darwin-x64@4.57.1': - resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} - cpu: [x64] - os: [darwin] + '@lifeomic/attempt@3.1.0': + resolution: {integrity: sha512-QZqem4QuAnAyzfz+Gj5/+SLxqwCAw2qmt7732ZXodr6VDWGeYLG6w1i/vYLa55JQM9wRuBKLmXmiZ2P0LtE5rw==} - '@rollup/rollup-freebsd-arm64@4.57.1': - resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} - cpu: [arm64] - os: [freebsd] + '@listr2/prompt-adapter-inquirer@3.0.5': + resolution: {integrity: sha512-WELs+hj6xcilkloBXYf9XXK8tYEnKsgLj01Xl5ONUJpKjmT5hGVUzNUS5tooUxs7pGMrw+jFD/41WpqW4V3LDA==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@inquirer/prompts': '>= 3 < 8' + listr2: 9.0.5 - '@rollup/rollup-freebsd-x64@4.57.1': - resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} - cpu: [x64] - os: [freebsd] + '@liveblocks/client@3.15.1': + resolution: {integrity: sha512-blyXz3ZytMCZn6gis0CtadMe6zPB7aPlJ+5JaRcJM4wP9ANP1/bM+K65lMCQZ/kSSVLuRJpUFlWYFTrTQbBqEg==} - '@rollup/rollup-linux-arm-gnueabihf@4.57.1': - resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} - cpu: [arm] - os: [linux] + '@liveblocks/core@3.15.1': + resolution: {integrity: sha512-rPjHU7Z1x2IQlKLd5S7ySk8oL3z8sFr4+8u2sStZ5JqpD+0wnJpMxT1QHlswwx116ZTBBRcKp3Pm/0ihPraIHg==} + peerDependencies: + '@types/json-schema': ^7 - '@rollup/rollup-linux-arm-musleabihf@4.57.1': - resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} - cpu: [arm] - os: [linux] + '@liveblocks/node@3.15.1': + resolution: {integrity: sha512-ais3uEnKQqBPzZTM7Zd1d5PbF4F0L1tGo5bbHYcmHiddc7try0HRI/I9dLCICRpil72eFhPubV7/vy2EOBaDSA==} - '@rollup/rollup-linux-arm64-gnu@4.57.1': - resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} - cpu: [arm64] - os: [linux] + '@liveblocks/yjs@3.15.1': + resolution: {integrity: sha512-RyjIJ5Bk1FtlPyXyqM3biJQXFaov+Ng2qVJEURWTGio7R+lCZOh3jCZzUetnaohF0ZPm+JROB5/3CxQQ88R4hg==} + peerDependencies: + yjs: ^13.6.1 - '@rollup/rollup-linux-arm64-musl@4.57.1': - resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} + '@lmdb/lmdb-darwin-arm64@3.5.1': + resolution: {integrity: sha512-tpfN4kKrrMpQ+If1l8bhmoNkECJi0iOu6AEdrTJvWVC+32sLxTARX5Rsu579mPImRP9YFWfWgeRQ5oav7zApQQ==} cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.57.1': - resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-loong64-musl@4.57.1': - resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.57.1': - resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-ppc64-musl@4.57.1': - resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.57.1': - resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} - cpu: [riscv64] - os: [linux] + os: [darwin] - '@rollup/rollup-linux-riscv64-musl@4.57.1': - resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} - cpu: [riscv64] - os: [linux] + '@lmdb/lmdb-darwin-x64@3.5.1': + resolution: {integrity: sha512-+a2tTfc3rmWhLAolFUWRgJtpSuu+Fw/yjn4rF406NMxhfjbMuiOUTDRvRlMFV+DzyjkwnokisskHbCWkS3Ly5w==} + cpu: [x64] + os: [darwin] - '@rollup/rollup-linux-s390x-gnu@4.57.1': - resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} - cpu: [s390x] + '@lmdb/lmdb-linux-arm64@3.5.1': + resolution: {integrity: sha512-aoERa5B6ywXdyFeYGQ1gbQpkMkDbEo45qVoXE5QpIRavqjnyPwjOulMkmkypkmsbJ5z4Wi0TBztON8agCTG0Vg==} + cpu: [arm64] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.57.1': - resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} - cpu: [x64] + '@lmdb/lmdb-linux-arm@3.5.1': + resolution: {integrity: sha512-0EgcE6reYr8InjD7V37EgXcYrloqpxVPINy3ig1MwDSbl6LF/vXTYRH9OE1Ti1D8YZnB35ZH9aTcdfSb5lql2A==} + cpu: [arm] os: [linux] - '@rollup/rollup-linux-x64-musl@4.57.1': - resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} + '@lmdb/lmdb-linux-x64@3.5.1': + resolution: {integrity: sha512-SqNDY1+vpji7bh0sFH5wlWyFTOzjbDOl0/kB5RLLYDAFyd/uw3n7wyrmas3rYPpAW7z18lMOi1yKlTPv967E3g==} cpu: [x64] os: [linux] - '@rollup/rollup-openbsd-x64@4.57.1': - resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.57.1': - resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.57.1': - resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} + '@lmdb/lmdb-win32-arm64@3.5.1': + resolution: {integrity: sha512-50v0O1Lt37cwrmR9vWZK5hRW0Aw+KEmxJJ75fge/zIYdvNKB/0bSMSVR5Uc2OV9JhosIUyklOmrEvavwNJ8D6w==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.57.1': - resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.57.1': - resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} + '@lmdb/lmdb-win32-x64@3.5.1': + resolution: {integrity: sha512-qwosvPyl+zpUlp3gRb7UcJ3H8S28XHCzkv0Y0EgQToXjQP91ZD67EHSCDmaLjtKhe+GVIW5om1KUpzVLA0l6pg==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.57.1': - resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} - cpu: [x64] - os: [win32] + '@mapbox/node-pre-gyp@2.0.3': + resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} + engines: {node: '>=18'} + hasBin: true - '@rushstack/node-core-library@5.19.1': - resolution: {integrity: sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} - '@rushstack/problem-matcher@0.1.1': - resolution: {integrity: sha512-Fm5XtS7+G8HLcJHCWpES5VmeMyjAKaWeyZU5qPzZC+22mPlJzAsOxymHiWIfuirtPckX3aptWws+K2d0BzniJA==} + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true + '@types/react': '>=16' + react: '>=16' - '@rushstack/rig-package@0.6.0': - resolution: {integrity: sha512-ZQmfzsLE2+Y91GF15c65L/slMRVhF6Hycq04D4TwtdGaUAbIXXg9c5pKA5KFU7M4QMaihoobp9JJYpYcaY3zOw==} + '@microsoft/api-extractor-model@7.32.2': + resolution: {integrity: sha512-Ussc25rAalc+4JJs9HNQE7TuO9y6jpYQX9nWD1DhqUzYPBr3Lr7O9intf+ZY8kD5HnIqeIRJX7ccCT0QyBy2Ww==} - '@rushstack/terminal@0.21.0': - resolution: {integrity: sha512-cLaI4HwCNYmknM5ns4G+drqdEB6q3dCPV423+d3TZeBusYSSm09+nR7CnhzJMjJqeRcdMAaLnrA4M/3xDz4R3w==} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true + '@microsoft/api-extractor@7.56.1': + resolution: {integrity: sha512-wX9ugJFqhsEWwt+UFTAkvXcBOzSQ1FeKe0ZdwEDKtjsf20Ec2frmCDXPjQwPtSNrpXUy1yQgyaF6YJVuC8gMtg==} + hasBin: true - '@rushstack/ts-command-line@5.2.0': - resolution: {integrity: sha512-lYxCX0nDdkDtCkVpvF0m25ymf66SaMWuppbD6b7MdkIzvGXKBXNIVZlwBH/C0YfkanrupnICWf2n4z3AKSfaHw==} + '@microsoft/tsdoc-config@0.18.0': + resolution: {integrity: sha512-8N/vClYyfOH+l4fLkkr9+myAoR6M7akc8ntBJ4DJdWH2b09uVfr71+LTMpNyG19fNqWDg8KEDZhx5wxuqHyGjw==} - '@sec-ant/readable-stream@0.4.1': - resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@microsoft/tsdoc@0.16.0': + resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} - '@semantic-release/changelog@6.0.3': - resolution: {integrity: sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==} - engines: {node: '>=14.17'} - peerDependencies: - semantic-release: '>=18.0.0' + '@mintlify/cli@4.0.935': + resolution: {integrity: sha512-mY0T3QOdDNuZlb4qx6GEAq0nSkWQGCn0Ug5kjQH3GjZFeeROm0EDYzoXlwAgLL/DkFEU9GpWmO3kU8EvetXtBw==} + engines: {node: '>=18.0.0'} + hasBin: true - '@semantic-release/commit-analyzer@13.0.1': - resolution: {integrity: sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==} - engines: {node: '>=20.8.1'} - peerDependencies: - semantic-release: '>=20.1.0' + '@mintlify/common@1.0.661': + resolution: {integrity: sha512-/Hdiblzaomp+AWStQ4smhVMgesQhffzQjC9aYBnmLReNdh2Js+ccQFUaWL3TNIxwiS2esaZvsHSV/D+zyRS3hg==} - '@semantic-release/error@3.0.0': - resolution: {integrity: sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==} - engines: {node: '>=14.17'} + '@mintlify/common@1.0.713': + resolution: {integrity: sha512-0Ir8BLMVfADPi04/O5jDDemL+dxpNqHgx/JDQALuCFS4ANqHk7C9ES7ifsnt/rjmiiX7kuXSFqoAZrt1WMTLaA==} - '@semantic-release/error@4.0.0': - resolution: {integrity: sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==} - engines: {node: '>=18'} + '@mintlify/link-rot@3.0.872': + resolution: {integrity: sha512-2KDAD+hTmRZZCq0XCvvG+p/xSn5gtHCkHYA8Zfd2mhHceHCofNikvjffpYKx96eqaNCLhbeUYVnLlquBs820oQ==} + engines: {node: '>=18.0.0'} - '@semantic-release/exec@6.0.3': - resolution: {integrity: sha512-bxAq8vLOw76aV89vxxICecEa8jfaWwYITw6X74zzlO0mc/Bgieqx9kBRz9z96pHectiTAtsCwsQcUyLYWnp3VQ==} - engines: {node: '>=14.17'} + '@mintlify/mdx@3.0.4': + resolution: {integrity: sha512-tJhdpnM5ReJLNJ2fuDRIEr0zgVd6id7/oAIfs26V46QlygiLsc8qx4Rz3LWIX51rUXW/cfakjj0EATxIciIw+g==} peerDependencies: - semantic-release: '>=18.0.0' + '@radix-ui/react-popover': ^1.1.15 + react: ^18.3.1 + react-dom: ^18.3.1 - '@semantic-release/git@10.0.1': - resolution: {integrity: sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==} - engines: {node: '>=14.17'} - peerDependencies: - semantic-release: '>=18.0.0' + '@mintlify/models@0.0.255': + resolution: {integrity: sha512-LIUkfA7l7ypHAAuOW74ZJws/NwNRqlDRD/U466jarXvvSlGhJec/6J4/I+IEcBvWDnc9anLFKmnGO04jPKgAsg==} + engines: {node: '>=18.0.0'} - '@semantic-release/github@11.0.6': - resolution: {integrity: sha512-ctDzdSMrT3H+pwKBPdyCPty6Y47X8dSrjd3aPZ5KKIKKWTwZBE9De8GtsH3TyAlw3Uyo2stegMx6rJMXKpJwJA==} - engines: {node: '>=20.8.1'} - peerDependencies: - semantic-release: '>=24.1.0' + '@mintlify/models@0.0.268': + resolution: {integrity: sha512-8HDPI3luABg5p/VTVYAOqabqOtcK2jdBuRTYOJiV39QqjQY29Q7kWH697PUokN6CO9uP2CCkPG5O5Gi7QxflWA==} + engines: {node: '>=18.0.0'} - '@semantic-release/npm@12.0.2': - resolution: {integrity: sha512-+M9/Lb35IgnlUO6OSJ40Ie+hUsZLuph2fqXC/qrKn0fMvUU/jiCjpoL6zEm69vzcmaZJ8yNKtMBEKHWN49WBbQ==} - engines: {node: '>=20.8.1'} - peerDependencies: - semantic-release: '>=20.1.0' + '@mintlify/openapi-parser@0.0.8': + resolution: {integrity: sha512-9MBRq9lS4l4HITYCrqCL7T61MOb20q9IdU7HWhqYMNMM1jGO1nHjXasFy61yZ8V6gMZyyKQARGVoZ0ZrYN48Og==} + engines: {node: '>=18'} - '@semantic-release/release-notes-generator@14.1.0': - resolution: {integrity: sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA==} - engines: {node: '>=20.8.1'} - peerDependencies: - semantic-release: '>=20.1.0' + '@mintlify/prebuild@1.0.849': + resolution: {integrity: sha512-GlFRJYrS7sIByZXKLa91VeCGruMunbwoxGbWRF5gAiknkuhng9SuX7zB7yTa0J3ApmLO3oZG5baWfzflcQY01w==} - '@shikijs/core@3.22.0': - resolution: {integrity: sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==} + '@mintlify/previewing@4.0.905': + resolution: {integrity: sha512-3PjzszHkvswA742dofEDohINUnlbmi4gnKP9xWK7wA+dLszKJ56BYjm6VCWJjpG3PuO4oPFIS9vI1YRCEM8kRQ==} + engines: {node: '>=18.0.0'} - '@shikijs/engine-javascript@3.22.0': - resolution: {integrity: sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==} + '@mintlify/scraping@4.0.522': + resolution: {integrity: sha512-PL2k52WT5S5OAgnT2K13bP7J2El6XwiVvQlrLvxDYw5KMMV+y34YVJI8ZscKb4trjitWDgyK0UTq2KN6NQgn6g==} + engines: {node: '>=18.0.0'} + hasBin: true - '@shikijs/engine-oniguruma@3.22.0': - resolution: {integrity: sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==} + '@mintlify/scraping@4.0.574': + resolution: {integrity: sha512-FN2MM8uxBi2Foxpua0UIDLYo4YvcJE/NMwOGfbQ/HWx73eWhsA0LI+uhqpq8ZYqgc4awVif1oKc7OcuEhtY7Kg==} + engines: {node: '>=18.0.0'} + hasBin: true - '@shikijs/langs@3.22.0': - resolution: {integrity: sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==} + '@mintlify/validation@0.1.555': + resolution: {integrity: sha512-11QVUReL4N5u8wSCgZt4RN7PA0jYQoMEBZ5IrUp5pgb5ZJBOoGV/vPsQrxPPa1cxsUDAuToNhtGxRQtOav/w8w==} - '@shikijs/themes@3.22.0': - resolution: {integrity: sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==} + '@mintlify/validation@0.1.585': + resolution: {integrity: sha512-32mezT7v1dmPQa2DyGDYf0t+HHUbmpShJVnMrxxhXyMHvKUqOu4ENoRCAxRbfc4OLPxAFRB4qEEq2toID+tOHw==} - '@shikijs/transformers@3.22.0': - resolution: {integrity: sha512-E7eRV7mwDBjueLF6852n2oYeJYxBq3NSsDk+uyruYAXONv4U8holGmIrT+mPRJQ1J1SNOH6L8G19KRzmBawrFw==} - - '@shikijs/twoslash@3.22.0': - resolution: {integrity: sha512-GO27UPN+kegOMQvC+4XcLt0Mttyg+n16XKjmoKjdaNZoW+sOJV7FLdv2QKauqUDws6nE3EQPD+TFHEdyyoUBDw==} + '@modelcontextprotocol/sdk@1.26.0': + resolution: {integrity: sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==} + engines: {node: '>=18'} peerDependencies: - typescript: '>=5.5.0' + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true - '@shikijs/types@3.22.0': - resolution: {integrity: sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + cpu: [arm64] + os: [darwin] - '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + cpu: [x64] + os: [darwin] - '@sindresorhus/is@4.6.0': - resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} - engines: {node: '>=10'} + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + cpu: [arm64] + os: [linux] - '@sindresorhus/is@5.6.0': - resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} - engines: {node: '>=14.16'} + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + cpu: [arm] + os: [linux] - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + cpu: [x64] + os: [linux] - '@sindresorhus/slugify@2.2.0': - resolution: {integrity: sha512-9Vybc/qX8Kj6pxJaapjkFbiUJPk7MAkCh/GFCxIBnnsuYCFPIXKvnLidG8xlepht3i24L5XemUmGtrJ3UWrl6w==} - engines: {node: '>=12'} + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + cpu: [x64] + os: [win32] - '@sindresorhus/transliterate@1.6.0': - resolution: {integrity: sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==} - engines: {node: '>=12'} + '@napi-rs/canvas-android-arm64@0.1.91': + resolution: {integrity: sha512-SLLzXXgSnfct4zy/BVAfweZQkYkPJsNsJ2e5DOE8DFEHC6PufyUrwb12yqeu2So2IOIDpWJJaDAxKY/xpy6MYQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] - '@smithy/abort-controller@4.2.8': - resolution: {integrity: sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-darwin-arm64@0.1.91': + resolution: {integrity: sha512-bzdbCjIjw3iRuVFL+uxdSoMra/l09ydGNX9gsBxO/zg+5nlppscIpj6gg+nL6VNG85zwUarDleIrUJ+FWHvmuA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] - '@smithy/chunked-blob-reader-native@4.2.1': - resolution: {integrity: sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-darwin-x64@0.1.91': + resolution: {integrity: sha512-q3qpkpw0IsG9fAS/dmcGIhCVoNxj8ojbexZKWwz3HwxlEWsLncEQRl4arnxrwbpLc2nTNTyj4WwDn7QR5NDAaA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] - '@smithy/chunked-blob-reader@5.2.0': - resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.91': + resolution: {integrity: sha512-Io3g8wJZVhK8G+Fpg1363BE90pIPqg+ZbeehYNxPWDSzbgwU3xV0l8r/JBzODwC7XHi1RpFEk+xyUTMa2POj6w==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] - '@smithy/config-resolver@4.4.6': - resolution: {integrity: sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-linux-arm64-gnu@0.1.91': + resolution: {integrity: sha512-HBnto+0rxx1bQSl8bCWA9PyBKtlk2z/AI32r3cu4kcNO+M/5SD4b0v1MWBWZyqMQyxFjWgy3ECyDjDKMC6tY1A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@smithy/core@3.23.0': - resolution: {integrity: sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-linux-arm64-musl@0.1.91': + resolution: {integrity: sha512-/eJtVe2Xw9A86I4kwXpxxoNagdGclu12/NSMsfoL8q05QmeRCbfjhg1PJS7ENAuAvaiUiALGrbVfeY1KU1gztQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@smithy/credential-provider-imds@4.2.8': - resolution: {integrity: sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-linux-riscv64-gnu@0.1.91': + resolution: {integrity: sha512-floNK9wQuRWevUhhXRcuis7h0zirdytVxPgkonWO+kQlbvxV7gEUHGUFQyq4n55UHYFwgck1SAfJ1HuXv/+ppQ==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] - '@smithy/eventstream-codec@4.2.8': - resolution: {integrity: sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-linux-x64-gnu@0.1.91': + resolution: {integrity: sha512-c3YDqBdf7KETuZy2AxsHFMsBBX1dWT43yFfWUq+j1IELdgesWtxf/6N7csi3VPf6VA3PmnT9EhMyb+M1wfGtqw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@smithy/eventstream-serde-browser@4.2.8': - resolution: {integrity: sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-linux-x64-musl@0.1.91': + resolution: {integrity: sha512-RpZ3RPIwgEcNBHSHSX98adm+4VP8SMT5FN6250s5jQbWpX/XNUX5aLMfAVJS/YnDjS1QlsCgQxFOPU0aCCWgag==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@smithy/eventstream-serde-config-resolver@4.3.8': - resolution: {integrity: sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-win32-arm64-msvc@0.1.91': + resolution: {integrity: sha512-gF8MBp4X134AgVurxqlCdDA2qO0WaDdi9o6Sd5rWRVXRhWhYQ6wkdEzXNLIrmmros0Tsp2J0hQzx4ej/9O8trQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] - '@smithy/eventstream-serde-node@4.2.8': - resolution: {integrity: sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas-win32-x64-msvc@0.1.91': + resolution: {integrity: sha512-++gtW9EV/neKI8TshD8WFxzBYALSPag2kFRahIJV+LYsyt5kBn21b1dBhEUDHf7O+wiZmuFCeUa7QKGHnYRZBA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] - '@smithy/eventstream-serde-universal@4.2.8': - resolution: {integrity: sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/canvas@0.1.91': + resolution: {integrity: sha512-eeIe1GoB74P1B0Nkw6pV8BCQ3hfCfvyYr4BntzlCsnFXzVJiPMDnLeIx3gVB0xQMblHYnjK/0nCLvirEhOjr5g==} + engines: {node: '>= 10'} - '@smithy/fetch-http-handler@5.3.9': - resolution: {integrity: sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-android-arm-eabi@1.1.1': + resolution: {integrity: sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] - '@smithy/hash-blob-browser@4.2.9': - resolution: {integrity: sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-android-arm64@1.1.1': + resolution: {integrity: sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] - '@smithy/hash-node@4.2.8': - resolution: {integrity: sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-darwin-arm64@1.1.1': + resolution: {integrity: sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] - '@smithy/hash-stream-node@4.2.8': - resolution: {integrity: sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-darwin-x64@1.1.1': + resolution: {integrity: sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] - '@smithy/invalid-dependency@4.2.8': - resolution: {integrity: sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-freebsd-x64@1.1.1': + resolution: {integrity: sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] - '@smithy/is-array-buffer@2.2.0': - resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} - engines: {node: '>=14.0.0'} + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + resolution: {integrity: sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] - '@smithy/is-array-buffer@4.2.0': - resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + resolution: {integrity: sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@smithy/md5-js@4.2.8': - resolution: {integrity: sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-linux-arm64-musl@1.1.1': + resolution: {integrity: sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@smithy/middleware-content-length@4.2.8': - resolution: {integrity: sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + resolution: {integrity: sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==} + engines: {node: '>= 10'} + cpu: [ppc64] + os: [linux] - '@smithy/middleware-endpoint@4.4.14': - resolution: {integrity: sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + resolution: {integrity: sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] - '@smithy/middleware-retry@4.4.31': - resolution: {integrity: sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + resolution: {integrity: sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==} + engines: {node: '>= 10'} + cpu: [s390x] + os: [linux] - '@smithy/middleware-serde@4.2.9': - resolution: {integrity: sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-linux-x64-gnu@1.1.1': + resolution: {integrity: sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@smithy/middleware-stack@4.2.8': - resolution: {integrity: sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-linux-x64-musl@1.1.1': + resolution: {integrity: sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@smithy/node-config-provider@4.3.8': - resolution: {integrity: sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-openharmony-arm64@1.1.1': + resolution: {integrity: sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [openharmony] - '@smithy/node-http-handler@4.4.10': - resolution: {integrity: sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + resolution: {integrity: sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] - '@smithy/property-provider@4.2.8': - resolution: {integrity: sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + resolution: {integrity: sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] - '@smithy/protocol-http@5.3.8': - resolution: {integrity: sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice-win32-x64-msvc@1.1.1': + resolution: {integrity: sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] - '@smithy/querystring-builder@4.2.8': - resolution: {integrity: sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==} - engines: {node: '>=18.0.0'} + '@napi-rs/nice@1.1.1': + resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} + engines: {node: '>= 10'} - '@smithy/querystring-parser@4.2.8': - resolution: {integrity: sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==} - engines: {node: '>=18.0.0'} + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@smithy/service-error-classification@4.2.8': - resolution: {integrity: sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==} - engines: {node: '>=18.0.0'} + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} - '@smithy/shared-ini-file-loader@4.4.3': - resolution: {integrity: sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==} - engines: {node: '>=18.0.0'} + '@next/env@16.1.6': + resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==} - '@smithy/signature-v4@5.3.8': - resolution: {integrity: sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==} - engines: {node: '>=18.0.0'} - - '@smithy/smithy-client@4.11.3': - resolution: {integrity: sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg==} - engines: {node: '>=18.0.0'} - - '@smithy/types@4.12.0': - resolution: {integrity: sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==} - engines: {node: '>=18.0.0'} - - '@smithy/url-parser@4.2.8': - resolution: {integrity: sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==} - engines: {node: '>=18.0.0'} + '@next/eslint-plugin-next@16.1.6': + resolution: {integrity: sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==} - '@smithy/util-base64@4.3.0': - resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} - engines: {node: '>=18.0.0'} + '@next/swc-darwin-arm64@16.1.6': + resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] - '@smithy/util-body-length-browser@4.2.0': - resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} - engines: {node: '>=18.0.0'} + '@next/swc-darwin-x64@16.1.6': + resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] - '@smithy/util-body-length-node@4.2.1': - resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} - engines: {node: '>=18.0.0'} + '@next/swc-linux-arm64-gnu@16.1.6': + resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@smithy/util-buffer-from@2.2.0': - resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} - engines: {node: '>=14.0.0'} + '@next/swc-linux-arm64-musl@16.1.6': + resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - '@smithy/util-buffer-from@4.2.0': - resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} - engines: {node: '>=18.0.0'} + '@next/swc-linux-x64-gnu@16.1.6': + resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@smithy/util-config-provider@4.2.0': - resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} - engines: {node: '>=18.0.0'} + '@next/swc-linux-x64-musl@16.1.6': + resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - '@smithy/util-defaults-mode-browser@4.3.30': - resolution: {integrity: sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng==} - engines: {node: '>=18.0.0'} + '@next/swc-win32-arm64-msvc@16.1.6': + resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] - '@smithy/util-defaults-mode-node@4.2.33': - resolution: {integrity: sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA==} - engines: {node: '>=18.0.0'} + '@next/swc-win32-x64-msvc@16.1.6': + resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] - '@smithy/util-endpoints@3.2.8': - resolution: {integrity: sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==} - engines: {node: '>=18.0.0'} + '@ngtools/webpack@21.2.1': + resolution: {integrity: sha512-HGRGTDmyo3IuxxEAVK9/QK2Nd/nwWIh/zcd2x6nmCxC7tdB0fwIhEZhWnUDyLP2QnDaEPeR4NnZCGTN89SWhGg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + peerDependencies: + '@angular/compiler-cli': ^21.0.0 + typescript: '>=5.9 <6.0' + webpack: ^5.54.0 - '@smithy/util-hex-encoding@4.2.0': - resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} - engines: {node: '>=18.0.0'} + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} - '@smithy/util-middleware@4.2.8': - resolution: {integrity: sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==} - engines: {node: '>=18.0.0'} + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} - '@smithy/util-retry@4.2.8': - resolution: {integrity: sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==} - engines: {node: '>=18.0.0'} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} - '@smithy/util-stream@4.5.12': - resolution: {integrity: sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg==} - engines: {node: '>=18.0.0'} + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} - '@smithy/util-uri-escape@4.2.0': - resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} - engines: {node: '>=18.0.0'} + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} - '@smithy/util-utf8@2.3.0': - resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} - engines: {node: '>=14.0.0'} + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} - '@smithy/util-utf8@4.2.0': - resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} - engines: {node: '>=18.0.0'} + '@npmcli/agent@4.0.0': + resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} + engines: {node: ^20.17.0 || >=22.9.0} - '@smithy/util-waiter@4.2.8': - resolution: {integrity: sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==} - engines: {node: '>=18.0.0'} + '@npmcli/fs@5.0.0': + resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} + engines: {node: ^20.17.0 || >=22.9.0} - '@smithy/uuid@1.1.0': - resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} - engines: {node: '>=18.0.0'} + '@npmcli/git@7.0.2': + resolution: {integrity: sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==} + engines: {node: ^20.17.0 || >=22.9.0} - '@socket.io/component-emitter@3.1.2': - resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@npmcli/installed-package-contents@4.0.0': + resolution: {integrity: sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true - '@stoplight/better-ajv-errors@1.0.3': - resolution: {integrity: sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==} - engines: {node: ^12.20 || >= 14.13} - peerDependencies: - ajv: '>=8' + '@npmcli/node-gyp@5.0.0': + resolution: {integrity: sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==} + engines: {node: ^20.17.0 || >=22.9.0} - '@stoplight/json-ref-readers@1.2.2': - resolution: {integrity: sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==} - engines: {node: '>=8.3.0'} + '@npmcli/package-json@7.0.5': + resolution: {integrity: sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==} + engines: {node: ^20.17.0 || >=22.9.0} - '@stoplight/json-ref-resolver@3.1.6': - resolution: {integrity: sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==} - engines: {node: '>=8.3.0'} + '@npmcli/promise-spawn@9.0.1': + resolution: {integrity: sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==} + engines: {node: ^20.17.0 || >=22.9.0} - '@stoplight/json@3.21.0': - resolution: {integrity: sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==} - engines: {node: '>=8.3.0'} + '@npmcli/redact@4.0.0': + resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==} + engines: {node: ^20.17.0 || >=22.9.0} - '@stoplight/ordered-object-literal@1.0.5': - resolution: {integrity: sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==} - engines: {node: '>=8'} + '@npmcli/run-script@10.0.4': + resolution: {integrity: sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==} + engines: {node: ^20.17.0 || >=22.9.0} - '@stoplight/path@1.3.2': - resolution: {integrity: sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==} - engines: {node: '>=8'} + '@nuxt/cli@3.33.1': + resolution: {integrity: sha512-/sCrcI0WemING9zASaXPgPDY7PrQTPlRyCXlSgGx8VwRAkWbxGaPhIc3kZQikgLwVAwy+muWVV4Wks8OTtW5Tw==} + engines: {node: ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@nuxt/schema': ^4.3.0 + peerDependenciesMeta: + '@nuxt/schema': + optional: true - '@stoplight/spectral-core@1.21.0': - resolution: {integrity: sha512-oj4e/FrDLUhBRocIW+lRMKlJ/q/rDZw61HkLbTFsdMd+f/FTkli2xHNB1YC6n1mrMKjjvy7XlUuFkC7XxtgbWw==} - engines: {node: ^16.20 || ^18.18 || >= 20.17} + '@nuxt/devalue@2.0.2': + resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} - '@stoplight/spectral-formats@1.8.2': - resolution: {integrity: sha512-c06HB+rOKfe7tuxg0IdKDEA5XnjL2vrn/m/OVIIxtINtBzphZrOgtRn7epQ5bQF5SWp84Ue7UJWaGgDwVngMFw==} - engines: {node: ^16.20 || ^18.18 || >= 20.17} + '@nuxt/devtools-kit@3.2.3': + resolution: {integrity: sha512-5zj7Xx5CDI6P84kMalXoxGLd470buF6ncsRhiEPq8UlwdpVeR7bwi8QnparZNFBdG79bZ5KUkfi5YDXpLYPoIA==} + peerDependencies: + vite: '>=6.0' - '@stoplight/spectral-functions@1.10.1': - resolution: {integrity: sha512-obu8ZfoHxELOapfGsCJixKZXZcffjg+lSoNuttpmUFuDzVLT3VmH8QkPXfOGOL5Pz80BR35ClNAToDkdnYIURg==} - engines: {node: ^16.20 || ^18.18 || >= 20.17} + '@nuxt/devtools-wizard@3.2.3': + resolution: {integrity: sha512-VXSxWlv476Mhg2RkWMkjslOXcbf0trsp/FDHZTjg9nPDGROGV88xNuvgIF4eClP7zesjETOUow0te6s8504w9A==} + hasBin: true - '@stoplight/spectral-parsers@1.0.5': - resolution: {integrity: sha512-ANDTp2IHWGvsQDAY85/jQi9ZrF4mRrA5bciNHX+PUxPr4DwS6iv4h+FVWJMVwcEYdpyoIdyL+SRmHdJfQEPmwQ==} - engines: {node: ^16.20 || ^18.18 || >= 20.17} + '@nuxt/devtools@3.2.3': + resolution: {integrity: sha512-UfbCHJDQ2DK0D787G6/QhuS2aYCDFTKMgtvE6OBBM1qYpR6pYEu5LRClQr9TFN4TIqJvgluQormGcYr1lsTKTw==} + hasBin: true + peerDependencies: + '@vitejs/devtools': '*' + vite: '>=6.0' + peerDependenciesMeta: + '@vitejs/devtools': + optional: true - '@stoplight/spectral-ref-resolver@1.0.5': - resolution: {integrity: sha512-gj3TieX5a9zMW29z3mBlAtDOCgN3GEc1VgZnCVlr5irmR4Qi5LuECuFItAq4pTn5Zu+sW5bqutsCH7D4PkpyAA==} - engines: {node: ^16.20 || ^18.18 || >= 20.17} + '@nuxt/kit@4.3.1': + resolution: {integrity: sha512-UjBFt72dnpc+83BV3OIbCT0YHLevJtgJCHpxMX0YRKWLDhhbcDdUse87GtsQBrjvOzK7WUNUYLDS/hQLYev5rA==} + engines: {node: '>=18.12.0'} - '@stoplight/spectral-runtime@1.1.4': - resolution: {integrity: sha512-YHbhX3dqW0do6DhiPSgSGQzr6yQLlWybhKwWx0cqxjMwxej3TqLv3BXMfIUYFKKUqIwH4Q2mV8rrMM8qD2N0rQ==} - engines: {node: ^16.20 || ^18.18 || >= 20.17} + '@nuxt/nitro-server@4.3.1': + resolution: {integrity: sha512-4aNiM69Re02gI1ywnDND0m6QdVKXhWzDdtvl/16veytdHZj3FSq57ZCwOClNJ7HQkEMqXgS+bi6S2HmJX+et+g==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + nuxt: ^4.3.1 - '@stoplight/types@13.20.0': - resolution: {integrity: sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==} - engines: {node: ^12.20 || >=14.13} + '@nuxt/schema@4.3.1': + resolution: {integrity: sha512-S+wHJdYDuyk9I43Ej27y5BeWMZgi7R/UVql3b3qtT35d0fbpXW7fUenzhLRCCDC6O10sjguc6fcMcR9sMKvV8g==} + engines: {node: ^14.18.0 || >=16.10.0} - '@stoplight/types@13.6.0': - resolution: {integrity: sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==} - engines: {node: ^12.20 || >=14.13} + '@nuxt/telemetry@2.7.0': + resolution: {integrity: sha512-mrKC3NjAlBOooLLVTYcIUie1meipoYq5vkoESoVTEWTB34T3a0QJzOfOPch+HYlUR+5Lqy1zLMv6epHFgYAKLA==} + engines: {node: '>=18.12.0'} + hasBin: true + peerDependencies: + '@nuxt/kit': '>=3.0.0' - '@stoplight/types@14.1.1': - resolution: {integrity: sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==} - engines: {node: ^12.20 || >=14.13} + '@nuxt/vite-builder@4.3.1': + resolution: {integrity: sha512-LndnxPJzDUDbWAB8q5gZZN1mSOLHEyMOoj4T3pTdPydGf31QZdMR0V1fQ1fdRgtgNtWB3WLP0d1ZfaAOITsUpw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + nuxt: 4.3.1 + rolldown: ^1.0.0-beta.38 + vue: 3.5.25 + peerDependenciesMeta: + rolldown: + optional: true - '@stoplight/yaml-ast-parser@0.0.50': - resolution: {integrity: sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==} + '@octokit/auth-token@6.0.0': + resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} + engines: {node: '>= 20'} - '@stoplight/yaml@4.3.0': - resolution: {integrity: sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==} - engines: {node: '>=10.8'} + '@octokit/core@7.0.6': + resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} + engines: {node: '>= 20'} - '@superdoc-dev/sdk@file:packages/sdk/langs/node': - resolution: {directory: packages/sdk/langs/node, type: directory} + '@octokit/endpoint@11.0.2': + resolution: {integrity: sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==} + engines: {node: '>= 20'} - '@szmarczak/http-timer@4.0.6': - resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} - engines: {node: '>=10'} + '@octokit/graphql@9.0.3': + resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} + engines: {node: '>= 20'} - '@szmarczak/http-timer@5.0.1': - resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} - engines: {node: '>=14.16'} + '@octokit/openapi-types@26.0.0': + resolution: {integrity: sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==} - '@testing-library/dom@10.4.1': - resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} - engines: {node: '>=18'} + '@octokit/openapi-types@27.0.0': + resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} - '@testing-library/jest-dom@6.9.1': - resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} - engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@octokit/plugin-paginate-rest@13.2.1': + resolution: {integrity: sha512-Tj4PkZyIL6eBMYcG/76QGsedF0+dWVeLhYprTmuFVVxzDW7PQh23tM0TP0z+1MvSkxB29YFZwnUX+cXfTiSdyw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' - '@testing-library/react@16.3.2': - resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} - engines: {node: '>=18'} + '@octokit/plugin-retry@8.0.3': + resolution: {integrity: sha512-vKGx1i3MC0za53IzYBSBXcrhmd+daQDzuZfYDd52X5S0M2otf3kVZTVP8bLA3EkU0lTvd1WEC2OlNNa4G+dohA==} + engines: {node: '>= 20'} peerDependencies: - '@testing-library/dom': ^10.0.0 - '@types/react': ^18.0.0 || ^19.0.0 - '@types/react-dom': ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true + '@octokit/core': '>=7' - '@testing-library/user-event@14.6.1': - resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} - engines: {node: '>=12', npm: '>=6'} + '@octokit/plugin-throttling@11.0.3': + resolution: {integrity: sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==} + engines: {node: '>= 20'} peerDependencies: - '@testing-library/dom': '>=7.21.4' + '@octokit/core': ^7.0.0 - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@octokit/request-error@7.1.0': + resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} + engines: {node: '>= 20'} - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@octokit/request@10.0.7': + resolution: {integrity: sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==} + engines: {node: '>= 20'} - '@types/acorn@4.0.6': - resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + '@octokit/types@15.0.2': + resolution: {integrity: sha512-rR+5VRjhYSer7sC51krfCctQhVTmjyUMAaShfPB8mscVa8tSoLyon3coxQmXu0ahJoLVWl8dSGD/3OGZlFV44Q==} - '@types/argparse@1.0.38': - resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + '@octokit/types@16.0.0': + resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + '@openapi-contrib/openapi-schema-to-json-schema@3.2.0': + resolution: {integrity: sha512-Gj6C0JwCr8arj0sYuslWXUBSP/KnUlEGnPW4qxlXvAl543oaNQgMgIgkQUA6vs5BCCvwTEiL8m/wdWzfl4UvSw==} - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + '@oxc-minify/binding-android-arm-eabi@0.112.0': + resolution: {integrity: sha512-m7TGBR2hjsBJIN9UJ909KBoKsuogo6CuLsHKvUIBXdjI0JVHP8g4ZHeB+BJpGn5LJdeSGDfz9MWiuXrZDRzunw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + '@oxc-minify/binding-android-arm64@0.112.0': + resolution: {integrity: sha512-RvxOOkzvP5NeeoraBtgNJSBqO+XzlS7DooxST/drAXCfO52GsmxVB1N7QmifrsTYtH8GC2z3DTFjZQ1w/AJOWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@oxc-minify/binding-darwin-arm64@0.112.0': + resolution: {integrity: sha512-hDslO3uVHza3kB9zkcsi25JzN65Gj5ZYty0OvylS11Mhg9ydCYxAzfQ/tISHW/YmV1NRUJX8+GGqM1cKmrHaTA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - '@types/bun@1.3.8': - resolution: {integrity: sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA==} + '@oxc-minify/binding-darwin-x64@0.112.0': + resolution: {integrity: sha512-mWA2Y5bUyNoGM+gSGGHesgtQ3LDWgpRe4zDGkBDovxNIiDLBXqu/7QcuS+G918w8oG9VYm1q1iinILer/2pD1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@oxc-minify/binding-freebsd-x64@0.112.0': + resolution: {integrity: sha512-T7fsegxcy82xS0jWPXkz/BMhrkb3D7YOCiV0R9pDksjaov+iIFoNEWAoBsaC5NtpdzkX+bmffwDpu336EIfEeg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - '@types/conventional-commits-parser@5.0.2': - resolution: {integrity: sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==} + '@oxc-minify/binding-linux-arm-gnueabihf@0.112.0': + resolution: {integrity: sha512-yePavbIilAcpVYc8vRsDCn3xJxHMXDZIiamyH9fuLosAHNELcLib4/JR4fhDk4NmHVagQH3kRhsnm5Q9cm3pAw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@types/cookie@0.4.1': - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} + '@oxc-minify/binding-linux-arm-musleabihf@0.112.0': + resolution: {integrity: sha512-lmPWLXtW6FspERhy97iP0hwbmLtL66xI29QQ9GpHmTiE4k+zv/FaefuV/Qw+LuHnmFSYzUNrLcxh4ulOZTIP2g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@types/cors@2.8.19': - resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + '@oxc-minify/binding-linux-arm64-gnu@0.112.0': + resolution: {integrity: sha512-gySS5XqU5MKs/oCjsTlVm8zb8lqcNKHEANsaRmhW2qvGKJoeGwFb6Fbq6TLCZMRuk143mLbncbverBCa1c3dog==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@oxc-minify/binding-linux-arm64-musl@0.112.0': + resolution: {integrity: sha512-IRFMZX589lr3rjG0jc8N261/7wqFq2Vl0OMrJWeFls5BF8HiB+fRYuf0Zy2CyRH6NCY2vbdDdp+QCAavQGVsGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@oxc-minify/binding-linux-ppc64-gnu@0.112.0': + resolution: {integrity: sha512-V/69XqIW9hCUceDpcZh79oDg+F4ptEgIfKRENzYs41LRbSoJ7sNjjcW4zifqyviTvzcnXLgK4uoTyoymmNZBMQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] - '@types/es-aggregate-error@1.0.6': - resolution: {integrity: sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==} + '@oxc-minify/binding-linux-riscv64-gnu@0.112.0': + resolution: {integrity: sha512-zghvexySyGXGNW+MutjZN7UGTyOQl56RWMlPe1gb+knBm/+0hf9qjk7Q6ofm2tSte+vQolPfQttifGl0dP9uvQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] - '@types/estree-jsx@1.0.5': - resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@oxc-minify/binding-linux-riscv64-musl@0.112.0': + resolution: {integrity: sha512-E4a8VUFDJPb2mPcc7J4NQQPi1ssHKF7/g4r6KD2+SBVERIaEEd3cGNqR7SG3g82/BLGV2UDoQe/WvZCkt5M/bQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@oxc-minify/binding-linux-s390x-gnu@0.112.0': + resolution: {integrity: sha512-2Hx87sK3y6jBV364Mvv0zyxiITIuy26Ixenv6pK7e+4an3HgNdhAj8nk3aLoLTTSvLik5/MaGhcZGEu9tYV1aA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] - '@types/extend@3.0.4': - resolution: {integrity: sha512-ArMouDUTJEz1SQRpFsT2rIw7DeqICFv5aaVzLSIYMYQSLcwcGOfT3VyglQs/p7K3F7fT4zxr0NWxYZIdifD6dA==} + '@oxc-minify/binding-linux-x64-gnu@0.112.0': + resolution: {integrity: sha512-2MSCnEPLk9ddSouMhJo78Xy2/JbYC80OYzWdR4yWTGSULsgH3d1VXg73DSwFL8vU7Ad9oK10DioBY2ww7sQTEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - '@types/fs-extra@8.1.5': - resolution: {integrity: sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==} + '@oxc-minify/binding-linux-x64-musl@0.112.0': + resolution: {integrity: sha512-HAPfmQKlkVi97/zRonVE9t/kKUG3ni+mOuU1Euw+3s37KwUuOJjmcwXdclVgXKBlTkCGO0FajPwW5dAJeIXCCw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - '@types/glob@7.2.0': - resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + '@oxc-minify/binding-openharmony-arm64@0.112.0': + resolution: {integrity: sha512-bLnMojcPadYzMNpB6IAqMiTOag4etc0zbs8On73JsotO1W5c5/j/ncplpSokpEpNasKRUpHVRXpmq0KRXprNhw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] - '@types/hast@2.3.10': - resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + '@oxc-minify/binding-wasm32-wasi@0.112.0': + resolution: {integrity: sha512-tv7PmHYq/8QBlqMaDjsy51GF5KQkG17Yc/PsgB5OVndU34kwbQuebBIic7UfK9ygzidI8moYq3ztnu3za/rqHw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@oxc-minify/binding-win32-arm64-msvc@0.112.0': + resolution: {integrity: sha512-d+jes2jwRkcBSpcaZC6cL8GBi56Br6uAorn9dfquhWLczWL+hHSvvVrRgT1i5/6dkf5UWx2zdoEsAMiJ11w78A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] - '@types/http-cache-semantics@4.2.0': - resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + '@oxc-minify/binding-win32-ia32-msvc@0.112.0': + resolution: {integrity: sha512-TV1C3qDwj7//jNIi5tnNRhReSUgtaRQKi5KobDE6zVAc5gjeuBA8G2qizS9ziXlf/I0dlelrGmGMMDJmH9ekWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@oxc-minify/binding-win32-x64-msvc@0.112.0': + resolution: {integrity: sha512-LML2Gld6VY8/+7a3VH4k1qngsBXvTkXgbmYgSYwaElqtiQiYaAcXfi0XKOUGe3k3GbBK4juAGixC31CrdFHAQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] - '@types/katex@0.16.8': - resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + '@oxc-parser/binding-android-arm-eabi@0.112.0': + resolution: {integrity: sha512-retxBzJ39Da7Lh/eZTn9+HJgTeDUxZIpuI0urOsmcFsBKXAth3lc1jIvwseQ9qbAI/VrsoFOXiGIzgclARbAHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] - '@types/lodash-es@4.17.12': - resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + '@oxc-parser/binding-android-arm64@0.112.0': + resolution: {integrity: sha512-pRkbBRbuIIsufUWpOJ+JHWfJFNupkidy4sbjfcm37e6xwYrn9LSKMLubPHvNaL1Zf92ZRhGiwaYkEcmaFg2VcA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@types/lodash@4.17.23': - resolution: {integrity: sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==} + '@oxc-parser/binding-darwin-arm64@0.112.0': + resolution: {integrity: sha512-fh6/KQL/cbH5DukT3VkdCqnULLuvVnszVKySD5IgSE0WZb32YZo/cPsPdEv052kk6w3N4agu+NTiMnZjcvhUIg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - '@types/mdast@3.0.15': - resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + '@oxc-parser/binding-darwin-x64@0.112.0': + resolution: {integrity: sha512-vUBOOY1E30vlu/DoTGDoT1UbLlwu5Yv9tqeBabAwRzwNDz8Skho16VKhsBDUiyqddtpsR3//v6vNk38w4c+6IA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@oxc-parser/binding-freebsd-x64@0.112.0': + resolution: {integrity: sha512-hnEtO/9AVnYWzrgnp6L+oPs/6UqlFeteUL6n7magkd2tttgmx1C01hyNNh6nTpZfLzEVJSNJ0S+4NTsK2q2CxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - '@types/mdx@2.0.13': - resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.112.0': + resolution: {integrity: sha512-WxJrUz3pcIc2hp4lvJbvt/sTL33oX9NPvkD3vDDybE6tc0V++rS+hNOJxwXdD2FDIFPkHs/IEn5asEZFVH+VKw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@types/minimatch@6.0.0': - resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} - deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. + '@oxc-parser/binding-linux-arm-musleabihf@0.112.0': + resolution: {integrity: sha512-jj8A8WWySaJQqM9XKAIG8U2Q3qxhFQKrXPWv98d1oC35at+L1h+C+V4M3l8BAKhpHKCu3dYlloaAbHd5q1Hw6A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@oxc-parser/binding-linux-arm64-gnu@0.112.0': + resolution: {integrity: sha512-G2F8H6FcAExVK5vvhpSh61tqWx5QoaXXUnSsj5FyuDiFT/K7AMMVSQVqnZREDc+YxhrjB0vnKjCcuobXK63kIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - '@types/nlcst@2.0.3': - resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + '@oxc-parser/binding-linux-arm64-musl@0.112.0': + resolution: {integrity: sha512-3R0iqjM3xYOZCnwgcxOQXH7hrz64/USDIuLbNTM1kZqQzRqaR4w7SwoWKU934zABo8d0op2oSwOp+CV3hZnM7A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - '@types/node@22.19.2': - resolution: {integrity: sha512-LPM2G3Syo1GLzXLGJAKdqoU35XvrWzGJ21/7sgZTUpbkBaOasTj8tjwn6w+hCkqaa1TfJ/w67rJSwYItlJ2mYw==} + '@oxc-parser/binding-linux-ppc64-gnu@0.112.0': + resolution: {integrity: sha512-lAQf8PQxfgy7h0bmcfSVE3hg3qMueshPYULFsCrHM+8KefGZ9W+ZMvRyU33gLrB4w1O3Fz1orR0hmKMCRxXNrQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] - '@types/node@22.19.8': - resolution: {integrity: sha512-ebO/Yl+EAvVe8DnMfi+iaAyIqYdK0q/q0y0rw82INWEKJOBe6b/P3YWE8NW7oOlF/nXFNrHwhARrN/hdgDkraA==} + '@oxc-parser/binding-linux-riscv64-gnu@0.112.0': + resolution: {integrity: sha512-2QlvQBUhHuAE3ezD4X3CAEKMXdfgInggQ5Bj/7gb5NcYP3GyfLTj7c+mMu+BRwfC9B3AXBNyqHWbqEuuUvZyRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@oxc-parser/binding-linux-riscv64-musl@0.112.0': + resolution: {integrity: sha512-v06iu0osHszgqJ1dLQRb6leWFU1sjG/UQk4MoVBtE6ZPewgfTkby6G9II1SpEAf2onnAuQceVYxQH9iuU3NJqw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] - '@types/parse5@6.0.3': - resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} + '@oxc-parser/binding-linux-s390x-gnu@0.112.0': + resolution: {integrity: sha512-+5HhNHtxsdcd7+ljXFnn9FOoCNXJX3UPgIfIE6vdwS1HqdGNH6eAcVobuqGOp54l8pvcxDQA6F4cPswCgLrQfQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} - peerDependencies: - '@types/react': ^19.2.0 + '@oxc-parser/binding-linux-x64-gnu@0.112.0': + resolution: {integrity: sha512-jKwO7ZLNkjxwg7FoCLw+fJszooL9yXRZsDN0AQ1AQUTWq1l8GH/2e44k68N3fcP19jl8O8jGpqLAZcQTYk6skA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - '@types/react@19.2.11': - resolution: {integrity: sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==} + '@oxc-parser/binding-linux-x64-musl@0.112.0': + resolution: {integrity: sha512-TYqnuKV/p3eOc+N61E0961nA7DC+gaCeJ3+V2LcjJdTwFMdikqWL6uVk1jlrpUCBrozHDATVUKDZYH7r4FQYjQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - '@types/responselike@1.0.0': - resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + '@oxc-parser/binding-openharmony-arm64@0.112.0': + resolution: {integrity: sha512-ZhrVmWFifVEFQX4XPwLoVFDHw9tAWH9p9vHsHFH+5uCKdfVR+jje4WxVo6YrokWCboGckoOzHq5KKMOcPZfkRg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] - '@types/supports-color@8.1.3': - resolution: {integrity: sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==} + '@oxc-parser/binding-wasm32-wasi@0.112.0': + resolution: {integrity: sha512-Gr8X2PUU3hX1g3F5oLWIZB8DhzDmjr5TfOrmn5tlBOo9l8ojPGdKjnIBfObM7X15928vza8QRKW25RTR7jfivg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] - '@types/unist@2.0.11': - resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@oxc-parser/binding-win32-arm64-msvc@0.112.0': + resolution: {integrity: sha512-t5CDLbU70Ea88bGRhvU/dLJTc/Wcrtf2Jp534E8P3cgjAvHDjdKsfDDqBZrhybJ8Jv9v9vW5ngE40EK51BluDA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@oxc-parser/binding-win32-ia32-msvc@0.112.0': + resolution: {integrity: sha512-rZH0JynCCwnhe2HfRoyNOl/Kfd9pudoWxgpC5OZhj7j77pMK0UOAa35hYDfrtSOUk2HLzrikV5dPUOY2DpSBSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] - '@types/urijs@1.19.26': - resolution: {integrity: sha512-wkXrVzX5yoqLnndOwFsieJA7oKM8cNkOKJtf/3vVGSUFkWDKZvFHpIl9Pvqb/T9UsawBBFMTTD8xu7sK5MWuvg==} + '@oxc-parser/binding-win32-x64-msvc@0.112.0': + resolution: {integrity: sha512-oGHluohzmVFAuQrkEnl1OXAxMz2aYmimxUqIgKXpBgbr7PvFv0doELB273sX+5V3fKeggohKg1A2Qq21W9Z9cQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] - '@types/vscode@1.108.1': - resolution: {integrity: sha512-DerV0BbSzt87TbrqmZ7lRDIYaMiqvP8tmJTzW2p49ZBVtGUnGAu2RGQd1Wv4XMzEVUpaHbsemVM5nfuQJj7H6w==} + '@oxc-project/runtime@0.101.0': + resolution: {integrity: sha512-t3qpfVZIqSiLQ5Kqt/MC4Ge/WCOGrrcagAdzTcDaggupjiGxUx4nJF2v6wUCXWSzWHn5Ns7XLv13fCJEwCOERQ==} + engines: {node: ^20.19.0 || >=22.12.0} - '@types/whatwg-mimetype@3.0.2': - resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + '@oxc-project/types@0.101.0': + resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==} - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@oxc-project/types@0.112.0': + resolution: {integrity: sha512-m6RebKHIRsax2iCwVpYW2ErQwa4ywHJrE4sCK3/8JK8ZZAWOKXaRJFl/uP51gaVyyXlaS4+chU1nSCdzYf6QqQ==} - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@oxc-project/types@0.113.0': + resolution: {integrity: sha512-Tp3XmgxwNQ9pEN9vxgJBAqdRamHibi76iowQ38O2I4PMpcvNRQNVsU2n1x1nv9yh0XoTrGFzf7cZSGxmixxrhA==} - '@typescript-eslint/eslint-plugin@8.54.0': - resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.54.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + '@oxc-transform/binding-android-arm-eabi@0.112.0': + resolution: {integrity: sha512-r4LuBaPnOAi0eUOBNi880Fm2tO2omH7N1FRrL6+nyz/AjQ+QPPLtoyZJva0O+sKi1buyN/7IzM5p9m+5ANSDbg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] - '@typescript-eslint/parser@8.54.0': - resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + '@oxc-transform/binding-android-arm64@0.112.0': + resolution: {integrity: sha512-ve46vQcQrY8eGe8990VSlS9gkD+AogJqbtfOkeua+5sQGQTDgeIRRxOm7ktCo19uZc2bEBwXRJITgosd+NRVmQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@typescript-eslint/project-service@8.54.0': - resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' + '@oxc-transform/binding-darwin-arm64@0.112.0': + resolution: {integrity: sha512-ddbmLU3Tr+i7MOynfwAXxUXud3SjJKlv7XNjaq08qiI8Av/QvhXVGc2bMhXkWQSMSBUeTDoiughKjK+Zsb6y/A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - '@typescript-eslint/scope-manager@8.54.0': - resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@oxc-transform/binding-darwin-x64@0.112.0': + resolution: {integrity: sha512-TKvmNw96jQZPqYb4pRrzLFDailNB3YS14KNn+x2hwRbqc6CqY96S9PYwyOpVpYdxfoRjYO9WgX9SoS+62a1DPA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - '@typescript-eslint/tsconfig-utils@8.54.0': - resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' + '@oxc-transform/binding-freebsd-x64@0.112.0': + resolution: {integrity: sha512-YPMkSCDaelO8HHYRMYjm+Q+IfkfIbdtQzwPuasItYkq8UUkNeHNPheNh2JkvQa3c+io3E9ePOgHQ2yihpk7o/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - '@typescript-eslint/type-utils@8.54.0': - resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + '@oxc-transform/binding-linux-arm-gnueabihf@0.112.0': + resolution: {integrity: sha512-nA7kzQGNEpuTRknst/IJ3l8hqmDmEda3aun6jkXgp7gKxESjuHeaNH04mKISxvJ7fIacvP2g/wtTSnm4u5jL8Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@typescript-eslint/types@8.54.0': - resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@oxc-transform/binding-linux-arm-musleabihf@0.112.0': + resolution: {integrity: sha512-w8GuLmckKlGc3YujaZKhtbFxziCcosvM2l9GnQjCb/yENWLGDiyQOy0BTAgPGdJwpYTiOeJblEXSuXYvlE1Ong==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@typescript-eslint/typescript-estree@8.54.0': - resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' + '@oxc-transform/binding-linux-arm64-gnu@0.112.0': + resolution: {integrity: sha512-9LwwGnJ8+WT0rXcrI8M0RJtDNt91eMqcDPPEvJxhRFHIMcHTy5D5xT+fOl3Us0yMqKo3HUWkbfUYqAp4GoZ3Jw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - '@typescript-eslint/utils@8.54.0': - resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + '@oxc-transform/binding-linux-arm64-musl@0.112.0': + resolution: {integrity: sha512-Lg6VOuSd3oXv7J0eGywgqh/086h+qQzIBOD+47pYKMTTJcbDe+f3h/RgGoMKJE5HhiwT5sH1aGEJfIfaYUiVSw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - '@typescript-eslint/visitor-keys@8.54.0': - resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@oxc-transform/binding-linux-ppc64-gnu@0.112.0': + resolution: {integrity: sha512-PXzmj82o1moA4IGphYImTRgc2youTi4VRfyFX3CHwLjxPcQ5JtcsgbDt4QUdOzXZ+zC07s5jf2ZzhRapEOlj2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] - '@typescript/vfs@1.6.2': - resolution: {integrity: sha512-hoBwJwcbKHmvd2QVebiytN1aELvpk9B74B4L1mFm/XT1Q/VOYAWl2vQ9AWRFtQq8zmz6enTpfTV8WRc4ATjW/g==} - peerDependencies: - typescript: '*' + '@oxc-transform/binding-linux-riscv64-gnu@0.112.0': + resolution: {integrity: sha512-vhJsMsVH/6xwa3bt1LGts33FXUkGjaEGDwsRyp4lIfOjSfQVWMtCmWMFNaA0dW9FVWdD2Gt2fSFBSZ+azDxlpg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] - '@typespec/ts-http-runtime@0.3.2': - resolution: {integrity: sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==} - engines: {node: '>=20.0.0'} + '@oxc-transform/binding-linux-riscv64-musl@0.112.0': + resolution: {integrity: sha512-cXWFb7z+2IjFUEcXtRwluq9oEG5qnyFCjiu3SWrgYNcWwPdHusv3I/7K5/CTbbi4StoZ5txbi7/iSfDHNyWuRw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@oxc-transform/binding-linux-s390x-gnu@0.112.0': + resolution: {integrity: sha512-eEFu4SRqJTJ20/88KRWmp+jpHKAw0Y1DsnSgpEeXyBIIcsOaLIUMU/TfYWUmqRbvbMV9rmOmI3kp5xWYUq6kSQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] + '@oxc-transform/binding-linux-x64-gnu@0.112.0': + resolution: {integrity: sha512-ST1MDT+TlOyZ1c5btrGinRSUW2Jf4Pa+0gdKwsyjDSOC3dxy2ZNkN3mosTf4ywc3J+mxfYKqtjs7zSwHz03ILA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + '@oxc-transform/binding-linux-x64-musl@0.112.0': + resolution: {integrity: sha512-ISQoA3pD4cyTGpf9sXXeerH6pL2L6EIpdy6oAy2ttkswyVFDyQNVOVIGIdLZDgbpmqGljxZnWqt/J/N68pQaig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@oxc-transform/binding-openharmony-arm64@0.112.0': + resolution: {integrity: sha512-UOGVrGIv7yLJovyEXEyUTADuLq98vd/cbMHFLJweRXD+11I8Tn4jASi4WzdsN8C3BVYGRHrXH2NlSBmhz33a4g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-transform/binding-wasm32-wasi@0.112.0': + resolution: {integrity: sha512-XIX7Gpq9koAvzBVHDlVFHM79r5uOVK6kTEsdsN4qaajpjkgtv4tdsAOKIYK6l7fUbsbE6xS+6w1+yRFrDeC1kg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-transform/binding-win32-arm64-msvc@0.112.0': + resolution: {integrity: sha512-EgXef9kOne9BNsbYBbuRqxk2hteT0xsAGcx/VbtCBMJYNj8fANFhT271DUSOgfa4DAgrQQmsyt/Kr1aV9mpU9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-transform/binding-win32-ia32-msvc@0.112.0': + resolution: {integrity: sha512-6QaB0qjNaou2YR+blncHdw7j0e26IOwOIjLbhVGDeuf9+4rjJeiqRXJ2hOtCcS4zblnao/MjdgQuZ3fM0nl+Kw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-transform/binding-win32-x64-msvc@0.112.0': + resolution: {integrity: sha512-FRKYlY959QeqRPx9kXs0HjU2xuXPT1cdF+vvA200D9uAX/KLcC34MwRqUKTYml4kCc2Vf/P2pBR9cQuBm3zECQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} - cpu: [ppc64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} - cpu: [riscv64] - os: [linux] - - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} - cpu: [s390x] - os: [linux] - - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] + '@parcel/watcher-wasm@2.5.6': + resolution: {integrity: sha512-byAiBZ1t3tXQvc8dMD/eoyE7lTXYorhn+6uVW5AC+JGI1KtJC/LvDche5cfUE+qiefH+Ybq0bUCJU0aB1cSHUA==} + engines: {node: '>= 10.0.0'} + bundledDependencies: + - napi-wasm - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} cpu: [ia32] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] - '@verdaccio/auth@8.0.0-next-8.29': - resolution: {integrity: sha512-lEIqneZ7LYYkF07/P9cJhOYVZTIIARGRVE66j666VR58T/fY/pC4hxEfuyqlfd3BhS3hM65aIrPZu+s03hyg+w==} - engines: {node: '>=18'} + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} - '@verdaccio/config@8.0.0-next-8.29': - resolution: {integrity: sha512-7kEZ6tv3NsJFPcKQrxELMkvJFI9Hmy1s8IPjuXjz9gobDV3NyF9VhPsh6l18Tm+nsqXb6ZTWiRup9V8Lkg0p0g==} - engines: {node: '>=18'} + '@peculiar/asn1-cms@2.6.1': + resolution: {integrity: sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==} - '@verdaccio/core@8.0.0-next-8.21': - resolution: {integrity: sha512-n3Y8cqf84cwXxUUdTTfEJc8fV55PONPKijCt2YaC0jilb5qp1ieB3d4brqTOdCdXuwkmnG2uLCiGpUd/RuSW0Q==} - engines: {node: '>=18'} + '@peculiar/asn1-csr@2.6.1': + resolution: {integrity: sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==} - '@verdaccio/core@8.0.0-next-8.29': - resolution: {integrity: sha512-ztsNbnHMGqpOJlC3x/Jz7+0Xzrul+UIQQAFsTFHO3pET8nyZWkh/1TH50olz0pZ/OS87O/+7mk04TK9hHD/eFQ==} - engines: {node: '>=18'} + '@peculiar/asn1-ecc@2.6.1': + resolution: {integrity: sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==} - '@verdaccio/file-locking@10.3.1': - resolution: {integrity: sha512-oqYLfv3Yg3mAgw9qhASBpjD50osj2AX4IwbkUtyuhhKGyoFU9eZdrbeW6tpnqUnj6yBMtAPm2eGD4BwQuX400g==} - engines: {node: '>=12'} + '@peculiar/asn1-pfx@2.6.1': + resolution: {integrity: sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==} - '@verdaccio/file-locking@13.0.0-next-8.6': - resolution: {integrity: sha512-F6xQWvsZnEyGjugrYfe+D/ChSVudXmBFWi8xuTIX6PAdp7dk9x9biOGQFW8O3GSAK8UhJ6WlRisQKJeYRa6vWQ==} - engines: {node: '>=18'} + '@peculiar/asn1-pkcs8@2.6.1': + resolution: {integrity: sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==} - '@verdaccio/hooks@8.0.0-next-8.29': - resolution: {integrity: sha512-KRuTN6iYg9ntFXmrH+fY+dNCFpNBMcEwOVLOJXk/fA3I3ki188FpRZz9rKToyj1XYZzPDqGUWv82ekswX5wrYw==} - engines: {node: '>=18'} + '@peculiar/asn1-pkcs9@2.6.1': + resolution: {integrity: sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==} - '@verdaccio/loaders@8.0.0-next-8.19': - resolution: {integrity: sha512-+mQuEZNLRZ4EEjzfROHrVeZXVHNFhQTpI98KCpcbU1NEC7ZAl5m7OBD2XPVtvNTia2ZT83q4H0JPi/bAomnIRA==} - engines: {node: '>=18'} + '@peculiar/asn1-rsa@2.6.1': + resolution: {integrity: sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==} - '@verdaccio/local-storage-legacy@11.1.1': - resolution: {integrity: sha512-P6ahH2W6/KqfJFKP+Eid7P134FHDLNvHa+i8KVgRVBeo2/IXb6FEANpM1mCVNvPANu0LCAmNJBOXweoUKViaoA==} - engines: {node: '>=18'} + '@peculiar/asn1-schema@2.6.0': + resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} - '@verdaccio/logger-commons@8.0.0-next-8.29': - resolution: {integrity: sha512-CVeLv+U0cL9wtNJVwtzjj7wtUFYxMDmynWoXtepP+AthVoNj6G6rU2P2tGLX/uqH40EwqaHJy5Vo0uZ3ex2qhQ==} - engines: {node: '>=18'} + '@peculiar/asn1-x509-attr@2.6.1': + resolution: {integrity: sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==} - '@verdaccio/logger-prettify@8.0.0-next-8.4': - resolution: {integrity: sha512-gjI/JW29fyalutn/X1PQ0iNuGvzeVWKXRmnLa7gXVKhdi4p37l/j7YZ7n44XVbbiLIKAK0pbavEg9Yr66QrYaA==} - engines: {node: '>=18'} + '@peculiar/asn1-x509@2.6.1': + resolution: {integrity: sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==} - '@verdaccio/logger@8.0.0-next-8.29': - resolution: {integrity: sha512-AF6hBAkgsRjDFGLjFWO9hzUWM47Jt15v90I6Wk0TotzsrWxgBYbslfJyTgwmTpGjhPe7al2dnFwT7hxKa6fr/w==} - engines: {node: '>=18'} + '@peculiar/x509@1.14.3': + resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} + engines: {node: '>=20.0.0'} - '@verdaccio/middleware@8.0.0-next-8.29': - resolution: {integrity: sha512-ANsQ8qjyNslH6BfGZnNkBvK1acTlnFgedXen6BnbN9nF+AWzHUea6knh529J5Clm3zrWggbRnGCrp1SSlbOqSA==} - engines: {node: '>=18'} + '@pinojs/redact@0.4.0': + resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} - '@verdaccio/search-indexer@8.0.0-next-8.5': - resolution: {integrity: sha512-0GC2tJKstbPg/W2PZl2yE+hoAxffD2ZWilEnEYSEo2e9UQpNIy2zg7KE/uMUq2P72Vf5EVfVzb8jdaH4KV4QeA==} - engines: {node: '>=18'} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} - '@verdaccio/signature@8.0.0-next-8.21': - resolution: {integrity: sha512-5TuGPRT4c5B3k6svxJ6Q5l31UBZTODo3iAJxmuAAC0iZBLNnivdvJlqUVdpZtYfrhwvuP5vuo7lucHQk6DsSmw==} + '@playwright/test@1.58.1': + resolution: {integrity: sha512-6LdVIUERWxQMmUSSQi0I53GgCBYgM2RpGngCPY7hSeju+VrKjq3lvs7HpJoPbDiY5QM5EYRtRX5fvrinnMAz3w==} engines: {node: '>=18'} + hasBin: true - '@verdaccio/streams@10.2.1': - resolution: {integrity: sha512-OojIG/f7UYKxC4dYX8x5ax8QhRx1b8OYUAMz82rUottCuzrssX/4nn5QE7Ank0DUSX3C9l/HPthc4d9uKRJqJQ==} - engines: {node: '>=12', npm: '>=5'} + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} - '@verdaccio/tarball@13.0.0-next-8.29': - resolution: {integrity: sha512-4hTQMXYF1olwwydaVfb6ab1TTImM42rAxLmw3VnJUI5ttbmfB9h095/TYsCssy5vqGQMp3l8YW/JxVTPcVtGYA==} - engines: {node: '>=18'} + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} - '@verdaccio/ui-theme@8.0.0-next-8.29': - resolution: {integrity: sha512-kSg69so1LHOL2SA1qLJikFxkx8FEOFQJV+Nde0lN3XMkp0RST8DgLx/hiVbgYzPz54S8LuvYR/DQAulyRulMcg==} + '@pnpm/npm-conf@3.0.2': + resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} + engines: {node: '>=12'} - '@verdaccio/url@13.0.0-next-8.29': - resolution: {integrity: sha512-ucJ6MhLfY0g8uU0zjcJypSkCa1mXSLmrqdiILyj16Lo0y4w/gEvddMrfab8QUmgvvuzbCgSqCZHJmbZn7DFxQg==} - engines: {node: '>=18'} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@verdaccio/utils@8.1.0-next-8.29': - resolution: {integrity: sha512-EgyazlL0VejvZqWZ6KL3ig27Yl8RXcwhz1hayuqeAIxaqbsnmSmogL2zKXgGnm9y/A6QkPfZH1BcQoUh1STvtQ==} - engines: {node: '>=18'} + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@vitejs/plugin-react@5.1.3': - resolution: {integrity: sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} - '@vitejs/plugin-vue@6.0.2': - resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - vue: 3.5.25 + '@poppinss/dumper@0.7.0': + resolution: {integrity: sha512-0UTYalzk2t6S4rA2uHOz5bSSW2CHdv4vggJI6Alg90yvl0UgXs6XSXpH96OH+bRkX4J/06djv29pqXJ0lq5Kag==} - '@vitest/coverage-v8@3.2.4': - resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} - peerDependencies: - '@vitest/browser': 3.2.4 - vitest: 3.2.4 - peerDependenciesMeta: - '@vitest/browser': - optional: true + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@puppeteer/browsers@2.3.0': + resolution: {integrity: sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==} + engines: {node: '>=18'} + hasBin: true - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - msw: + '@types/react': optional: true - vite: + '@types/react-dom': optional: true - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - - '@volar/language-core@2.4.28': - resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} - - '@volar/source-map@2.4.28': - resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} - - '@volar/typescript@2.4.28': - resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - - '@vscode/vsce-sign-alpine-arm64@2.0.6': - resolution: {integrity: sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==} - cpu: [arm64] - os: [alpine] - - '@vscode/vsce-sign-alpine-x64@2.0.6': - resolution: {integrity: sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==} - cpu: [x64] - os: [alpine] - - '@vscode/vsce-sign-darwin-arm64@2.0.6': - resolution: {integrity: sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==} - cpu: [arm64] - os: [darwin] - - '@vscode/vsce-sign-darwin-x64@2.0.6': - resolution: {integrity: sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw==} - cpu: [x64] - os: [darwin] + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vscode/vsce-sign-linux-arm64@2.0.6': - resolution: {integrity: sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==} - cpu: [arm64] - os: [linux] + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vscode/vsce-sign-linux-arm@2.0.6': - resolution: {integrity: sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==} - cpu: [arm] - os: [linux] + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@vscode/vsce-sign-linux-x64@2.0.6': - resolution: {integrity: sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==} - cpu: [x64] - os: [linux] + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vscode/vsce-sign-win32-arm64@2.0.6': - resolution: {integrity: sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==} - cpu: [arm64] - os: [win32] + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@vscode/vsce-sign-win32-x64@2.0.6': - resolution: {integrity: sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==} - cpu: [x64] - os: [win32] + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vscode/vsce-sign@2.0.9': - resolution: {integrity: sha512-8IvaRvtFyzUnGGl3f5+1Cnor3LqaUWvhaUjAYO8Y39OUYlOf3cRd+dowuQYLpZcP3uwSG+mURwjEBOSq4SOJ0g==} + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@vscode/vsce@2.32.0': - resolution: {integrity: sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==} - engines: {node: '>= 16'} - hasBin: true + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@vue/compiler-core@3.5.25': - resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@vue/compiler-dom@3.5.25': - resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@vue/compiler-sfc@3.5.25': - resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@vue/compiler-ssr@3.5.25': - resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vue/compiler-vue2@2.7.16': - resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vue/devtools-api@6.6.4': - resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vue/language-core@2.2.0': - resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} peerDependencies: - typescript: '*' + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - typescript: + '@types/react': optional: true - '@vue/reactivity@3.5.25': - resolution: {integrity: sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==} + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vue/runtime-core@3.5.25': - resolution: {integrity: sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==} + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vue/runtime-dom@3.5.25': - resolution: {integrity: sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==} + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vue/server-renderer@3.5.25': - resolution: {integrity: sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==} + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} peerDependencies: - vue: 3.5.25 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@vue/shared@3.5.25': - resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - '@vue/test-utils@2.4.6': - resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + '@rolldown/binding-android-arm64@1.0.0-beta.53': + resolution: {integrity: sha512-Ok9V8o7o6YfSdTTYA/uHH30r3YtOxLD6G3wih/U9DO0ucBBFq8WPt/DslU53OgfteLRHITZny9N/qCUxMf9kjQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - '@zeit/schemas@2.36.0': - resolution: {integrity: sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==} + '@rolldown/binding-android-arm64@1.0.0-rc.4': + resolution: {integrity: sha512-vRq9f4NzvbdZavhQbjkJBx7rRebDKYR9zHfO/Wg486+I7bSecdUapzCm5cyXoK+LHokTxgSq7A5baAXUZkIz0w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true + '@rolldown/binding-darwin-arm64@1.0.0-beta.53': + resolution: {integrity: sha512-yIsKqMz0CtRnVa6x3Pa+mzTihr4Ty+Z6HfPbZ7RVbk1Uxnco4+CUn7Qbm/5SBol1JD/7nvY8rphAgyAi7Lj6Vg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - abbrev@2.0.0: - resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@rolldown/binding-darwin-arm64@1.0.0-rc.4': + resolution: {integrity: sha512-kFgEvkWLqt3YCgKB5re9RlIrx9bRsvyVUnaTakEpOPuLGzLpLapYxE9BufJNvPg8GjT6mB1alN4yN1NjzoeM8Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} + '@rolldown/binding-darwin-x64@1.0.0-beta.53': + resolution: {integrity: sha512-GTXe+mxsCGUnJOFMhfGWmefP7Q9TpYUseHvhAhr21nCTgdS8jPsvirb0tJwM3lN0/u/cg7bpFNa16fQrjKrCjQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} + '@rolldown/binding-darwin-x64@1.0.0-rc.4': + resolution: {integrity: sha512-JXmaOJGsL/+rsmMfutcDjxWM2fTaVgCHGoXS7nE8Z3c9NAYjGqHvXrAhMUZvMpHS/k7Mg+X7n/MVKb7NYWKKww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} + '@rolldown/binding-freebsd-x64@1.0.0-beta.53': + resolution: {integrity: sha512-9Tmp7bBvKqyDkMcL4e089pH3RsjD3SUungjmqWtyhNOxoQMh0fSmINTyYV8KXtE+JkxYMPWvnEt+/mfpVCkk8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@rolldown/binding-freebsd-x64@1.0.0-rc.4': + resolution: {integrity: sha512-ep3Catd6sPnHTM0P4hNEvIv5arnDvk01PfyJIJ+J3wVCG1eEaPo09tvFqdtcaTrkwQy0VWR24uz+cb4IsK53Qw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] - acorn@8.11.2: - resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} - engines: {node: '>=0.4.0'} - hasBin: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': + resolution: {integrity: sha512-a1y5fiB0iovuzdbjUxa7+Zcvgv+mTmlGGC4XydVIsyl48eoxgaYkA3l9079hyTyhECsPq+mbr0gVQsFU11OJAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.4': + resolution: {integrity: sha512-LwA5ayKIpnsgXJEwWc3h8wPiS33NMIHd9BhsV92T8VetVAbGe2qXlJwNVDGHN5cOQ22R9uYvbrQir2AB+ntT2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - address@1.2.2: - resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} - engines: {node: '>= 10.0.0'} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': + resolution: {integrity: sha512-bpIGX+ov9PhJYV+wHNXl9rzq4F0QvILiURn0y0oepbQx+7stmQsKA0DhPGwmhfvF856wq+gbM8L92SAa/CBcLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - adm-zip@0.5.16: - resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==} - engines: {node: '>=12.0'} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.4': + resolution: {integrity: sha512-AC1WsGdlV1MtGay/OQ4J9T7GRadVnpYRzTcygV1hKnypbYN20Yh4t6O1Sa2qRBMqv1etulUknqXjc3CTIsBu6A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': + resolution: {integrity: sha512-bGe5EBB8FVjHBR1mOLOPEFg1Lp3//7geqWkU5NIhxe+yH0W8FVrQ6WRYOap4SUTKdklD/dC4qPLREkMMQ855FA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.4': + resolution: {integrity: sha512-lU+6rgXXViO61B4EudxtVMXSOfiZONR29Sys5VGSetUY7X8mg9FCKIIjcPPj8xNDeYzKl+H8F/qSKOBVFJChCQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': + resolution: {integrity: sha512-qL+63WKVQs1CMvFedlPt0U9PiEKJOAL/bsHMKUDS6Vp2Q+YAv/QLPu8rcvkfIMvQ0FPU2WL0aX4eWwF6e/GAnA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - aggregate-error@4.0.1: - resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} - engines: {node: '>=12'} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.4': + resolution: {integrity: sha512-DZaN1f0PGp/bSvKhtw50pPsnln4T13ycDq1FrDWRiHmWt1JeW+UtYg9touPFf8yt993p8tS2QjybpzKNTxYEwg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - aggregate-error@5.0.0: - resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==} - engines: {node: '>=18'} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': + resolution: {integrity: sha512-VGl9JIGjoJh3H8Mb+7xnVqODajBmrdOOb9lxWXdcmxyI+zjB2sux69br0hZJDTyLJfvBoYm439zPACYbCjGRmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] - ajv-draft-04@1.0.0: - resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.4': + resolution: {integrity: sha512-RnGxwZLN7fhMMAItnD6dZ7lvy+TI7ba+2V54UF4dhaWa/p8I/ys1E73KO6HmPmgz92ZkfD8TXS1IMV8+uhbR9g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': + resolution: {integrity: sha512-B4iIserJXuSnNzA5xBLFUIjTfhNy7d9sq4FUMQY3GhQWGVhS2RWWzzDnkSU6MUt7/aHUrep0CdQfXUJI9D3W7A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.4': + resolution: {integrity: sha512-6lcI79+X8klGiGd8yHuTgQRjuuJYNggmEml+RsyN596P23l/zf9FVmJ7K0KVKkFAeYEdg0iMUKyIxiV5vebDNQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': + resolution: {integrity: sha512-BUjAEgpABEJXilGq/BPh7jeU3WAJ5o15c1ZEgHaDWSz3LB881LQZnbNJHmUiM4d1JQWMYYyR1Y490IBHi2FPJg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.4': + resolution: {integrity: sha512-wz7ohsKCAIWy91blZ/1FlpPdqrsm1xpcEOQVveWoL6+aSPKL4VUcoYmmzuLTssyZxRpEwzuIxL/GDsvpjaBtOw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': + resolution: {integrity: sha512-s27uU7tpCWSjHBnxyVXHt3rMrQdJq5MHNv3BzsewCIroIw3DJFjMH1dzCPPMUFxnh1r52Nf9IJ/eWp6LDoyGcw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.4': + resolution: {integrity: sha512-cfiMrfuWCIgsFmcVG0IPuO6qTRHvF7NuG3wngX1RZzc6dU8FuBFb+J3MIR5WrdTNozlumfgL4cvz+R4ozBCvsQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': + resolution: {integrity: sha512-cjWL/USPJ1g0en2htb4ssMjIycc36RvdQAx1WlXnS6DpULswiUTVXPDesTifSKYSyvx24E0YqQkEm0K/M2Z/AA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.4': + resolution: {integrity: sha512-p6UeR9y7ht82AH57qwGuFYn69S6CZ7LLKdCKy/8T3zS9VTrJei2/CGsTUV45Da4Z9Rbhc7G4gyWQ/Ioamqn09g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rolldown/pluginutils@1.0.0-beta.50': + resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==} + + '@rolldown/pluginutils@1.0.0-beta.53': + resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + + '@rolldown/pluginutils@1.0.0-rc.2': + resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==} + + '@rolldown/pluginutils@1.0.0-rc.4': + resolution: {integrity: sha512-1BrrmTu0TWfOP1riA8uakjFc9bpIUGzVKETsOtzY39pPga8zELGDl8eu1Dx7/gjM5CAz14UknsUMpBO8L+YntQ==} + + '@rollup/plugin-alias@6.0.0': + resolution: {integrity: sha512-tPCzJOtS7uuVZd+xPhoy5W4vThe6KWXNmsFCNktaAh5RTqcLiSfT4huPQIXkgJ6YCOjJHvecOAzQxLFhPxKr+g==} + engines: {node: '>=20.19.0'} peerDependencies: - ajv: ^8.5.0 + rollup: '>=4.0.0' peerDependenciesMeta: - ajv: + rollup: optional: true - ajv-errors@3.0.0: - resolution: {integrity: sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==} + '@rollup/plugin-commonjs@29.0.2': + resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} peerDependencies: - ajv: ^8.0.1 + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + '@rollup/plugin-inject@5.0.5': + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} peerDependencies: - ajv: ^8.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: - ajv: + rollup: optional: true - ajv-formats@3.0.1: - resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} peerDependencies: - ajv: ^8.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: - ajv: + rollup: optional: true - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + '@rollup/plugin-node-resolve@16.0.3': + resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - ajv@8.13.0: - resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==} + '@rollup/plugin-replace@6.0.3': + resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + '@rollup/plugin-terser@0.4.4': + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - alien-signals@0.4.14: - resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - ansi-align@3.0.1: - resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + '@rollup/rollup-android-arm-eabi@4.57.1': + resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} + cpu: [arm] + os: [android] - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + '@rollup/rollup-android-arm64@4.57.1': + resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} + cpu: [arm64] + os: [android] - ansi-escapes@7.3.0: - resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} - engines: {node: '>=18'} + '@rollup/rollup-darwin-arm64@4.57.1': + resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} + cpu: [arm64] + os: [darwin] - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + '@rollup/rollup-darwin-x64@4.57.1': + resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} + cpu: [x64] + os: [darwin] - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} + '@rollup/rollup-freebsd-arm64@4.57.1': + resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} + cpu: [arm64] + os: [freebsd] - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + '@rollup/rollup-freebsd-x64@4.57.1': + resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} + cpu: [x64] + os: [freebsd] - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} + cpu: [arm] + os: [linux] - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} + cpu: [arm] + os: [linux] - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} + '@rollup/rollup-linux-arm64-gnu@4.57.1': + resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} + cpu: [arm64] + os: [linux] - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + '@rollup/rollup-linux-arm64-musl@4.57.1': + resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} + cpu: [arm64] + os: [linux] - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + '@rollup/rollup-linux-loong64-gnu@4.57.1': + resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} + cpu: [loong64] + os: [linux] - apache-md5@1.1.8: - resolution: {integrity: sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==} - engines: {node: '>=8'} + '@rollup/rollup-linux-loong64-musl@4.57.1': + resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} + cpu: [loong64] + os: [linux] - arch@2.2.0: - resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} + cpu: [ppc64] + os: [linux] - are-docs-informative@0.0.2: - resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} - engines: {node: '>=14'} + '@rollup/rollup-linux-ppc64-musl@4.57.1': + resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} + cpu: [ppc64] + os: [linux] - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} + cpu: [riscv64] + os: [linux] - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + '@rollup/rollup-linux-riscv64-musl@4.57.1': + resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} + cpu: [riscv64] + os: [linux] - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + '@rollup/rollup-linux-s390x-gnu@4.57.1': + resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} + cpu: [s390x] + os: [linux] - argv-formatter@1.0.0: - resolution: {integrity: sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==} + '@rollup/rollup-linux-x64-gnu@4.57.1': + resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} + cpu: [x64] + os: [linux] - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} + '@rollup/rollup-linux-x64-musl@4.57.1': + resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} + cpu: [x64] + os: [linux] - aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + '@rollup/rollup-openbsd-x64@4.57.1': + resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} + cpu: [x64] + os: [openbsd] - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} + '@rollup/rollup-openharmony-arm64@4.57.1': + resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} + cpu: [arm64] + os: [openharmony] - arkregex@0.0.3: - resolution: {integrity: sha512-bU21QJOJEFJK+BPNgv+5bVXkvRxyAvgnon75D92newgHxkBJTgiFwQxusyViYyJkETsddPlHyspshDQcCzmkNg==} + '@rollup/rollup-win32-arm64-msvc@4.57.1': + resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} + cpu: [arm64] + os: [win32] - arkregex@0.0.5: - resolution: {integrity: sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==} + '@rollup/rollup-win32-ia32-msvc@4.57.1': + resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} + cpu: [ia32] + os: [win32] - arktype@2.1.27: - resolution: {integrity: sha512-enctOHxI4SULBv/TDtCVi5M8oLd4J5SVlPUblXDzSsOYQNMzmVbUosGBnJuZDKmFlN5Ie0/QVEuTE+Z5X1UhsQ==} + '@rollup/rollup-win32-x64-gnu@4.57.1': + resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} + cpu: [x64] + os: [win32] - arktype@2.1.29: - resolution: {integrity: sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ==} + '@rollup/rollup-win32-x64-msvc@4.57.1': + resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} + cpu: [x64] + os: [win32] - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + '@rushstack/node-core-library@5.19.1': + resolution: {integrity: sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true - array-ify@1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + '@rushstack/problem-matcher@0.1.1': + resolution: {integrity: sha512-Fm5XtS7+G8HLcJHCWpES5VmeMyjAKaWeyZU5qPzZC+22mPlJzAsOxymHiWIfuirtPckX3aptWws+K2d0BzniJA==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} + '@rushstack/rig-package@0.6.0': + resolution: {integrity: sha512-ZQmfzsLE2+Y91GF15c65L/slMRVhF6Hycq04D4TwtdGaUAbIXXg9c5pKA5KFU7M4QMaihoobp9JJYpYcaY3zOw==} - array-iterate@2.0.1: - resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + '@rushstack/terminal@0.21.0': + resolution: {integrity: sha512-cLaI4HwCNYmknM5ns4G+drqdEB6q3dCPV423+d3TZeBusYSSm09+nR7CnhzJMjJqeRcdMAaLnrA4M/3xDz4R3w==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} + '@rushstack/ts-command-line@5.2.0': + resolution: {integrity: sha512-lYxCX0nDdkDtCkVpvF0m25ymf66SaMWuppbD6b7MdkIzvGXKBXNIVZlwBH/C0YfkanrupnICWf2n4z3AKSfaHw==} - array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} + '@schematics/angular@21.2.1': + resolution: {integrity: sha512-DjrHRMoILhbZ6tc7aNZWuHA1wCm1iU/JN1TxAwNEyIBgyU3Fx8Z5baK4w0TCpOIPt0RLWVgP2L7kka9aXWCUFA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} + '@semantic-release/changelog@6.0.3': + resolution: {integrity: sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==} + engines: {node: '>=14.17'} + peerDependencies: + semantic-release: '>=18.0.0' - array.prototype.tosorted@1.1.4: - resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} - engines: {node: '>= 0.4'} + '@semantic-release/commit-analyzer@13.0.1': + resolution: {integrity: sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} + '@semantic-release/error@3.0.0': + resolution: {integrity: sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==} + engines: {node: '>=14.17'} - asn1.js@4.10.1: - resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} + '@semantic-release/error@4.0.0': + resolution: {integrity: sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==} + engines: {node: '>=18'} - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + '@semantic-release/exec@6.0.3': + resolution: {integrity: sha512-bxAq8vLOw76aV89vxxICecEa8jfaWwYITw6X74zzlO0mc/Bgieqx9kBRz9z96pHectiTAtsCwsQcUyLYWnp3VQ==} + engines: {node: '>=14.17'} + peerDependencies: + semantic-release: '>=18.0.0' - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} + '@semantic-release/git@10.0.1': + resolution: {integrity: sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==} + engines: {node: '>=14.17'} + peerDependencies: + semantic-release: '>=18.0.0' - assert@2.1.0: - resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + '@semantic-release/github@11.0.6': + resolution: {integrity: sha512-ctDzdSMrT3H+pwKBPdyCPty6Y47X8dSrjd3aPZ5KKIKKWTwZBE9De8GtsH3TyAlw3Uyo2stegMx6rJMXKpJwJA==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=24.1.0' - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + '@semantic-release/npm@12.0.2': + resolution: {integrity: sha512-+M9/Lb35IgnlUO6OSJ40Ie+hUsZLuph2fqXC/qrKn0fMvUU/jiCjpoL6zEm69vzcmaZJ8yNKtMBEKHWN49WBbQ==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' - ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} + '@semantic-release/release-notes-generator@14.1.0': + resolution: {integrity: sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' - ast-v8-to-istanbul@0.3.11: - resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==} + '@shikijs/core@3.22.0': + resolution: {integrity: sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==} - astring@1.9.0: - resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} - hasBin: true + '@shikijs/engine-javascript@3.22.0': + resolution: {integrity: sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==} - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} + '@shikijs/engine-oniguruma@3.22.0': + resolution: {integrity: sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==} - async-lock@1.4.1: - resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} + '@shikijs/langs@3.22.0': + resolution: {integrity: sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==} - async-validator@4.2.5: - resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + '@shikijs/themes@3.22.0': + resolution: {integrity: sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==} - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + '@shikijs/transformers@3.22.0': + resolution: {integrity: sha512-E7eRV7mwDBjueLF6852n2oYeJYxBq3NSsDk+uyruYAXONv4U8holGmIrT+mPRJQ1J1SNOH6L8G19KRzmBawrFw==} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + '@shikijs/twoslash@3.22.0': + resolution: {integrity: sha512-GO27UPN+kegOMQvC+4XcLt0Mttyg+n16XKjmoKjdaNZoW+sOJV7FLdv2QKauqUDws6nE3EQPD+TFHEdyyoUBDw==} + peerDependencies: + typescript: '>=5.5.0' - atomic-sleep@1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} + '@shikijs/types@3.22.0': + resolution: {integrity: sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==} - auto-bind@5.0.1: - resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + '@sigstore/bundle@4.0.0': + resolution: {integrity: sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==} + engines: {node: ^20.17.0 || >=22.9.0} - avsc@5.7.9: - resolution: {integrity: sha512-yOA4wFeI7ET3v32Di/sUybQ+ttP20JHSW3mxLuNGeO0uD6PPcvLrIQXSvy/rhJOWU5JrYh7U4OHplWMmtAtjMg==} - engines: {node: '>=0.11'} + '@sigstore/core@3.1.0': + resolution: {integrity: sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==} + engines: {node: ^20.17.0 || >=22.9.0} - aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + '@sigstore/protobuf-specs@0.5.0': + resolution: {integrity: sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==} + engines: {node: ^18.17.0 || >=20.5.0} - aws4@1.13.2: - resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + '@sigstore/sign@4.1.0': + resolution: {integrity: sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==} + engines: {node: ^20.17.0 || >=22.9.0} - axios@1.10.0: - resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + '@sigstore/tuf@4.0.1': + resolution: {integrity: sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==} + engines: {node: ^20.17.0 || >=22.9.0} - axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + '@sigstore/verify@3.1.0': + resolution: {integrity: sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==} + engines: {node: ^20.17.0 || >=22.9.0} - azure-devops-node-api@12.5.0: - resolution: {integrity: sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} - b4a@1.7.3: - resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} - peerDependencies: - react-native-b4a: '*' - peerDependenciesMeta: - react-native-b4a: - optional: true + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} - bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} + engines: {node: '>=18'} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} - bare-events@2.8.2: - resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} - peerDependencies: - bare-abort-controller: '*' - peerDependenciesMeta: - bare-abort-controller: - optional: true + '@sindresorhus/slugify@2.2.0': + resolution: {integrity: sha512-9Vybc/qX8Kj6pxJaapjkFbiUJPk7MAkCh/GFCxIBnnsuYCFPIXKvnLidG8xlepht3i24L5XemUmGtrJ3UWrl6w==} + engines: {node: '>=12'} - bare-fs@4.5.3: - resolution: {integrity: sha512-9+kwVx8QYvt3hPWnmb19tPnh38c6Nihz8Lx3t0g9+4GoIf3/fTgYwM4Z6NxgI+B9elLQA7mLE9PpqcWtOMRDiQ==} - engines: {bare: '>=1.16.0'} - peerDependencies: - bare-buffer: '*' - peerDependenciesMeta: - bare-buffer: - optional: true + '@sindresorhus/transliterate@1.6.0': + resolution: {integrity: sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==} + engines: {node: '>=12'} - bare-os@3.6.2: - resolution: {integrity: sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==} - engines: {bare: '>=1.14.0'} + '@smithy/abort-controller@4.2.8': + resolution: {integrity: sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==} + engines: {node: '>=18.0.0'} - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + '@smithy/chunked-blob-reader-native@4.2.1': + resolution: {integrity: sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==} + engines: {node: '>=18.0.0'} - bare-stream@2.7.0: - resolution: {integrity: sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==} - peerDependencies: - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - bare-events: - optional: true + '@smithy/chunked-blob-reader@5.2.0': + resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==} + engines: {node: '>=18.0.0'} - bare-url@2.3.2: - resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} + '@smithy/config-resolver@4.4.6': + resolution: {integrity: sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==} + engines: {node: '>=18.0.0'} - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + '@smithy/core@3.23.0': + resolution: {integrity: sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg==} + engines: {node: '>=18.0.0'} - base64id@2.0.0: - resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} - engines: {node: ^4.5.0 || >= 5.9} + '@smithy/credential-provider-imds@4.2.8': + resolution: {integrity: sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==} + engines: {node: '>=18.0.0'} - baseline-browser-mapping@2.9.19: - resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} - hasBin: true + '@smithy/eventstream-codec@4.2.8': + resolution: {integrity: sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==} + engines: {node: '>=18.0.0'} - basic-ftp@5.1.0: - resolution: {integrity: sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==} - engines: {node: '>=10.0.0'} + '@smithy/eventstream-serde-browser@4.2.8': + resolution: {integrity: sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw==} + engines: {node: '>=18.0.0'} - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + '@smithy/eventstream-serde-config-resolver@4.3.8': + resolution: {integrity: sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ==} + engines: {node: '>=18.0.0'} - bcryptjs@2.4.3: - resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} + '@smithy/eventstream-serde-node@4.2.8': + resolution: {integrity: sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A==} + engines: {node: '>=18.0.0'} - before-after-hook@4.0.0: - resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + '@smithy/eventstream-serde-universal@4.2.8': + resolution: {integrity: sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ==} + engines: {node: '>=18.0.0'} - better-opn@3.0.2: - resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} - engines: {node: '>=12.0.0'} + '@smithy/fetch-http-handler@5.3.9': + resolution: {integrity: sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==} + engines: {node: '>=18.0.0'} - bidi-js@1.0.3: - resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + '@smithy/hash-blob-browser@4.2.9': + resolution: {integrity: sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg==} + engines: {node: '>=18.0.0'} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} + '@smithy/hash-node@4.2.8': + resolution: {integrity: sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==} + engines: {node: '>=18.0.0'} - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + '@smithy/hash-stream-node@4.2.8': + resolution: {integrity: sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w==} + engines: {node: '>=18.0.0'} - bn.js@4.12.2: - resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} + '@smithy/invalid-dependency@4.2.8': + resolution: {integrity: sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==} + engines: {node: '>=18.0.0'} - bn.js@5.2.2: - resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} - body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + '@smithy/is-array-buffer@4.2.0': + resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} + engines: {node: '>=18.0.0'} - body-parser@1.20.4: - resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + '@smithy/md5-js@4.2.8': + resolution: {integrity: sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==} + engines: {node: '>=18.0.0'} - body-parser@2.2.2: - resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} - engines: {node: '>=18'} + '@smithy/middleware-content-length@4.2.8': + resolution: {integrity: sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==} + engines: {node: '>=18.0.0'} - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + '@smithy/middleware-endpoint@4.4.14': + resolution: {integrity: sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag==} + engines: {node: '>=18.0.0'} - bottleneck@2.19.5: - resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + '@smithy/middleware-retry@4.4.31': + resolution: {integrity: sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg==} + engines: {node: '>=18.0.0'} - bowser@2.14.1: - resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + '@smithy/middleware-serde@4.2.9': + resolution: {integrity: sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==} + engines: {node: '>=18.0.0'} - boxen@7.0.0: - resolution: {integrity: sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==} - engines: {node: '>=14.16'} + '@smithy/middleware-stack@4.2.8': + resolution: {integrity: sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==} + engines: {node: '>=18.0.0'} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + '@smithy/node-config-provider@4.3.8': + resolution: {integrity: sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==} + engines: {node: '>=18.0.0'} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + '@smithy/node-http-handler@4.4.10': + resolution: {integrity: sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA==} + engines: {node: '>=18.0.0'} - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + '@smithy/property-provider@4.2.8': + resolution: {integrity: sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==} + engines: {node: '>=18.0.0'} - brorand@1.1.0: - resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + '@smithy/protocol-http@5.3.8': + resolution: {integrity: sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==} + engines: {node: '>=18.0.0'} - browser-resolve@2.0.0: - resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==} + '@smithy/querystring-builder@4.2.8': + resolution: {integrity: sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==} + engines: {node: '>=18.0.0'} - browserify-aes@1.2.0: - resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + '@smithy/querystring-parser@4.2.8': + resolution: {integrity: sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==} + engines: {node: '>=18.0.0'} - browserify-cipher@1.0.1: - resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + '@smithy/service-error-classification@4.2.8': + resolution: {integrity: sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==} + engines: {node: '>=18.0.0'} - browserify-des@1.0.2: - resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + '@smithy/shared-ini-file-loader@4.4.3': + resolution: {integrity: sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==} + engines: {node: '>=18.0.0'} - browserify-rsa@4.1.1: - resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} - engines: {node: '>= 0.10'} + '@smithy/signature-v4@5.3.8': + resolution: {integrity: sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==} + engines: {node: '>=18.0.0'} - browserify-sign@4.2.5: - resolution: {integrity: sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==} - engines: {node: '>= 0.10'} + '@smithy/smithy-client@4.11.3': + resolution: {integrity: sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg==} + engines: {node: '>=18.0.0'} - browserify-zlib@0.1.4: - resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} + '@smithy/types@4.12.0': + resolution: {integrity: sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==} + engines: {node: '>=18.0.0'} - browserify-zlib@0.2.0: - resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + '@smithy/url-parser@4.2.8': + resolution: {integrity: sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==} + engines: {node: '>=18.0.0'} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + '@smithy/util-base64@4.3.0': + resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} + engines: {node: '>=18.0.0'} - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + '@smithy/util-body-length-browser@4.2.0': + resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} + engines: {node: '>=18.0.0'} - buffer-crc32@1.0.0: - resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} - engines: {node: '>=8.0.0'} + '@smithy/util-body-length-node@4.2.1': + resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} + engines: {node: '>=18.0.0'} - buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + '@smithy/util-buffer-from@4.2.0': + resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} + engines: {node: '>=18.0.0'} - buffer-xor@1.0.3: - resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + '@smithy/util-config-provider@4.2.0': + resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} + engines: {node: '>=18.0.0'} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + '@smithy/util-defaults-mode-browser@4.3.30': + resolution: {integrity: sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng==} + engines: {node: '>=18.0.0'} - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + '@smithy/util-defaults-mode-node@4.2.33': + resolution: {integrity: sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA==} + engines: {node: '>=18.0.0'} - builtin-status-codes@3.0.0: - resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + '@smithy/util-endpoints@3.2.8': + resolution: {integrity: sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==} + engines: {node: '>=18.0.0'} - bun-types@1.3.8: - resolution: {integrity: sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q==} + '@smithy/util-hex-encoding@4.2.0': + resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} + engines: {node: '>=18.0.0'} - bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} - engines: {node: '>=18'} + '@smithy/util-middleware@4.2.8': + resolution: {integrity: sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==} + engines: {node: '>=18.0.0'} - bundle-require@5.1.0: - resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.18' + '@smithy/util-retry@4.2.8': + resolution: {integrity: sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==} + engines: {node: '>=18.0.0'} - bytes@3.0.0: - resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} - engines: {node: '>= 0.8'} + '@smithy/util-stream@4.5.12': + resolution: {integrity: sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg==} + engines: {node: '>=18.0.0'} - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} + '@smithy/util-uri-escape@4.2.0': + resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} + engines: {node: '>=18.0.0'} - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} - cacheable-lookup@6.1.0: - resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} - engines: {node: '>=10.6.0'} + '@smithy/util-utf8@4.2.0': + resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} + engines: {node: '>=18.0.0'} - cacheable-lookup@7.0.0: - resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} - engines: {node: '>=14.16'} + '@smithy/util-waiter@4.2.8': + resolution: {integrity: sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==} + engines: {node: '>=18.0.0'} - cacheable-request@10.2.14: - resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} - engines: {node: '>=14.16'} + '@smithy/uuid@1.1.0': + resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} + engines: {node: '>=18.0.0'} - cacheable-request@7.0.2: - resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} - engines: {node: '>=8'} + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + '@speed-highlight/core@1.2.14': + resolution: {integrity: sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==} - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} + '@stablelib/base64@1.0.1': + resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + '@stoplight/better-ajv-errors@1.0.3': + resolution: {integrity: sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==} + engines: {node: ^12.20 || >= 14.13} + peerDependencies: + ajv: '>=8' - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} + '@stoplight/json-ref-readers@1.2.2': + resolution: {integrity: sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==} + engines: {node: '>=8.3.0'} - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} + '@stoplight/json-ref-resolver@3.1.6': + resolution: {integrity: sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==} + engines: {node: '>=8.3.0'} - camelcase@7.0.1: - resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} - engines: {node: '>=14.16'} + '@stoplight/json@3.21.0': + resolution: {integrity: sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==} + engines: {node: '>=8.3.0'} - caniuse-lite@1.0.30001767: - resolution: {integrity: sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==} + '@stoplight/ordered-object-literal@1.0.5': + resolution: {integrity: sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==} + engines: {node: '>=8'} - canvas@3.2.1: - resolution: {integrity: sha512-ej1sPFR5+0YWtaVp6S1N1FVz69TQCqmrkGeRvQxZeAB1nAIcjNTHVwrZtYtWFFBmQsF40/uDLehsW5KuYC99mg==} - engines: {node: ^18.12.0 || >= 20.9.0} + '@stoplight/path@1.3.2': + resolution: {integrity: sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==} + engines: {node: '>=8'} - caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + '@stoplight/spectral-core@1.21.0': + resolution: {integrity: sha512-oj4e/FrDLUhBRocIW+lRMKlJ/q/rDZw61HkLbTFsdMd+f/FTkli2xHNB1YC6n1mrMKjjvy7XlUuFkC7XxtgbWw==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} - ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + '@stoplight/spectral-formats@1.8.2': + resolution: {integrity: sha512-c06HB+rOKfe7tuxg0IdKDEA5XnjL2vrn/m/OVIIxtINtBzphZrOgtRn7epQ5bQF5SWp84Ue7UJWaGgDwVngMFw==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} - chai@5.3.3: - resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} - engines: {node: '>=18'} + '@stoplight/spectral-functions@1.10.1': + resolution: {integrity: sha512-obu8ZfoHxELOapfGsCJixKZXZcffjg+lSoNuttpmUFuDzVLT3VmH8QkPXfOGOL5Pz80BR35ClNAToDkdnYIURg==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} - chalk-template@0.4.0: - resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==} - engines: {node: '>=12'} - - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + '@stoplight/spectral-parsers@1.0.5': + resolution: {integrity: sha512-ANDTp2IHWGvsQDAY85/jQi9ZrF4mRrA5bciNHX+PUxPr4DwS6iv4h+FVWJMVwcEYdpyoIdyL+SRmHdJfQEPmwQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} - chalk@5.0.1: - resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + '@stoplight/spectral-ref-resolver@1.0.5': + resolution: {integrity: sha512-gj3TieX5a9zMW29z3mBlAtDOCgN3GEc1VgZnCVlr5irmR4Qi5LuECuFItAq4pTn5Zu+sW5bqutsCH7D4PkpyAA==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} - chalk@5.2.0: - resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + '@stoplight/spectral-runtime@1.1.4': + resolution: {integrity: sha512-YHbhX3dqW0do6DhiPSgSGQzr6yQLlWybhKwWx0cqxjMwxej3TqLv3BXMfIUYFKKUqIwH4Q2mV8rrMM8qD2N0rQ==} + engines: {node: ^16.20 || ^18.18 || >= 20.17} - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + '@stoplight/types@13.20.0': + resolution: {integrity: sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==} + engines: {node: ^12.20 || >=14.13} - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + '@stoplight/types@13.6.0': + resolution: {integrity: sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==} + engines: {node: ^12.20 || >=14.13} - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} + '@stoplight/types@14.1.1': + resolution: {integrity: sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g==} + engines: {node: ^12.20 || >=14.13} - character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + '@stoplight/yaml-ast-parser@0.0.50': + resolution: {integrity: sha512-Pb6M8TDO9DtSVla9yXSTAxmo9GVEouq5P40DWXdOie69bXogZTkgvopCq+yEvTMA0F6PEvdJmbtTV3ccIp11VQ==} - character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + '@stoplight/yaml@4.3.0': + resolution: {integrity: sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==} + engines: {node: '>=10.8'} - character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + '@superdoc-dev/react@1.0.0-rc.2': + resolution: {integrity: sha512-InnTQA94Glg7f6/nPiumw4iVmHwyV3LAvu9VysmRLNYATAOWF/JhteeYeQgAOw8LCYYZBNL1kz1JdQb0Prwu7Q==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' - character-reference-invalid@2.0.1: - resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + '@superdoc-dev/sdk-darwin-arm64@1.0.0-alpha.39': + resolution: {integrity: sha512-koNRyNj7V/KTSQ1cTwU/qSJijdn+IJ3AqNfMEk6XjyXy088sA3J4nod2ZdQEPUYZdyTjS6oQAWQT7bWXXftNeA==} + cpu: [arm64] + os: [darwin] + hasBin: true - chardet@2.1.1: - resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + '@superdoc-dev/sdk-darwin-x64@1.0.0-alpha.39': + resolution: {integrity: sha512-denq7/8dMyakOKr1hbAz77D1K/itlNV1xBya5IYBLhsAwgvj2IC4WGma+bVGkwsvLEIjViYqUxPhQARv2gUjFA==} + cpu: [x64] + os: [darwin] + hasBin: true - check-error@2.1.3: - resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} - engines: {node: '>= 16'} + '@superdoc-dev/sdk-linux-arm64@1.0.0-alpha.39': + resolution: {integrity: sha512-Lq0qtcR1HXmuhr+/jTu09R2VMflUCvKep4veRtbBxQJXOYCE1M6YDHkHze4Y+6vRyzMI9G2duUuEFjKUoDs1Dg==} + cpu: [arm64] + os: [linux] + hasBin: true - cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + '@superdoc-dev/sdk-linux-x64@1.0.0-alpha.39': + resolution: {integrity: sha512-HTTiFrEM950JcR3KAM2tmuOAEnhStWLnwI2J3a3NeJquiZKkiwOSvb9dHG8ZD72dSnMKX2h/HCBulJJy7zF0bg==} + cpu: [x64] + os: [linux] + hasBin: true - cheerio@1.2.0: - resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} - engines: {node: '>=20.18.1'} + '@superdoc-dev/sdk-windows-x64@1.0.0-alpha.39': + resolution: {integrity: sha512-CHlFWa/bPRnZN+JDe3i0As2tszsMX+QSk5eorISEJJ2JyxqCLnFjVDgHkQoS6Zq65EaO1q1jg+gqqyEucIU1jA==} + cpu: [x64] + os: [win32] + hasBin: true - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} + '@superdoc-dev/sdk@1.0.0-alpha.39': + resolution: {integrity: sha512-jkrEWx+qIntA8WtXu7a4Ht+S+ueJzQAOhSC+ybGoaaBAt2Lnip4yGmTG4Nqww6dvdqykIX4x665fV8vfJHMtHA==} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + '@superdoc-dev/sdk@file:packages/sdk/langs/node': + resolution: {directory: packages/sdk/langs/node, type: directory} - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} + '@superdoc-dev/superdoc-yjs-collaboration@1.0.2': + resolution: {integrity: sha512-bmTCS3xMSIfvWL8V7is9IR/MxWhkLUlaxJy7J/1/u8m1wP/cQLznzmK2kF0egslz3odH7DCG3ag0Tr6i8u9ySA==} - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - chromium-bidi@0.6.2: - resolution: {integrity: sha512-4WVBa6ijmUTVr9cZD4eicQD8Mdy/HCX3bzEIYYpmk0glqYLoWH+LqQEvV9RpDRzoQSbY1KJHloYXbDMXMbDPhg==} - peerDependencies: - devtools-protocol: '*' + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} - cipher-base@1.0.7: - resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} - engines: {node: '>= 0.10'} + '@tailwindcss/node@4.2.1': + resolution: {integrity: sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==} - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} + '@tailwindcss/oxide-android-arm64@4.2.1': + resolution: {integrity: sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] - clean-stack@4.2.0: - resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} - engines: {node: '>=12'} + '@tailwindcss/oxide-darwin-arm64@4.2.1': + resolution: {integrity: sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] - clean-stack@5.3.0: - resolution: {integrity: sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==} - engines: {node: '>=14.16'} + '@tailwindcss/oxide-darwin-x64@4.2.1': + resolution: {integrity: sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] - cli-boxes@3.0.0: - resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} - engines: {node: '>=10'} + '@tailwindcss/oxide-freebsd-x64@4.2.1': + resolution: {integrity: sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] - cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': + resolution: {integrity: sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] - cli-highlight@2.1.11: - resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} - engines: {node: '>=8.0.0', npm: '>=5.0.0'} - hasBin: true + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': + resolution: {integrity: sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': + resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} - engines: {node: 10.* || >= 12.*} + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': + resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] - cli-truncate@4.0.0: - resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} - engines: {node: '>=18'} + '@tailwindcss/oxide-linux-x64-musl@4.2.1': + resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} + '@tailwindcss/oxide-wasm32-wasi@4.2.1': + resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': + resolution: {integrity: sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] - clipanion@4.0.0-rc.4: - resolution: {integrity: sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q==} - peerDependencies: - typanion: '*' + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': + resolution: {integrity: sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] - clipboardy@3.0.0: - resolution: {integrity: sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + '@tailwindcss/oxide@4.2.1': + resolution: {integrity: sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==} + engines: {node: '>= 20'} - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + '@tailwindcss/postcss@4.2.1': + resolution: {integrity: sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==} - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} - clone-response@1.0.3: - resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - cockatiel@3.2.1: - resolution: {integrity: sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==} - engines: {node: '>=16'} + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - code-excerpt@4.0.0: - resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' - collapse-white-space@2.1.0: - resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - color-blend@4.0.0: - resolution: {integrity: sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw==} - engines: {node: '>=10.0.0'} + '@tufjs/canonical-json@2.0.0': + resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} + engines: {node: ^16.14.0 || >=18.0.0} - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + '@tufjs/models@4.1.0': + resolution: {integrity: sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==} + engines: {node: ^20.17.0 || >=22.9.0} - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + '@types/acorn@4.0.6': + resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + '@types/argparse@1.0.38': + resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - color2k@2.0.3: - resolution: {integrity: sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - colorette@1.4.0: - resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + '@types/bonjour@3.5.13': + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} + '@types/bun@1.3.8': + resolution: {integrity: sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA==} - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - commander@6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} + '@types/connect-history-api-fallback@1.5.4': + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - comment-parser@1.4.1: - resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} - engines: {node: '>= 12.0.0'} + '@types/conventional-commits-parser@5.0.2': + resolution: {integrity: sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==} - comment-parser@1.4.5: - resolution: {integrity: sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==} - engines: {node: '>= 12.0.0'} + '@types/cookie@0.4.1': + resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} - compare-func@2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + '@types/cors@2.8.19': + resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} - compare-versions@6.1.1: - resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - compressible@2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - compression@1.8.1: - resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} - engines: {node: '>= 0.8.0'} + '@types/es-aggregate-error@1.0.6': + resolution: {integrity: sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - concurrently@9.2.1: - resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} - engines: {node: '>=18'} - hasBin: true + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - confbox@0.2.2: - resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - config-chain@1.1.13: - resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} - console-browserify@1.2.0: - resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} + '@types/extend@3.0.4': + resolution: {integrity: sha512-ArMouDUTJEz1SQRpFsT2rIw7DeqICFv5aaVzLSIYMYQSLcwcGOfT3VyglQs/p7K3F7fT4zxr0NWxYZIdifD6dA==} - constants-browserify@1.0.0: - resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} + '@types/fs-extra@8.1.5': + resolution: {integrity: sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==} - content-disposition@0.5.2: - resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} - engines: {node: '>= 0.6'} + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} - content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} - content-disposition@1.0.1: - resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} - engines: {node: '>=18'} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} - conventional-changelog-angular@7.0.0: - resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} - engines: {node: '>=16'} + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} - conventional-changelog-angular@8.1.0: - resolution: {integrity: sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==} - engines: {node: '>=18'} + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} - conventional-changelog-conventionalcommits@7.0.2: - resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} - engines: {node: '>=16'} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - conventional-changelog-writer@8.2.0: - resolution: {integrity: sha512-Y2aW4596l9AEvFJRwFGJGiQjt2sBYTjPD18DdvxX9Vpz0Z7HQ+g1Z+6iYDAm1vR3QOJrDBkRHixHK/+FhkR6Pw==} - engines: {node: '>=18'} - hasBin: true + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - conventional-commits-filter@5.0.0: - resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} - engines: {node: '>=18'} + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} - conventional-commits-parser@5.0.0: - resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} - engines: {node: '>=16'} - hasBin: true + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} - conventional-commits-parser@6.2.1: - resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} - engines: {node: '>=18'} - hasBin: true + '@types/lodash@4.17.23': + resolution: {integrity: sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==} - convert-hrtime@5.0.0: - resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} - engines: {node: '>=12'} + '@types/mdast@3.0.15': + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - convert-to-spaces@2.0.1: - resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - cookie-signature@1.0.7: - resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + '@types/minimatch@6.0.0': + resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} + deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} + '@types/node@20.19.37': + resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==} - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} + '@types/node@22.19.2': + resolution: {integrity: sha512-LPM2G3Syo1GLzXLGJAKdqoU35XvrWzGJ21/7sgZTUpbkBaOasTj8tjwn6w+hCkqaa1TfJ/w67rJSwYItlJ2mYw==} - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + '@types/node@22.19.8': + resolution: {integrity: sha512-ebO/Yl+EAvVe8DnMfi+iaAyIqYdK0q/q0y0rw82INWEKJOBe6b/P3YWE8NW7oOlF/nXFNrHwhARrN/hdgDkraA==} - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} + '@types/parse5@6.0.3': + resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} - cors@2.8.6: - resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} - engines: {node: '>= 0.10'} + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - cosmiconfig-typescript-loader@6.2.0: - resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==} - engines: {node: '>=v18'} + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} peerDependencies: - '@types/node': '*' - cosmiconfig: '>=9' - typescript: '>=5' + '@types/react': ^18.0.0 - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true + '@types/react': ^19.2.0 - create-ecdh@4.0.4: - resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + '@types/react@18.3.28': + resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} - create-hash@1.2.0: - resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + '@types/react@19.2.11': + resolution: {integrity: sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==} - create-hmac@1.1.7: - resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + '@types/responselike@1.0.0': + resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - crypto-browserify@3.12.1: - resolution: {integrity: sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==} - engines: {node: '>= 0.10'} + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} - crypto-random-string@2.0.0: - resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} - engines: {node: '>=8'} + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} - crypto-random-string@4.0.0: - resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} - engines: {node: '>=12'} + '@types/serve-index@1.9.4': + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} - css-render@0.15.14: - resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==} + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + '@types/sockjs@0.3.36': + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} - css-tree@3.1.0: - resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + '@types/supports-color@8.1.3': + resolution: {integrity: sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==} - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - css.escape@1.5.1: - resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - cssstyle@5.3.7: - resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==} - engines: {node: '>=20'} - - csstype@3.0.11: - resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + '@types/urijs@1.19.26': + resolution: {integrity: sha512-wkXrVzX5yoqLnndOwFsieJA7oKM8cNkOKJtf/3vVGSUFkWDKZvFHpIl9Pvqb/T9UsawBBFMTTD8xu7sK5MWuvg==} - dargs@8.1.0: - resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} - engines: {node: '>=12'} + '@types/vscode@1.108.1': + resolution: {integrity: sha512-DerV0BbSzt87TbrqmZ7lRDIYaMiqvP8tmJTzW2p49ZBVtGUnGAu2RGQd1Wv4XMzEVUpaHbsemVM5nfuQJj7H6w==} - dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - data-urls@6.0.1: - resolution: {integrity: sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==} - engines: {node: '>=20'} + '@typescript-eslint/eslint-plugin@8.54.0': + resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.54.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} + '@typescript-eslint/parser@8.54.0': + resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} + '@typescript-eslint/project-service@8.54.0': + resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} + '@typescript-eslint/scope-manager@8.54.0': + resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - date-fns-tz@3.2.0: - resolution: {integrity: sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==} + '@typescript-eslint/tsconfig-utils@8.54.0': + resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - date-fns: ^3.0.0 || ^4.0.0 - - date-fns@4.1.0: - resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + typescript: '>=4.8.4 <6.0.0' - dayjs@1.11.13: - resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + '@typescript-eslint/type-utils@8.54.0': + resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' - de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + '@typescript-eslint/types@8.54.0': + resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + '@typescript-eslint/typescript-estree@8.54.0': + resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + typescript: '>=4.8.4 <6.0.0' - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} + '@typescript-eslint/utils@8.54.0': + resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + '@typescript-eslint/visitor-keys@8.54.0': + resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} + '@typescript/vfs@1.6.2': + resolution: {integrity: sha512-hoBwJwcbKHmvd2QVebiytN1aELvpk9B74B4L1mFm/XT1Q/VOYAWl2vQ9AWRFtQq8zmz6enTpfTV8WRc4ATjW/g==} peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + typescript: '*' - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + '@typespec/ts-http-runtime@0.3.2': + resolution: {integrity: sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==} + engines: {node: '>=20.0.0'} - decode-bmp@0.2.1: - resolution: {integrity: sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==} - engines: {node: '>=8.6.0'} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - decode-ico@0.4.1: - resolution: {integrity: sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==} - engines: {node: '>=8.6'} + '@unhead/vue@2.1.10': + resolution: {integrity: sha512-VP78Onh2HNezLPfhYjfHqn4dxlcQsE6PJgTTs61NksO/thvilNswtgBq0N0MWCLtn43N5akEPGW2y2zxM3PWgQ==} + peerDependencies: + vue: 3.5.25 - decode-named-character-reference@1.3.0: - resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] - default-browser-id@5.0.1: - resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} - engines: {node: '>=18'} + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} - engines: {node: '>=18'} + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] - defer-to-connect@2.0.1: - resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} - engines: {node: '>=10'} + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] - define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] - degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] - del@6.1.1: - resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} - engines: {node: '>=10'} + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] - dependency-graph@0.11.0: - resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} - engines: {node: '>= 0.6.0'} + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] - des.js@1.1.0: - resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + '@vercel/nft@1.3.2': + resolution: {integrity: sha512-HC8venRc4Ya7vNeBsJneKHHMDDWpQie7VaKhAIOst3MKO+DES+Y/SbzSp8mFkD7OzwAE2HhHkeSuSmwS20mz3A==} + engines: {node: '>=20'} + hasBin: true - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} + '@verdaccio/auth@8.0.0-next-8.29': + resolution: {integrity: sha512-lEIqneZ7LYYkF07/P9cJhOYVZTIIARGRVE66j666VR58T/fY/pC4hxEfuyqlfd3BhS3hM65aIrPZu+s03hyg+w==} + engines: {node: '>=18'} - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + '@verdaccio/config@8.0.0-next-8.29': + resolution: {integrity: sha512-7kEZ6tv3NsJFPcKQrxELMkvJFI9Hmy1s8IPjuXjz9gobDV3NyF9VhPsh6l18Tm+nsqXb6ZTWiRup9V8Lkg0p0g==} + engines: {node: '>=18'} - detect-port@1.5.1: - resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} - hasBin: true + '@verdaccio/core@8.0.0-next-8.21': + resolution: {integrity: sha512-n3Y8cqf84cwXxUUdTTfEJc8fV55PONPKijCt2YaC0jilb5qp1ieB3d4brqTOdCdXuwkmnG2uLCiGpUd/RuSW0Q==} + engines: {node: '>=18'} - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + '@verdaccio/core@8.0.0-next-8.29': + resolution: {integrity: sha512-ztsNbnHMGqpOJlC3x/Jz7+0Xzrul+UIQQAFsTFHO3pET8nyZWkh/1TH50olz0pZ/OS87O/+7mk04TK9hHD/eFQ==} + engines: {node: '>=18'} - devtools-protocol@0.0.1312386: - resolution: {integrity: sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==} + '@verdaccio/file-locking@10.3.1': + resolution: {integrity: sha512-oqYLfv3Yg3mAgw9qhASBpjD50osj2AX4IwbkUtyuhhKGyoFU9eZdrbeW6tpnqUnj6yBMtAPm2eGD4BwQuX400g==} + engines: {node: '>=12'} - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + '@verdaccio/file-locking@13.0.0-next-8.6': + resolution: {integrity: sha512-F6xQWvsZnEyGjugrYfe+D/ChSVudXmBFWi8xuTIX6PAdp7dk9x9biOGQFW8O3GSAK8UhJ6WlRisQKJeYRa6vWQ==} + engines: {node: '>=18'} - diff@5.2.2: - resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==} - engines: {node: '>=0.3.1'} + '@verdaccio/hooks@8.0.0-next-8.29': + resolution: {integrity: sha512-KRuTN6iYg9ntFXmrH+fY+dNCFpNBMcEwOVLOJXk/fA3I3ki188FpRZz9rKToyj1XYZzPDqGUWv82ekswX5wrYw==} + engines: {node: '>=18'} - diff@8.0.3: - resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} - engines: {node: '>=0.3.1'} + '@verdaccio/loaders@8.0.0-next-8.19': + resolution: {integrity: sha512-+mQuEZNLRZ4EEjzfROHrVeZXVHNFhQTpI98KCpcbU1NEC7ZAl5m7OBD2XPVtvNTia2ZT83q4H0JPi/bAomnIRA==} + engines: {node: '>=18'} - diffie-hellman@5.0.3: - resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + '@verdaccio/local-storage-legacy@11.1.1': + resolution: {integrity: sha512-P6ahH2W6/KqfJFKP+Eid7P134FHDLNvHa+i8KVgRVBeo2/IXb6FEANpM1mCVNvPANu0LCAmNJBOXweoUKViaoA==} + engines: {node: '>=18'} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + '@verdaccio/logger-commons@8.0.0-next-8.29': + resolution: {integrity: sha512-CVeLv+U0cL9wtNJVwtzjj7wtUFYxMDmynWoXtepP+AthVoNj6G6rU2P2tGLX/uqH40EwqaHJy5Vo0uZ3ex2qhQ==} + engines: {node: '>=18'} - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + '@verdaccio/logger-prettify@8.0.0-next-8.4': + resolution: {integrity: sha512-gjI/JW29fyalutn/X1PQ0iNuGvzeVWKXRmnLa7gXVKhdi4p37l/j7YZ7n44XVbbiLIKAK0pbavEg9Yr66QrYaA==} + engines: {node: '>=18'} - dns-packet@5.6.1: - resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} - engines: {node: '>=6'} + '@verdaccio/logger@8.0.0-next-8.29': + resolution: {integrity: sha512-AF6hBAkgsRjDFGLjFWO9hzUWM47Jt15v90I6Wk0TotzsrWxgBYbslfJyTgwmTpGjhPe7al2dnFwT7hxKa6fr/w==} + engines: {node: '>=18'} - dns-socket@4.2.2: - resolution: {integrity: sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==} - engines: {node: '>=6'} + '@verdaccio/middleware@8.0.0-next-8.29': + resolution: {integrity: sha512-ANsQ8qjyNslH6BfGZnNkBvK1acTlnFgedXen6BnbN9nF+AWzHUea6knh529J5Clm3zrWggbRnGCrp1SSlbOqSA==} + engines: {node: '>=18'} - doctrine-temporary-fork@2.1.0: - resolution: {integrity: sha512-nliqOv5NkE4zMON4UA6AMJE6As35afs8aYXATpU4pTUdIKiARZwrJVEP1boA3Rx1ZXHVkwxkhcq4VkqvsuRLsA==} - engines: {node: '>=0.10.0'} + '@verdaccio/search-indexer@8.0.0-next-8.5': + resolution: {integrity: sha512-0GC2tJKstbPg/W2PZl2yE+hoAxffD2ZWilEnEYSEo2e9UQpNIy2zg7KE/uMUq2P72Vf5EVfVzb8jdaH4KV4QeA==} + engines: {node: '>=18'} - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} + '@verdaccio/signature@8.0.0-next-8.21': + resolution: {integrity: sha512-5TuGPRT4c5B3k6svxJ6Q5l31UBZTODo3iAJxmuAAC0iZBLNnivdvJlqUVdpZtYfrhwvuP5vuo7lucHQk6DsSmw==} + engines: {node: '>=18'} - documentation@14.0.3: - resolution: {integrity: sha512-B7cAviVKN9Rw7Ofd+9grhVuxiHwly6Ieh+d/ceMw8UdBOv/irkuwnDEJP8tq0wgdLJDUVuIkovV+AX9mTrZFxg==} - engines: {node: '>=14'} - hasBin: true + '@verdaccio/streams@10.2.1': + resolution: {integrity: sha512-OojIG/f7UYKxC4dYX8x5ax8QhRx1b8OYUAMz82rUottCuzrssX/4nn5QE7Ank0DUSX3C9l/HPthc4d9uKRJqJQ==} + engines: {node: '>=12', npm: '>=5'} - dom-accessibility-api@0.5.16: - resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + '@verdaccio/tarball@13.0.0-next-8.29': + resolution: {integrity: sha512-4hTQMXYF1olwwydaVfb6ab1TTImM42rAxLmw3VnJUI5ttbmfB9h095/TYsCssy5vqGQMp3l8YW/JxVTPcVtGYA==} + engines: {node: '>=18'} - dom-accessibility-api@0.6.3: - resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + '@verdaccio/ui-theme@8.0.0-next-8.29': + resolution: {integrity: sha512-kSg69so1LHOL2SA1qLJikFxkx8FEOFQJV+Nde0lN3XMkp0RST8DgLx/hiVbgYzPz54S8LuvYR/DQAulyRulMcg==} - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + '@verdaccio/url@13.0.0-next-8.29': + resolution: {integrity: sha512-ucJ6MhLfY0g8uU0zjcJypSkCa1mXSLmrqdiILyj16Lo0y4w/gEvddMrfab8QUmgvvuzbCgSqCZHJmbZn7DFxQg==} + engines: {node: '>=18'} - domain-browser@4.22.0: - resolution: {integrity: sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==} - engines: {node: '>=10'} + '@verdaccio/utils@8.1.0-next-8.29': + resolution: {integrity: sha512-EgyazlL0VejvZqWZ6KL3ig27Yl8RXcwhz1hayuqeAIxaqbsnmSmogL2zKXgGnm9y/A6QkPfZH1BcQoUh1STvtQ==} + engines: {node: '>=18'} - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + '@vitejs/plugin-basic-ssl@2.1.4': + resolution: {integrity: sha512-HXciTXN/sDBYWgeAD4V4s0DN0g72x5mlxQhHxtYu3Tt8BLa6MzcJZUyDVFCdtjNs3bfENVHVzOsmooTVuNgAAw==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} + '@vitejs/plugin-react@4.7.0': + resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + '@vitejs/plugin-react@5.1.3': + resolution: {integrity: sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - dot-prop@5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} + '@vitejs/plugin-vue-jsx@5.1.4': + resolution: {integrity: sha512-70LmoVk9riR7qc4W2CpjsbNMWTPnuZb9dpFKX1emru0yP57nsc9k8nhLA6U93ngQapv5VDIUq2JatNfLbBIkrA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vue: 3.5.25 - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} - engines: {node: '>=12'} + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: 3.5.25 - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + '@vitejs/plugin-vue@6.0.2': + resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vue: 3.5.25 - duplexer2@0.1.4: - resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + '@vitejs/plugin-vue@6.0.4': + resolution: {integrity: sha512-uM5iXipgYIn13UUQCZNdWkYk+sysBeA97d5mHsAoAt1u/wpN3+zxOmsVJWosuzX+IMGRzeYUNytztrYznboIkQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vue: 3.5.25 - duplexify@3.7.1: - resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + '@vitest/coverage-v8@3.2.4': + resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} + peerDependencies: + '@vitest/browser': 3.2.4 + vitest: 3.2.4 + peerDependenciesMeta: + '@vitest/browser': + optional: true - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true - ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - editorconfig@1.0.4: - resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} - engines: {node: '>=14'} - hasBin: true + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - electron-to-chromium@1.5.286: - resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - elliptic@6.6.1: - resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + '@volar/typescript@2.4.28': + resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - emojilib@2.4.0: - resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + '@vscode/vsce-sign-alpine-arm64@2.0.6': + resolution: {integrity: sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==} + cpu: [arm64] + os: [alpine] - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} + '@vscode/vsce-sign-alpine-x64@2.0.6': + resolution: {integrity: sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==} + cpu: [x64] + os: [alpine] - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} + '@vscode/vsce-sign-darwin-arm64@2.0.6': + resolution: {integrity: sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==} + cpu: [arm64] + os: [darwin] - encoding-sniffer@0.2.1: - resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + '@vscode/vsce-sign-darwin-x64@2.0.6': + resolution: {integrity: sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw==} + cpu: [x64] + os: [darwin] - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + '@vscode/vsce-sign-linux-arm64@2.0.6': + resolution: {integrity: sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==} + cpu: [arm64] + os: [linux] - engine.io-parser@5.2.3: - resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} - engines: {node: '>=10.0.0'} + '@vscode/vsce-sign-linux-arm@2.0.6': + resolution: {integrity: sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==} + cpu: [arm] + os: [linux] - engine.io@6.5.5: - resolution: {integrity: sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==} - engines: {node: '>=10.2.0'} + '@vscode/vsce-sign-linux-x64@2.0.6': + resolution: {integrity: sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==} + cpu: [x64] + os: [linux] - entities@2.1.0: - resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} + '@vscode/vsce-sign-win32-arm64@2.0.6': + resolution: {integrity: sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==} + cpu: [arm64] + os: [win32] - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} + '@vscode/vsce-sign-win32-x64@2.0.6': + resolution: {integrity: sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==} + cpu: [x64] + os: [win32] - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} + '@vscode/vsce-sign@2.0.9': + resolution: {integrity: sha512-8IvaRvtFyzUnGGl3f5+1Cnor3LqaUWvhaUjAYO8Y39OUYlOf3cRd+dowuQYLpZcP3uwSG+mURwjEBOSq4SOJ0g==} - entities@7.0.1: - resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} - engines: {node: '>=0.12'} + '@vscode/vsce@2.32.0': + resolution: {integrity: sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==} + engines: {node: '>= 16'} + hasBin: true - env-ci@11.2.0: - resolution: {integrity: sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==} - engines: {node: ^18.17 || >=20.6.1} + '@vue-macros/common@3.1.2': + resolution: {integrity: sha512-h9t4ArDdniO9ekYHAD95t9AZcAbb19lEGK+26iAjUODOIJKmObDNBSe4+6ELQAA3vtYiFPPBtHh7+cQCKi3Dng==} + engines: {node: '>=20.19.0'} + peerDependencies: + vue: 3.5.25 + peerDependenciesMeta: + vue: + optional: true - env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} + '@vue/babel-helper-vue-transform-on@2.0.1': + resolution: {integrity: sha512-uZ66EaFbnnZSYqYEyplWvn46GhZ1KuYSThdT68p+am7MgBNbQ3hphTL9L+xSIsWkdktwhPYLwPgVWqo96jDdRA==} - envinfo@7.15.0: - resolution: {integrity: sha512-chR+t7exF6y59kelhXw5I3849nTy7KIRO+ePdLMhCD+JRP/JvmkenDWP7QSFGlsHX+kxGxdDutOPrmj5j1HR6g==} - engines: {node: '>=4'} - hasBin: true + '@vue/babel-plugin-jsx@2.0.1': + resolution: {integrity: sha512-a8CaLQjD/s4PVdhrLD/zT574ZNPnZBOY+IhdtKWRB4HRZ0I2tXBi5ne7d9eCfaYwp5gU5+4KIyFTV1W1YL9xZA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true - environment@1.1.0: - resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} - engines: {node: '>=18'} + '@vue/babel-plugin-resolve-type@2.0.1': + resolution: {integrity: sha512-ybwgIuRGRRBhOU37GImDoWQoz+TlSqap65qVI6iwg/J7FfLTLmMf97TS7xQH9I7Qtr/gp161kYVdhr1ZMraSYQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 - error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + '@vue/compiler-core@3.5.25': + resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} - es-abstract@1.24.1: - resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} - engines: {node: '>= 0.4'} + '@vue/compiler-dom@3.5.25': + resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} - es-aggregate-error@1.0.14: - resolution: {integrity: sha512-3YxX6rVb07B5TV11AV5wsL7nQCHXNwoHPsQC8S4AmBiqYhyNCJ5BRKXkXyDJvs8QzXN20NgRtxe3dEEQD9NLHA==} - engines: {node: '>= 0.4'} + '@vue/compiler-sfc@3.5.25': + resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + '@vue/compiler-ssr@3.5.25': + resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} - es-iterator-helpers@1.2.2: - resolution: {integrity: sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==} - engines: {node: '>= 0.4'} + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + '@vue/devtools-core@8.0.7': + resolution: {integrity: sha512-PmpiPxvg3Of80ODHVvyckxwEW1Z02VIAvARIZS1xegINn3VuNQLm9iHUmKD+o6cLkMNWV8OG8x7zo0kgydZgdg==} + peerDependencies: + vue: 3.5.25 - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} + '@vue/devtools-kit@8.0.7': + resolution: {integrity: sha512-H6esJGHGl5q0E9iV3m2EoBQHJ+V83WMW83A0/+Fn95eZ2iIvdsq4+UCS6yT/Fdd4cGZSchx/MdWDreM3WqMsDw==} - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + '@vue/devtools-shared@8.0.7': + resolution: {integrity: sha512-CgAb9oJH5NUmbQRdYDj/1zMiaICYSLtm+B1kxcP72LBrifGAjUmt8bx52dDH1gWRPlQgxGPqpAMKavzVirAEhA==} - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} + '@vue/language-core@2.2.0': + resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} + '@vue/language-core@3.2.5': + resolution: {integrity: sha512-d3OIxN/+KRedeM5wQ6H6NIpwS3P5gC9nmyaHgBk+rO6dIsjY+tOh4UlPpiZbAh3YtLdCGEX4M16RmsBqPmJV+g==} - es-toolkit@1.44.0: - resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==} + '@vue/reactivity@3.5.25': + resolution: {integrity: sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==} - esast-util-from-estree@2.0.0: - resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + '@vue/runtime-core@3.5.25': + resolution: {integrity: sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==} - esast-util-from-js@2.0.1: - resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + '@vue/runtime-dom@3.5.25': + resolution: {integrity: sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==} - esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} - hasBin: true + '@vue/server-renderer@3.5.25': + resolution: {integrity: sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==} + peerDependencies: + vue: 3.5.25 - esbuild@0.27.2: - resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} - engines: {node: '>=18'} - hasBin: true + '@vue/shared@3.5.25': + resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + '@vue/test-utils@2.4.6': + resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - eslint-config-prettier@9.1.2: - resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - peerDependencies: - unrs-resolver: ^1.0.0 - peerDependenciesMeta: - unrs-resolver: - optional: true + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - eslint-import-resolver-typescript@4.4.4: - resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} - engines: {node: ^16.17.0 || >=18.6.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - eslint-plugin-import-x: '*' - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - eslint-plugin-import-x@4.16.1: - resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/utils': ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 - eslint-import-resolver-node: '*' - peerDependenciesMeta: - '@typescript-eslint/utils': - optional: true - eslint-import-resolver-node: - optional: true + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - eslint-plugin-jsdoc@54.7.0: - resolution: {integrity: sha512-u5Na4he2+6kY1rWqxzbQaAwJL3/tDCuT5ElDRc5UJ9stOeQeQ5L1JJ1kRRu7ldYMlOHMCJLsY8Mg/Tu3ExdZiQ==} - engines: {node: '>=20.11.0'} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - eslint-plugin-react-hooks@7.0.1: - resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} - engines: {node: '>=18'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - eslint-plugin-react@7.37.5: - resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - eslint@9.39.2: - resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} + '@zeit/schemas@2.36.0': + resolution: {integrity: sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==} - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - estree-util-attach-comments@3.0.0: - resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} - estree-util-build-jsx@3.0.1: - resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + abbrev@4.0.0: + resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} + engines: {node: ^20.17.0 || >=22.9.0} - estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} - estree-util-scope@1.0.0: - resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + abstract-logging@2.0.1: + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} - estree-util-to-js@2.0.0: - resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} - estree-util-visit@2.0.0: - resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} + acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + engines: {node: '>=0.4.0'} + hasBin: true - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true - eventemitter3@5.0.4: - resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true - events-universal@1.0.1: - resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} + adjust-sourcemap-loader@4.0.0: + resolution: {integrity: sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==} + engines: {node: '>=8.9'} - eventsource-parser@3.0.6: - resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} - engines: {node: '>=18.0.0'} + adm-zip@0.5.16: + resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==} + engines: {node: '>=12.0'} - eventsource@3.0.7: - resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} - engines: {node: '>=18.0.0'} + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} - evp_bytestokey@1.0.3: - resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} - evtd@0.2.4: - resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + aggregate-error@4.0.1: + resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} + engines: {node: '>=12'} - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} + aggregate-error@5.0.0: + resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==} + engines: {node: '>=18'} - execa@9.6.1: - resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} - engines: {node: ^18.19.0 || >=20.5.0} + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} + ajv-errors@3.0.0: + resolution: {integrity: sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==} + peerDependencies: + ajv: ^8.0.1 - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true - express-rate-limit@5.5.1: - resolution: {integrity: sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==} + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true - express-rate-limit@8.2.1: - resolution: {integrity: sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==} - engines: {node: '>= 16'} + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} peerDependencies: - express: '>= 4.11' + ajv: ^8.8.2 - express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - express@4.22.1: - resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} - engines: {node: '>= 0.10.0'} + ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} + ajv@8.13.0: + resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==} - exsolve@1.0.8: - resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true + algoliasearch@5.48.1: + resolution: {integrity: sha512-Rf7xmeuIo7nb6S4mp4abW2faW8DauZyE2faBIKFaUfP3wnpOvNSbiI5AwVhqBNj0jPgBWEvhyCu0sLjN2q77Rg==} + engines: {node: '>= 14.0.0'} - extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} + alien-signals@0.4.14: + resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} - fast-content-type-parse@3.0.0: - resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} + alien-signals@3.1.2: + resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==} - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} + engines: {node: '>=18'} - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true - fast-memoize@2.5.2: - resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} - fast-uri@3.1.0: - resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} - fast-xml-parser@5.3.4: - resolution: {integrity: sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==} - hasBin: true + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} - fault@2.0.1: - resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} - favicons@7.2.0: - resolution: {integrity: sha512-k/2rVBRIRzOeom3wI9jBPaSEvoTSQEW4iM0EveBmBBKFxO8mSyyRWtDlfC3VnEfu0avmjrMzy8/ZFPSe6F71Hw==} - engines: {node: '>=14.0.0'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} - figures@2.0.0: - resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} - engines: {node: '>=4'} + apache-md5@1.1.8: + resolution: {integrity: sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==} + engines: {node: '>=8'} - figures@6.1.0: - resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} - engines: {node: '>=18'} + arch@2.2.0: + resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} - finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} + are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} - finalhandler@1.3.2: - resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} - engines: {node: '>= 0.8'} + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - find-up-simple@1.0.1: - resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} - engines: {node: '>=18'} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - find-up@2.1.0: - resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} - engines: {node: '>=4'} + argv-formatter@1.0.0: + resolution: {integrity: sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==} - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} - find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - find-up@7.0.0: - resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} - engines: {node: '>=18'} + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} - find-versions@6.0.0: - resolution: {integrity: sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==} - engines: {node: '>=18'} + arkregex@0.0.3: + resolution: {integrity: sha512-bU21QJOJEFJK+BPNgv+5bVXkvRxyAvgnon75D92newgHxkBJTgiFwQxusyViYyJkETsddPlHyspshDQcCzmkNg==} - fix-dts-default-cjs-exports@1.0.1: - resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + arkregex@0.0.5: + resolution: {integrity: sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==} - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + arktype@2.1.27: + resolution: {integrity: sha512-enctOHxI4SULBv/TDtCVi5M8oLd4J5SVlPUblXDzSsOYQNMzmVbUosGBnJuZDKmFlN5Ie0/QVEuTE+Z5X1UhsQ==} - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + arktype@2.1.29: + resolution: {integrity: sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ==} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} engines: {node: '>= 0.4'} - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} - forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} - form-data-encoder@1.7.2: - resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} - form-data-encoder@2.1.4: - resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} - engines: {node: '>= 14.17'} + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} - format@0.2.2: - resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} - engines: {node: '>=0.4.x'} + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} + asn1.js@4.10.1: + resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - from2@2.3.0: - resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + asn1js@3.0.7: + resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} + engines: {node: '>=12.0.0'} - front-matter@4.0.2: - resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + assert@2.1.0: + resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} - fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - fs-extra@11.1.0: - resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} - engines: {node: '>=14.14'} + ast-kit@2.2.0: + resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} + engines: {node: '>=20.19.0'} - fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} - fs-extra@11.3.3: - resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} - engines: {node: '>=14.14'} + ast-v8-to-istanbul@0.3.11: + resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==} - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} + ast-walker-scope@0.8.3: + resolution: {integrity: sha512-cbdCP0PGOBq0ASG+sjnKIoYkWMKhhz+F/h9pRexUdX2Hd38+WOlBkRKlqkGOSm0YQpcFMQBJeK4WspUAkwsEdg==} + engines: {node: '>=20.19.0'} - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + async-lock@1.4.1: + resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} - function-timeout@1.0.2: - resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} - engines: {node: '>=18'} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} - gcd@0.0.1: - resolution: {integrity: sha512-VNx3UEGr+ILJTiMs1+xc5SX1cMgJCrXezKPa003APUWNqQqaF6n25W8VcR7nHN6yRWbvvUTwCpZCFJeWC2kXlw==} + auto-bind@5.0.1: + resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - generator-function@2.0.1: - resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + avsc@5.7.9: + resolution: {integrity: sha512-yOA4wFeI7ET3v32Di/sUybQ+ttP20JHSW3mxLuNGeO0uD6PPcvLrIQXSvy/rhJOWU5JrYh7U4OHplWMmtAtjMg==} + engines: {node: '>=0.11'} - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + avvio@9.2.0: + resolution: {integrity: sha512-2t/sy01ArdHHE0vRH5Hsay+RtCZt3dLPji7W7/MMOCEgze5b7SNDC4j5H6FnVgPkI1MTNFGzHdHrVXDDl7QSSQ==} - get-east-asian-width@1.4.0: - resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} - engines: {node: '>=18'} + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} + axe-core@4.11.1: + resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} + engines: {node: '>=4'} - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} + azure-devops-node-api@12.5.0: + resolution: {integrity: sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==} - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + b4a@1.7.3: + resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true - get-stream@7.0.1: - resolution: {integrity: sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==} - engines: {node: '>=16'} + babel-loader@10.0.0: + resolution: {integrity: sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==} + engines: {node: ^18.20.0 || ^20.10.0 || >=22.0.0} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5.61.0' - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} + babel-plugin-polyfill-corejs2@0.4.16: + resolution: {integrity: sha512-xaVwwSfebXf0ooE11BJovZYKhFjIvQo7TsyVpETuIeH2JHv0k/T6Y5j22pPTvqYqmpkxdlPAJlyJ0tfOJAoMxw==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - get-stream@9.0.1: - resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} - engines: {node: '>=18'} + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} + babel-plugin-polyfill-corejs3@0.14.1: + resolution: {integrity: sha512-ENp89vM9Pw4kv/koBb5N2f9bDZsR0hpf3BdPMOg/pkS3pwO4dzNnQZVXtBbeyAadgm865DmQG2jMMLqmZXvuCw==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - get-tsconfig@4.13.1: - resolution: {integrity: sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==} + babel-plugin-polyfill-regenerator@0.6.7: + resolution: {integrity: sha512-OTYbUlSwXhNgr4g6efMZgsO8//jA61P7ZbRX3iTT53VON8l+WQS8IAUEVo4a4cWknrg2W8Cj4gQhRYNCJ8GkAA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - get-uri@6.0.5: - resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} - engines: {node: '>= 14'} + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - git-log-parser@1.2.1: - resolution: {integrity: sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} - git-raw-commits@4.0.0: - resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} - engines: {node: '>=16'} - hasBin: true + bare-events@2.8.2: + resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true - git-up@7.0.0: - resolution: {integrity: sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==} + bare-fs@4.5.3: + resolution: {integrity: sha512-9+kwVx8QYvt3hPWnmb19tPnh38c6Nihz8Lx3t0g9+4GoIf3/fTgYwM4Z6NxgI+B9elLQA7mLE9PpqcWtOMRDiQ==} + engines: {bare: '>=1.16.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true - git-url-parse@13.1.1: - resolution: {integrity: sha512-PCFJyeSSdtnbfhSNRw9Wk96dDCNx+sogTe4YNXeXSJxt7xz5hvXekuRn9JX7m+Mf4OscCu8h+mtAl3+h5Fo8lQ==} + bare-os@3.6.2: + resolution: {integrity: sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==} + engines: {bare: '>=1.14.0'} - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - github-slugger@1.4.0: - resolution: {integrity: sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==} + bare-stream@2.7.0: + resolution: {integrity: sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==} + peerDependencies: + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true - github-slugger@2.0.0: - resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + bare-url@2.3.2: + resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + base64id@2.0.0: + resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} + engines: {node: ^4.5.0 || >= 5.9} - glob@10.5.0: - resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + basic-ftp@5.1.0: + resolution: {integrity: sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==} + engines: {node: '>=10.0.0'} - global-directory@4.0.1: - resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} - engines: {node: '>=18'} + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} - globals-docs@2.4.1: - resolution: {integrity: sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==} + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} + bcryptjs@2.4.3: + resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} + beasties@0.4.1: + resolution: {integrity: sha512-2Imdcw3LznDuxAbJM26RHniOLAzE6WgrK8OuvVXCQtNBS8rsnD9zsSEa3fHl4hHpUY7BYTlrpvtPVbvu9G6neg==} + engines: {node: '>=18.0.0'} - globby@10.0.1: - resolution: {integrity: sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==} - engines: {node: '>=8'} + before-after-hook@4.0.0: + resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} - got-cjs@12.5.4: - resolution: {integrity: sha512-Uas6lAsP8bRCt5WXGMhjFf/qEHTrm4v4qxGR02rLG2kdG9qedctvlkdwXVcDJ7Cs84X+r4dPU7vdwGjCaspXug==} - engines: {node: '>=12'} + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} - got@12.6.1: - resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} - engines: {node: '>=14.16'} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} - got@13.0.0: - resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} - engines: {node: '>=16'} + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - graceful-fs@4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + birpc@4.0.0: + resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} - gunzip-maybe@1.4.2: - resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} - hasBin: true + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} - engines: {node: '>=0.4.7'} - hasBin: true + bn.js@4.12.2: + resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} - happy-dom@20.4.0: - resolution: {integrity: sha512-RDeQm3dT9n0A5f/TszjUmNCLEuPnMGv3Tv4BmNINebz/h17PA6LMBcxJ5FrcqltNBMh9jA/8ufgDdBYUdBt+eg==} - engines: {node: '>=20.0.0'} + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} + body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + bonjour-service@1.3.0: + resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==} - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} - hash-base@3.0.5: - resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} - engines: {node: '>= 0.10'} + boxen@7.0.0: + resolution: {integrity: sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==} + engines: {node: '>=14.16'} - hash-base@3.1.2: - resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} - engines: {node: '>= 0.8'} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - hash.js@1.1.7: - resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + brace-expansion@5.0.4: + resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + engines: {node: 18 || 20 || >=22} - hast-util-embedded@3.0.0: - resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} - hast-util-from-dom@5.0.1: - resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - hast-util-from-html-isomorphic@2.0.0: - resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + browser-resolve@2.0.0: + resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==} - hast-util-from-html@2.0.3: - resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} - hast-util-from-parse5@7.1.2: - resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==} + browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} - hast-util-from-parse5@8.0.3: - resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} - hast-util-has-property@3.0.0: - resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + browserify-rsa@4.1.1: + resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} + engines: {node: '>= 0.10'} - hast-util-is-body-ok-link@3.0.1: - resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + browserify-sign@4.2.5: + resolution: {integrity: sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==} + engines: {node: '>= 0.10'} - hast-util-is-element@3.0.0: - resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + browserify-zlib@0.1.4: + resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} - hast-util-minify-whitespace@1.0.1: - resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - hast-util-parse-selector@3.1.1: - resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true - hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - hast-util-phrasing@3.0.1: - resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} - hast-util-raw@7.2.3: - resolution: {integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==} + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - hast-util-sanitize@4.1.0: - resolution: {integrity: sha512-Hd9tU0ltknMGRDv+d6Ro/4XKzBqQnP/EZrpiTbpFYfXv/uOhWeKc+2uajcbEvAEH98VZd7eII2PiXm13RihnLw==} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - hast-util-to-estree@3.1.3: - resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} - hast-util-to-html@8.0.4: - resolution: {integrity: sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==} + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - hast-util-to-html@9.0.4: - resolution: {integrity: sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - hast-util-to-html@9.0.5: - resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} - hast-util-to-jsx-runtime@2.3.6: - resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + bun-types@1.3.8: + resolution: {integrity: sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q==} - hast-util-to-mdast@10.1.0: - resolution: {integrity: sha512-DsL/SvCK9V7+vfc6SLQ+vKIyBDXTk2KLSbfBYkH4zeF/uR1yBajHRhkzuaUSGOB1WJSTieJBdHwxlC+HLKvZZw==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} - hast-util-to-mdast@10.1.2: - resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' - hast-util-to-parse5@7.1.0: - resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==} + bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} - hast-util-to-string@3.0.1: - resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} - hast-util-to-text@4.0.2: - resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} - hast-util-whitespace@2.0.1: - resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} + c12@3.3.3: + resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true - hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} - hastscript@7.2.0: - resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} + cacache@20.0.3: + resolution: {integrity: sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==} + engines: {node: ^20.17.0 || >=22.9.0} - hastscript@9.0.1: - resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + cacheable-lookup@6.1.0: + resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} + engines: {node: '>=10.6.0'} - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} - hermes-estree@0.25.1: - resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} - hermes-parser@0.25.1: - resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + cacheable-request@7.0.2: + resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} + engines: {node: '>=8'} - hex-rgb@5.0.0: - resolution: {integrity: sha512-NQO+lgVUCtHxZ792FodgW0zflK+ozS9X9dwGp9XvvmPlH7pyxd588cn24TD3rmPm/N0AIRXF10Otah8yKqGw4w==} - engines: {node: '>=12'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} - highlight.js@10.7.3: - resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} - highlight.js@11.11.1: - resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} - engines: {node: '>=12.0.0'} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} - hmac-drbg@1.0.1: - resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} - hono@4.12.1: - resolution: {integrity: sha512-hi9afu8g0lfJVLolxElAZGANCTTl6bewIdsRNhaywfP9K8BPf++F2z6OLrYGIinUwpRKzbZHMhPwvc0ZEpAwGw==} - engines: {node: '>=16.9.0'} + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} - hook-std@4.0.0: - resolution: {integrity: sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==} - engines: {node: '>=20'} + camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} - hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} + caniuse-lite@1.0.30001767: + resolution: {integrity: sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==} - hosted-git-info@7.0.2: - resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} - engines: {node: ^16.14.0 || >=18.0.0} + caniuse-lite@1.0.30001777: + resolution: {integrity: sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==} - hosted-git-info@8.1.0: - resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} - engines: {node: ^18.17.0 || >=20.5.0} + canvas@3.2.1: + resolution: {integrity: sha512-ej1sPFR5+0YWtaVp6S1N1FVz69TQCqmrkGeRvQxZeAB1nAIcjNTHVwrZtYtWFFBmQsF40/uDLehsW5KuYC99mg==} + engines: {node: ^18.12.0 || >= 20.9.0} - html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + chalk-template@0.4.0: + resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==} + engines: {node: '>=12'} - html-void-elements@2.0.1: - resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} - html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} - htmlparser2@10.1.0: - resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + chalk@5.0.1: + resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + chalk@5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} - http-signature@1.4.0: - resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==} - engines: {node: '>=0.10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - http-status-codes@2.3.0: - resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - http2-wrapper@2.2.1: - resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} - engines: {node: '>=10.19.0'} + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - https-browserify@1.0.0: - resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} + engines: {node: '>=20.18.1'} - human-signals@8.0.1: - resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} - engines: {node: '>=18.18.0'} + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} - ico-endec@0.1.6: - resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} - iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} - ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} + chromium-bidi@0.6.2: + resolution: {integrity: sha512-4WVBa6ijmUTVr9cZD4eicQD8Mdy/HCX3bzEIYYpmk0glqYLoWH+LqQEvV9RpDRzoQSbY1KJHloYXbDMXMbDPhg==} + peerDependencies: + devtools-protocol: '*' - immediate@3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + engines: {node: '>= 0.10'} - immer@9.0.21: - resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + citty@0.2.1: + resolution: {integrity: sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} - import-from-esm@2.0.0: - resolution: {integrity: sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==} - engines: {node: '>=18.20'} + clean-stack@4.2.0: + resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} + engines: {node: '>=12'} - import-lazy@4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} + clean-stack@5.3.0: + resolution: {integrity: sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==} + engines: {node: '>=14.16'} - import-meta-resolve@4.2.0: - resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} - indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true - index-to-position@1.2.0: - resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} - engines: {node: '>=18'} + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + cli-spinners@3.4.0: + resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} + engines: {node: '>=18.20'} - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} - ini@3.0.1: - resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} + engines: {node: '>=20'} - ini@4.1.1: - resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} - ink-spinner@5.0.0: - resolution: {integrity: sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA==} - engines: {node: '>=14.16'} - peerDependencies: - ink: '>=4.0.0' - react: '>=18.0.0' + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - ink@6.3.0: - resolution: {integrity: sha512-2CbJAa7XeziZYe6pDS5RVLirRY28iSGMQuEV8jRU5NQsONQNfcR/BZHHc9vkMg2lGYTHTM2pskxC1YmY28p6bQ==} - engines: {node: '>=20'} + clipanion@4.0.0-rc.4: + resolution: {integrity: sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q==} peerDependencies: - '@types/react': '>=19.0.0' - react: '>=19.0.0' - react-devtools-core: ^4.19.1 - peerDependenciesMeta: - '@types/react': - optional: true - react-devtools-core: - optional: true + typanion: '*' - inline-style-parser@0.2.7: - resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + clipboardy@3.0.0: + resolution: {integrity: sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - inquirer@12.3.0: - resolution: {integrity: sha512-3NixUXq+hM8ezj2wc7wC37b32/rHq1MwNZDYdvx+d6jokOD+r+i8Q4Pkylh9tISYP114A128LCX8RKhopC5RfQ==} + clipboardy@4.0.0: + resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - into-stream@7.0.0: - resolution: {integrity: sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} - ip-address@10.0.1: - resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} - engines: {node: '>= 12'} - - ip-address@10.1.0: - resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} - engines: {node: '>= 12'} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} - ip-regex@4.3.0: - resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==} - engines: {node: '>=8'} + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} - is-absolute@1.0.0: - resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} - is-alphabetical@2.0.1: - resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + cockatiel@3.2.1: + resolution: {integrity: sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==} + engines: {node: '>=16'} - is-alphanumerical@2.0.1: - resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + code-excerpt@4.0.0: + resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-arguments@1.2.0: - resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} - engines: {node: '>= 0.4'} + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} + color-blend@4.0.0: + resolution: {integrity: sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw==} + engines: {node: '>=10.0.0'} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - is-arrayish@0.3.4: - resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} + color2k@2.0.3: + resolution: {integrity: sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==} - is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} - is-bun-module@2.0.0: - resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} + colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - is-decimal@2.0.1: - resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} - is-deflate@1.0.0: - resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} - is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} + comment-parser@1.4.5: + resolution: {integrity: sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==} + engines: {node: '>= 12.0.0'} - is-fullwidth-code-point@5.1.0: - resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} - engines: {node: '>=18'} + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - is-generator-function@1.1.2: - resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} - engines: {node: '>= 0.4'} + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + compare-versions@6.1.1: + resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - is-gzip@1.0.0: - resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} - engines: {node: '>=0.10.0'} + compatx@0.2.0: + resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} - is-hexadecimal@2.0.1: - resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} - is-in-ci@2.0.0: - resolution: {integrity: sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==} - engines: {node: '>=20'} - hasBin: true + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concurrently@9.2.1: + resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} + engines: {node: '>=18'} hasBin: true - is-ip@3.1.0: - resolution: {integrity: sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==} - engines: {node: '>=8'} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} - is-nan@1.3.2: - resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} - engines: {node: '>= 0.4'} + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} - is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} + console-browserify@1.2.0: + resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} - is-online@10.0.0: - resolution: {integrity: sha512-WCPdKwNDjXJJmUubf2VHLMDBkUZEtuOvpXUfUnUFbEnM6In9ByiScL4f4jKACz/fsb2qDkesFerW3snf/AYz3A==} - engines: {node: '>=14.16'} + constants-browserify@1.0.0: + resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} - is-path-cwd@2.2.0: - resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} - engines: {node: '>=6'} + content-disposition@0.5.2: + resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} + engines: {node: '>= 0.6'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} - is-plain-object@3.0.1: - resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} - engines: {node: '>=0.10.0'} + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} - is-port-reachable@4.0.0: - resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + conventional-changelog-angular@8.1.0: + resolution: {integrity: sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==} + engines: {node: '>=18'} - is-promise@2.2.2: - resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + conventional-changelog-conventionalcommits@7.0.2: + resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} + engines: {node: '>=16'} - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + conventional-changelog-writer@8.2.0: + resolution: {integrity: sha512-Y2aW4596l9AEvFJRwFGJGiQjt2sBYTjPD18DdvxX9Vpz0Z7HQ+g1Z+6iYDAm1vR3QOJrDBkRHixHK/+FhkR6Pw==} + engines: {node: '>=18'} + hasBin: true - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} + conventional-commits-filter@5.0.0: + resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} + engines: {node: '>=18'} - is-relative@1.0.0: - resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} - engines: {node: '>=0.10.0'} + conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} + engines: {node: '>=16'} + hasBin: true - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} + conventional-commits-parser@6.2.1: + resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} + engines: {node: '>=18'} + hasBin: true - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} + convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} - is-ssh@1.4.1: - resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + convert-to-spaces@2.0.1: + resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-stream@4.0.1: - resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} - engines: {node: '>=18'} + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} + cookie-es@2.0.0: + resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - is-text-path@2.0.0: - resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} - engines: {node: '>=8'} + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} - is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} - is-unc-path@1.0.0: - resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} - engines: {node: '>=0.10.0'} + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} + copy-anything@2.0.6: + resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} + copy-paste@2.2.0: + resolution: {integrity: sha512-jqSL4r9DSeiIvJZStLzY/sMLt9ToTM7RsK237lYOTG+KcbQJHGala3R1TUpa8h1p9adswVgIdV4qGbseVhL4lg==} - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} + copy-webpack-plugin@14.0.0: + resolution: {integrity: sha512-3JLW90aBGeaTLpM7mYQKpnVdgsUZRExY55giiZgLuX/xTQRUs1dOCwbBnWnvY6Q6rfZoXMNwzOQJCSZPppfqXA==} + engines: {node: '>= 20.9.0'} + peerDependencies: + webpack: ^5.1.0 - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} + core-js-compat@3.48.0: + resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} - engines: {node: '>=16'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + cosmiconfig-typescript-loader@6.2.0: + resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==} + engines: {node: '>=v18'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=9' + typescript: '>=5' - isomorphic-timers-promises@1.0.1: - resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==} - engines: {node: '>=10'} + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true - isomorphic.js@0.2.5: - resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true - isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} - issue-parser@7.0.1: - resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} - engines: {node: ^18.17 || >=20.6.1} + create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} - istanbul-lib-source-maps@5.0.6: - resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} - engines: {node: '>=10'} + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} + croner@9.1.0: + resolution: {integrity: sha512-p9nwwR4qyT5W996vBZhdvBCnMhicY5ytZkR4D1Xj0wuTDEiMnjwR57Q3RXYY/s0EpX6Ay3vgIcfaR+ewGHsi+g==} + engines: {node: '>=18.0'} - iterator.prototype@1.1.5: - resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} - engines: {node: '>= 0.4'} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - java-properties@1.0.2: - resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==} - engines: {node: '>= 0.6.0'} + crypto-browserify@3.12.1: + resolution: {integrity: sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==} + engines: {node: '>= 0.10'} - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true + crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} - jju@1.4.0: - resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + css-declaration-sorter@7.3.1: + resolution: {integrity: sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 - jose@6.1.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + css-loader@7.1.3: + resolution: {integrity: sha512-frbERmjT0UC5lMheWpJmMilnt9GEhbZJN/heUb7/zaJYeIzj5St9HvDcfshzzOqbsS+rYpMk++2SD3vGETDSyA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.27.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} + css-render@0.15.14: + resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==} - js-beautify@1.15.4: - resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} - engines: {node: '>=14'} - hasBin: true + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - js-cookie@3.0.5: - resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} - engines: {node: '>=14'} + css-select@6.0.0: + resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==} - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} - js-yaml@3.14.2: - resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} - hasBin: true + css-what@7.0.0: + resolution: {integrity: sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==} + engines: {node: '>= 6'} - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} hasBin: true - jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - - jsdoc-type-pratt-parser@5.1.1: - resolution: {integrity: sha512-DYYlVP1fe4QBMh2xTIs20/YeTz2GYVbWAEZweHSZD+qQ/Cx2d5RShuhhsdk64eTjNq0FeVnteP/qVOgaywSRbg==} - engines: {node: '>=12.0.0'} + cssnano-preset-default@7.0.11: + resolution: {integrity: sha512-waWlAMuCakP7//UCY+JPrQS1z0OSLeOXk2sKWJximKWGupVxre50bzPlvpbUwZIDylhf/ptf0Pk+Yf7C+hoa3g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 - jsdom@27.3.0: - resolution: {integrity: sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + cssnano-utils@5.0.1: + resolution: {integrity: sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: - canvas: 3.2.1 - peerDependenciesMeta: - canvas: - optional: true + postcss: ^8.4.32 - jsep@1.4.0: - resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} - engines: {node: '>= 10.16.0'} + cssnano@7.1.3: + resolution: {integrity: sha512-mLFHQAzyapMVFLiJIn7Ef4C2UCEvtlTlbyILR6B5ZsUAV3D/Pa761R5uC1YPhyBkRd3eqaDm2ncaNrD7R4mTRg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + cssstyle@5.3.7: + resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==} + engines: {node: '>=20'} - json-parse-better-errors@1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + csstype@3.0.11: + resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} - json-schema-typed@8.0.2: - resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + data-urls@6.0.1: + resolution: {integrity: sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==} + engines: {node: '>=20'} - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} - jsonc-parser@2.2.1: - resolution: {integrity: sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==} + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + date-fns-tz@3.2.0: + resolution: {integrity: sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==} + peerDependencies: + date-fns: ^3.0.0 || ^4.0.0 - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} - jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} - jsonpath-plus@10.3.0: - resolution: {integrity: sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==} - engines: {node: '>=18.0.0'} - hasBin: true + db0@0.3.4: + resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + better-sqlite3: '*' + drizzle-orm: '*' + mysql2: '*' + sqlite3: '*' + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + better-sqlite3: + optional: true + drizzle-orm: + optional: true + mysql2: + optional: true + sqlite3: + optional: true - jsonpointer@5.0.1: - resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} - engines: {node: '>=0.10.0'} + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - jsonwebtoken@9.0.3: - resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} - engines: {node: '>=12', npm: '>=6'} + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true - jsprim@2.0.2: - resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} - engines: {'0': node >=0.6.0} + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true - jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true - jszip@3.10.1: - resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true - jwa@2.0.1: - resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true - jws@4.0.1: - resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} - katex@0.16.28: - resolution: {integrity: sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==} - hasBin: true + decode-bmp@0.2.1: + resolution: {integrity: sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==} + engines: {node: '>=8.6.0'} - keytar@7.9.0: - resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} + decode-ico@0.4.1: + resolution: {integrity: sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==} + engines: {node: '>=8.6'} - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} - konan@2.1.1: - resolution: {integrity: sha512-7ZhYV84UzJ0PR/RJnnsMZcAbn+kLasJhVNWsu8ZyVEJYRpGA5XESQ9d/7zOa08U0Ou4cmB++hMNY/3OSV9KIbg==} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - konva@10.2.0: - resolution: {integrity: sha512-JBoz0Xjbf49UPxCZegZ4WseqOzJ+C4AUDOtJ9eBve5RS5Fcq/u8TdBD5fDl/uPFInpC3a9uycm0sRyZpF4hheg==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} - lcm@0.0.3: - resolution: {integrity: sha512-TB+ZjoillV6B26Vspf9l2L/vKaRY/4ep3hahcyVkCGFgsTNRUQdc24bQeNFiZeoxH0vr5+7SfNRMQuPHv/1IrQ==} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} - lefthook-darwin-arm64@1.13.6: - resolution: {integrity: sha512-m6Lb77VGc84/Qo21Lhq576pEvcgFCnvloEiP02HbAHcIXD0RTLy9u2yAInrixqZeaz13HYtdDaI7OBYAAdVt8A==} - cpu: [arm64] - os: [darwin] + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} - lefthook-darwin-x64@1.13.6: - resolution: {integrity: sha512-CoRpdzanu9RK3oXR1vbEJA5LN7iB+c7hP+sONeQJzoOXuq4PNKVtEaN84Gl1BrVtCNLHWFAvCQaZPPiiXSy8qg==} - cpu: [x64] - os: [darwin] + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} - lefthook-freebsd-arm64@1.13.6: - resolution: {integrity: sha512-X4A7yfvAJ68CoHTqP+XvQzdKbyd935sYy0bQT6Ajz7FL1g7hFiro8dqHSdPdkwei9hs8hXeV7feyTXbYmfjKQQ==} - cpu: [arm64] - os: [freebsd] + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} - lefthook-freebsd-x64@1.13.6: - resolution: {integrity: sha512-ai2m+Sj2kGdY46USfBrCqLKe9GYhzeq01nuyDYCrdGISePeZ6udOlD1k3lQKJGQCHb0bRz4St0r5nKDSh1x/2A==} - cpu: [x64] - os: [freebsd] + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} - lefthook-linux-arm64@1.13.6: - resolution: {integrity: sha512-cbo4Wtdq81GTABvikLORJsAWPKAJXE8Q5RXsICFUVznh5PHigS9dFW/4NXywo0+jfFPCT6SYds2zz4tCx6DA0Q==} - cpu: [arm64] - os: [linux] + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} - lefthook-linux-x64@1.13.6: - resolution: {integrity: sha512-uJl9vjCIIBTBvMZkemxCE+3zrZHlRO7Oc+nZJ+o9Oea3fu+W82jwX7a7clw8jqNfaeBS+8+ZEQgiMHWCloTsGw==} - cpu: [x64] - os: [linux] + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} - lefthook-openbsd-arm64@1.13.6: - resolution: {integrity: sha512-7r153dxrNRQ9ytRs2PmGKKkYdvZYFPre7My7XToSTiRu5jNCq++++eAKVkoyWPduk97dGIA+YWiEr5Noe0TK2A==} - cpu: [arm64] - os: [openbsd] + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - lefthook-openbsd-x64@1.13.6: - resolution: {integrity: sha512-Z+UhLlcg1xrXOidK3aLLpgH7KrwNyWYE3yb7ITYnzJSEV8qXnePtVu8lvMBHs/myzemjBzeIr/U/+ipjclR06g==} - cpu: [x64] - os: [openbsd] + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} - lefthook-windows-arm64@1.13.6: - resolution: {integrity: sha512-Uxef6qoDxCmUNQwk8eBvddYJKSBFglfwAY9Y9+NnnmiHpWTjjYiObE9gT2mvGVpEgZRJVAatBXc+Ha5oDD/OgQ==} - cpu: [arm64] - os: [win32] + del@6.1.1: + resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} + engines: {node: '>=10'} - lefthook-windows-x64@1.13.6: - resolution: {integrity: sha512-mOZoM3FQh3o08M8PQ/b3IYuL5oo36D9ehczIw1dAgp1Ly+Tr4fJ96A+4SEJrQuYeRD4mex9bR7Ps56I73sBSZA==} - cpu: [x64] - os: [win32] + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} - lefthook@1.13.6: - resolution: {integrity: sha512-ojj4/4IJ29Xn4drd5emqVgilegAPN3Kf0FQM2p/9+lwSTpU+SZ1v4Ig++NF+9MOa99UKY8bElmVrLhnUUNFh5g==} - hasBin: true + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} - leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} - leven@4.1.0: - resolution: {integrity: sha512-KZ9W9nWDT7rF7Dazg8xyLHGLrmpgq2nVNFUckhqdW3szVP6YhCpp/RAnpmVExA9JvrMynjwSLVrEj3AepHR6ew==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + dependency-graph@0.11.0: + resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} + engines: {node: '>= 0.6.0'} - lib0@0.2.117: - resolution: {integrity: sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw==} - engines: {node: '>=16'} - hasBin: true + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} - lie@3.3.0: - resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} - lightningcss-android-arm64@1.31.1: - resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - lightningcss-darwin-arm64@1.31.1: - resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - lightningcss-darwin-x64@1.31.1: - resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} - lightningcss-freebsd-x64@1.31.1: - resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - lightningcss-linux-arm-gnueabihf@1.31.1: - resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - lightningcss-linux-arm64-gnu@1.31.1: - resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] + detect-port@1.5.1: + resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} + hasBin: true - lightningcss-linux-arm64-musl@1.31.1: - resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] + devalue@5.6.3: + resolution: {integrity: sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==} - lightningcss-linux-x64-gnu@1.31.1: - resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - lightningcss-linux-x64-musl@1.31.1: - resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] + devtools-protocol@0.0.1312386: + resolution: {integrity: sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==} - lightningcss-win32-arm64-msvc@1.31.1: - resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - lightningcss-win32-x64-msvc@1.31.1: - resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] + diff@5.2.2: + resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==} + engines: {node: '>=0.3.1'} - lightningcss@1.31.1: - resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} - engines: {node: '>= 12.0.0'} + diff@8.0.3: + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} + engines: {node: '>=0.3.1'} - lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} + diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - linkify-it@3.0.3: - resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} - load-json-file@4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} + dns-socket@4.2.2: + resolution: {integrity: sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==} + engines: {node: '>=6'} - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + doctrine-temporary-fork@2.1.0: + resolution: {integrity: sha512-nliqOv5NkE4zMON4UA6AMJE6As35afs8aYXATpU4pTUdIKiARZwrJVEP1boA3Rx1ZXHVkwxkhcq4VkqvsuRLsA==} + engines: {node: '>=0.10.0'} - local-pkg@1.1.2: - resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + documentation@14.0.3: + resolution: {integrity: sha512-B7cAviVKN9Rw7Ofd+9grhVuxiHwly6Ieh+d/ceMw8UdBOv/irkuwnDEJP8tq0wgdLJDUVuIkovV+AX9mTrZFxg==} engines: {node: '>=14'} + hasBin: true - locate-path@2.0.0: - resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} - engines: {node: '>=4'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - lockfile@1.0.4: - resolution: {integrity: sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==} + domain-browser@4.22.0: + resolution: {integrity: sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==} + engines: {node: '>=10'} - lodash-es@4.17.23: - resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} - lodash.capitalize@4.2.1: - resolution: {integrity: sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - lodash.escaperegexp@4.1.2: - resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + dot-prop@10.1.0: + resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} + engines: {node: '>=20'} - lodash.includes@4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} - lodash.isboolean@3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} - lodash.isinteger@4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} + engines: {node: '>=12'} - lodash.isnumber@3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} - lodash.isstring@4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - lodash.kebabcase@4.1.1: - resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - lodash.mergewith@4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - lodash.snakecase@4.1.1: - resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + editorconfig@1.0.4: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} + engines: {node: '>=14'} + hasBin: true - lodash.topath@4.5.2: - resolution: {integrity: sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - lodash.uniq@4.5.0: - resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + electron-to-chromium@1.5.286: + resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} - lodash.uniqby@4.7.0: - resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==} + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} - lodash.upperfirst@4.3.1: - resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - lodash@4.17.23: - resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - longest-streak@3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} - loupe@3.2.1: - resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} - lowdb@1.0.0: - resolution: {integrity: sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==} - engines: {node: '>=4'} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} - lowercase-keys@2.0.0: - resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} - engines: {node: '>=8'} + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} - lowercase-keys@3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} - lru-cache@11.2.5: - resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} - engines: {node: 20 || >=22} + engine.io@6.5.5: + resolution: {integrity: sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==} + engines: {node: '>=10.2.0'} - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + enhanced-resolve@5.20.0: + resolution: {integrity: sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==} + engines: {node: '>=10.13.0'} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + entities@2.1.0: + resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} - lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} - hasBin: true + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} - magicast@0.3.5: - resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + env-ci@11.2.0: + resolution: {integrity: sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==} + engines: {node: ^18.17 || >=20.6.1} - make-asynchronous@1.0.1: - resolution: {integrity: sha512-T9BPOmEOhp6SmV25SwLVcHK4E6JyG/coH3C6F1NjNXSziv/fd4GmsqMk8YR6qpPOswfaOCApSNkZv6fxoaYFcQ==} - engines: {node: '>=18'} + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + envinfo@7.15.0: + resolution: {integrity: sha512-chR+t7exF6y59kelhXw5I3849nTy7KIRO+ePdLMhCD+JRP/JvmkenDWP7QSFGlsHX+kxGxdDutOPrmj5j1HR6g==} + engines: {node: '>=4'} + hasBin: true - map-cache@0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} - markdown-extensions@2.0.0: - resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} - engines: {node: '>=16'} + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - markdown-it@12.3.2: - resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true - markdown-table@3.0.4: - resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - marked-terminal@7.3.0: - resolution: {integrity: sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==} - engines: {node: '>=16.0.0'} - peerDependencies: - marked: '>=1 <16' + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - marked@15.0.12: - resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} - engines: {node: '>= 18'} - hasBin: true + errx@0.1.0: + resolution: {integrity: sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + es-abstract@1.24.1: + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} engines: {node: '>= 0.4'} - md5.js@1.3.5: - resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} - - mdast-util-definitions@5.1.2: - resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} - - mdast-util-find-and-replace@2.2.2: - resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==} + es-aggregate-error@1.0.14: + resolution: {integrity: sha512-3YxX6rVb07B5TV11AV5wsL7nQCHXNwoHPsQC8S4AmBiqYhyNCJ5BRKXkXyDJvs8QzXN20NgRtxe3dEEQD9NLHA==} + engines: {node: '>= 0.4'} - mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} - mdast-util-from-markdown@1.3.1: - resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} - mdast-util-from-markdown@2.0.2: - resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + es-iterator-helpers@1.2.2: + resolution: {integrity: sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==} + engines: {node: '>= 0.4'} - mdast-util-frontmatter@2.0.1: - resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - mdast-util-gfm-autolink-literal@1.0.3: - resolution: {integrity: sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==} + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} - mdast-util-gfm-footnote@1.0.2: - resolution: {integrity: sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} - mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} - mdast-util-gfm-strikethrough@1.0.3: - resolution: {integrity: sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==} + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} - mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + es-toolkit@1.44.0: + resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==} - mdast-util-gfm-table@1.0.7: - resolution: {integrity: sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==} + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} - mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} - mdast-util-gfm-task-list-item@1.0.2: - resolution: {integrity: sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==} + esbuild-wasm@0.27.3: + resolution: {integrity: sha512-AUXuOxZ145/5Az+lIqk6TdJbxKTyDGkXMJpTExmBdbnHR6n6qAFx+F4oG9ORpVYJ9dQYeQAqzv51TO4DFKsbXw==} + engines: {node: '>=18'} + hasBin: true - mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true - mdast-util-gfm@2.0.2: - resolution: {integrity: sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==} + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true - mdast-util-gfm@3.0.0: - resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true - mdast-util-gfm@3.1.0: - resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} - mdast-util-inject@1.1.0: - resolution: {integrity: sha512-CcJ0mHa36QYumDKiZ2OIR+ClhfOM7zIzN+Wfy8tRZ1hpH9DKLCS+Mh4DyK5bCxzE9uxMWcbIpeNFWsg1zrj/2g==} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - mdast-util-math@3.0.0: - resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} - mdast-util-mdx-expression@2.0.1: - resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} - mdast-util-mdx-jsx@3.1.3: - resolution: {integrity: sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==} + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} - mdast-util-mdx-jsx@3.2.0: - resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} - mdast-util-mdx@3.0.0: - resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true - mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + eslint-config-next@16.1.6: + resolution: {integrity: sha512-vKq40io2B0XtkkNDYyleATwblNt8xuh3FWp8SpSz3pt7P01OkBFlKsJZ2mWt5WsCySlDQLckb1zMY9yE9Qy0LA==} + peerDependencies: + eslint: '>=9.0.0' + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true - mdast-util-phrasing@3.0.1: - resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==} + eslint-config-prettier@9.1.2: + resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' - mdast-util-phrasing@4.1.0: - resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + eslint-import-context@0.1.9: + resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true - mdast-util-to-hast@12.3.0: - resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - mdast-util-to-hast@13.2.1: - resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true - mdast-util-to-markdown@1.5.0: - resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} + eslint-import-resolver-typescript@4.4.4: + resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} + engines: {node: ^16.17.0 || >=18.6.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true - mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true - mdast-util-to-string@1.1.0: - resolution: {integrity: sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==} + eslint-plugin-import-x@4.16.1: + resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/utils': ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + eslint-import-resolver-node: '*' + peerDependenciesMeta: + '@typescript-eslint/utils': + optional: true + eslint-import-resolver-node: + optional: true - mdast-util-to-string@3.2.0: - resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true - mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + eslint-plugin-jsdoc@54.7.0: + resolution: {integrity: sha512-u5Na4he2+6kY1rWqxzbQaAwJL3/tDCuT5ElDRc5UJ9stOeQeQ5L1JJ1kRRu7ldYMlOHMCJLsY8Mg/Tu3ExdZiQ==} + engines: {node: '>=20.11.0'} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - mdast-util-toc@6.1.1: - resolution: {integrity: sha512-Er21728Kow8hehecK2GZtb7Ny3omcoPUVrmObiSUwmoRYVZaXLR751QROEFjR8W/vAQdHMLj49Lz20J55XaNpw==} + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - mdn-data@2.12.2: - resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - mdurl@1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - meow@12.1.1: - resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} - engines: {node: '>=16.10'} + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - meow@13.2.0: - resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} - engines: {node: '>=18'} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true - merge-descriptors@1.0.3: - resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} - methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} - micromark-core-commonmark@1.1.0: - resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} - micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} - micromark-extension-frontmatter@2.0.0: - resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} - micromark-extension-gfm-autolink-literal@1.0.5: - resolution: {integrity: sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==} + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} - micromark-extension-gfm-footnote@1.1.2: - resolution: {integrity: sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==} + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} - micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} - micromark-extension-gfm-strikethrough@1.0.7: - resolution: {integrity: sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - micromark-extension-gfm-table@1.0.7: - resolution: {integrity: sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==} + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} - micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} - micromark-extension-gfm-tagfilter@1.0.2: - resolution: {integrity: sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==} + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} - micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - micromark-extension-gfm-task-list-item@1.0.5: - resolution: {integrity: sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} - micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} - micromark-extension-gfm@2.0.3: - resolution: {integrity: sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} - micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} - micromark-extension-math@3.1.0: - resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} - micromark-extension-mdx-expression@3.0.1: - resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} - micromark-extension-mdx-jsx@3.0.1: - resolution: {integrity: sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==} + evtd@0.2.4: + resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} - micromark-extension-mdx-md@2.0.0: - resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} - micromark-extension-mdxjs-esm@3.0.0: - resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} - micromark-extension-mdxjs@3.0.0: - resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} - micromark-factory-destination@1.1.0: - resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} - micromark-factory-destination@2.0.1: - resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} - micromark-factory-label@1.1.0: - resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} - micromark-factory-label@2.0.1: - resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + express-rate-limit@5.5.1: + resolution: {integrity: sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==} - micromark-factory-mdx-expression@2.0.3: - resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + express-rate-limit@8.2.1: + resolution: {integrity: sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' - micromark-factory-space@1.1.0: - resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} - micromark-factory-space@2.0.1: - resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} - micromark-factory-title@1.1.0: - resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} - micromark-factory-title@2.0.1: - resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} - micromark-factory-whitespace@1.1.0: - resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true - micromark-util-character@1.2.0: - resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} - micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + fast-content-type-parse@3.0.0: + resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} - micromark-util-chunked@1.1.0: - resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} - micromark-util-chunked@2.0.1: - resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - micromark-util-classify-character@1.1.0: - resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - micromark-util-classify-character@2.0.1: - resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} - micromark-util-combine-extensions@1.1.0: - resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} - micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - micromark-util-decode-numeric-character-reference@1.1.0: - resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + fast-json-stringify@6.3.0: + resolution: {integrity: sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA==} - micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - micromark-util-decode-string@1.1.0: - resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + fast-memoize@2.5.2: + resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} - micromark-util-decode-string@2.0.1: - resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + fast-npm-meta@1.4.2: + resolution: {integrity: sha512-XXyd9d3ie/JeIIjm6WeKalvapGGFI4ShAjPJM78vgUFYzoEsuNSjvvVTuht0XZcwbVdOnEEGzhxwguRbxkIcDg==} + hasBin: true - micromark-util-encode@1.1.0: - resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} - micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + fast-sha256@1.3.0: + resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} - micromark-util-events-to-acorn@2.0.3: - resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - micromark-util-html-tag-name@1.2.0: - resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + fast-xml-parser@5.3.4: + resolution: {integrity: sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==} + hasBin: true - micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + fastify-plugin@5.1.0: + resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} - micromark-util-normalize-identifier@1.1.0: - resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + fastify@5.8.2: + resolution: {integrity: sha512-lZmt3navvZG915IE+f7/TIVamxIwmBd+OMB+O9WBzcpIwOo6F0LTh0sluoMFk5VkrKTvvrwIaoJPkir4Z+jtAg==} - micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - micromark-util-resolve-all@1.1.0: - resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} - micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + favicons@7.2.0: + resolution: {integrity: sha512-k/2rVBRIRzOeom3wI9jBPaSEvoTSQEW4iM0EveBmBBKFxO8mSyyRWtDlfC3VnEfu0avmjrMzy8/ZFPSe6F71Hw==} + engines: {node: '>=14.0.0'} - micromark-util-sanitize-uri@1.2.0: - resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} - micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - micromark-util-subtokenize@1.1.0: - resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true - micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} - micromark-util-symbol@1.1.0: - resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} - micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} - micromark-util-types@1.1.0: - resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} - micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - micromark@3.2.0: - resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} - micromark@4.0.2: - resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} - miller-rabin@4.0.1: - resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} - hasBin: true + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} - mime-db@1.33.0: - resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} - engines: {node: '>= 0.6'} + find-my-way@9.5.0: + resolution: {integrity: sha512-VW2RfnmscZO5KgBY5XVyKREMW5nMZcxDy+buTOsL+zIPnBlbKm+00sgzoQzq1EVh4aALZLfKdwv6atBGcjvjrQ==} + engines: {node: '>=20'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} - mime-types@2.1.18: - resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} - engines: {node: '>= 0.6'} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} engines: {node: '>=18'} - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true + find-versions@6.0.0: + resolution: {integrity: sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==} + engines: {node: '>=18'} - mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} - mime@4.1.0: - resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true - mimic-response@1.0.1: - resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} - engines: {node: '>=4'} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} - mimic-response@4.0.0: - resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} + form-data-encoder@1.7.2: + resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} - minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} - minimalistic-crypto-utils@1.0.1: - resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} - minimatch@10.0.3: - resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} - engines: {node: 20 || >=22} + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} - minimatch@10.1.2: - resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} - engines: {node: 20 || >=22} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - minimatch@7.4.6: - resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} - engines: {node: '>=10'} + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} - minimatch@9.0.1: - resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} - engines: {node: '>=16 || 14 >=14.17'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} + from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + front-matter@4.0.2: + resolution: {integrity: sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==} - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - mintlify@4.2.331: - resolution: {integrity: sha512-57mLAnYuZ9EEpTT84NAgUOFK7SSEM0cuO1J+NxNfywJi/RL+JmDijd9Tv74QHOEUhPwHjKPzOkhYR82vMqIdvw==} - engines: {node: '>=18.0.0'} - hasBin: true + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} - mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + fs-extra@11.1.0: + resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} + engines: {node: '>=14.14'} - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} - mlly@1.8.0: - resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + fs-extra@11.3.3: + resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + engines: {node: '>=14.14'} - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] - mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] - mute-stream@2.0.0: - resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} - engines: {node: ^18.17.0 || >=20.5.0} + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + function-timeout@1.0.2: + resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} + engines: {node: '>=18'} - naive-ui@2.43.2: - resolution: {integrity: sha512-YlLMnGrwGTOc+zMj90sG3ubaH5/7czsgLgGcjTLA981IUaz8r6t4WIujNt8r9PNr+dqv6XNEr0vxkARgPPjfBQ==} - peerDependencies: - vue: 3.5.25 + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + fuse.js@7.1.0: + resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} + engines: {node: '>=10'} - napi-postinstall@0.3.4: - resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - hasBin: true + fzf@0.5.2: + resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==} - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + gcd@0.0.1: + resolution: {integrity: sha512-VNx3UEGr+ILJTiMs1+xc5SX1cMgJCrXezKPa003APUWNqQqaF6n25W8VcR7nHN6yRWbvvUTwCpZCFJeWC2kXlw==} - negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} - negotiator@0.6.4: - resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} - engines: {node: '>= 0.6'} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} - neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + engines: {node: '>=18'} - neotraverse@0.6.18: - resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} - engines: {node: '>= 10'} + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} - nerf-dart@1.0.0: - resolution: {integrity: sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} - netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} - next-mdx-remote-client@1.1.4: - resolution: {integrity: sha512-psCMdO50tfoT1kAH7OGXZvhyRfiHVK6IqwjmWFV5gtLo4dnqjAgcjcLNeJ92iI26UNlKShxYrBs1GQ6UXxk97A==} - engines: {node: '>=18.18.0'} - peerDependencies: - react: '>= 18.3.0 < 19.0.0' - react-dom: '>= 18.3.0 < 19.0.0' + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} - nimma@0.2.3: - resolution: {integrity: sha512-1ZOI8J+1PKKGceo/5CT5GfQOG6H8I2BencSK06YarZ2wXwH37BSSUWldqJmMJYA5JfqDqffxDXynt6f11AyKcA==} - engines: {node: ^12.20 || >=14.13} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} - nlcst-to-string@4.0.0: - resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} - node-abi@3.87.0: - resolution: {integrity: sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==} + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - node-addon-api@4.3.0: - resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} - - node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + get-stream@7.0.1: + resolution: {integrity: sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==} + engines: {node: '>=16'} - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} - node-emoji@2.2.0: - resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} - node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} - node-readable-to-web-readable-stream@0.4.2: - resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==} + get-tsconfig@4.13.1: + resolution: {integrity: sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==} - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + get-uri@6.0.5: + resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} + engines: {node: '>= 14'} - node-stdlib-browser@1.3.1: - resolution: {integrity: sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw==} - engines: {node: '>=10'} + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - nodemon@3.1.11: - resolution: {integrity: sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==} - engines: {node: '>=10'} + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true - nopt@7.2.1: - resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + giget@3.1.2: + resolution: {integrity: sha512-T2qUpKBHeUTwHcIhydgnJzhL0Hj785ms+JkxaaWQH9SDM/llXeewnOkfJcFShAHjWI+26hOChwUfCoupaXLm8g==} hasBin: true - normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + git-log-parser@1.2.1: + resolution: {integrity: sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==} - normalize-package-data@3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} + git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} + hasBin: true - normalize-package-data@6.0.2: - resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} - engines: {node: ^16.14.0 || >=18.0.0} + git-up@7.0.0: + resolution: {integrity: sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==} - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + git-url-parse@13.1.1: + resolution: {integrity: sha512-PCFJyeSSdtnbfhSNRw9Wk96dDCNx+sogTe4YNXeXSJxt7xz5hvXekuRn9JX7m+Mf4OscCu8h+mtAl3+h5Fo8lQ==} - normalize-url@6.1.0: - resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} - engines: {node: '>=10'} - - normalize-url@8.1.1: - resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} - engines: {node: '>=14.16'} + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + github-slugger@1.4.0: + resolution: {integrity: sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==} - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} - npm-run-path@6.0.0: - resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} - engines: {node: '>=18'} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} - npm@10.9.4: - resolution: {integrity: sha512-OnUG836FwboQIbqtefDNlyR0gTHzIfwRfE3DuiNewBvnMnWEpB0VEXwBlFVgqpNzIgYo/MHh3d2Hel/pszapAA==} - engines: {node: ^18.17.0 || >=20.5.0} - hasBin: true - bundledDependencies: - - '@isaacs/string-locale-compare' - - '@npmcli/arborist' - - '@npmcli/config' - - '@npmcli/fs' - - '@npmcli/map-workspaces' - - '@npmcli/package-json' - - '@npmcli/promise-spawn' - - '@npmcli/redact' - - '@npmcli/run-script' - - '@sigstore/tuf' - - abbrev - - archy - - cacache - - chalk - - ci-info - - cli-columns - - fastest-levenshtein - - fs-minipass - - glob - - graceful-fs - - hosted-git-info - - ini - - init-package-json - - is-cidr - - json-parse-even-better-errors - - libnpmaccess - - libnpmdiff - - libnpmexec - - libnpmfund - - libnpmhook - - libnpmorg - - libnpmpack - - libnpmpublish - - libnpmsearch - - libnpmteam - - libnpmversion - - make-fetch-happen - - minimatch - - minipass - - minipass-pipeline - - ms - - node-gyp - - nopt - - normalize-package-data - - npm-audit-report - - npm-install-checks - - npm-package-arg - - npm-pick-manifest - - npm-profile - - npm-registry-fetch - - npm-user-validate - - p-map - - pacote - - parse-conflict-json - - proc-log - - qrcode-terminal - - read - - semver - - spdx-expression-parse - - ssri - - supports-color - - tar - - text-table - - tiny-relative-date - - treeverse - - validate-npm-package-name - - which - - write-file-atomic + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} - npm@8.19.4: - resolution: {integrity: sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - hasBin: true - bundledDependencies: - - '@isaacs/string-locale-compare' - - '@npmcli/arborist' - - '@npmcli/ci-detect' - - '@npmcli/config' - - '@npmcli/fs' - - '@npmcli/map-workspaces' - - '@npmcli/package-json' - - '@npmcli/run-script' - - abbrev - - archy - - cacache - - chalk - - chownr - - cli-columns - - cli-table3 - - columnify - - fastest-levenshtein - - fs-minipass - - glob - - graceful-fs - - hosted-git-info - - ini - - init-package-json - - is-cidr - - json-parse-even-better-errors - - libnpmaccess - - libnpmdiff - - libnpmexec - - libnpmfund - - libnpmhook - - libnpmorg - - libnpmpack - - libnpmpublish - - libnpmsearch - - libnpmteam - - libnpmversion - - make-fetch-happen - - minimatch - - minipass - - minipass-pipeline - - mkdirp - - mkdirp-infer-owner - - ms - - node-gyp - - nopt - - npm-audit-report - - npm-install-checks - - npm-package-arg - - npm-pick-manifest - - npm-profile - - npm-registry-fetch - - npm-user-validate - - npmlog - - opener - - p-map - - pacote - - parse-conflict-json - - proc-log - - qrcode-terminal - - read - - read-package-json - - read-package-json-fast - - readdir-scoped-modules - - rimraf - - semver - - ssri - - tar - - text-table - - tiny-relative-date - - treeverse - - validate-npm-package-name - - which - - write-file-atomic + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} + globals-docs@2.4.1: + resolution: {integrity: sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==} - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - on-exit-leak-free@2.1.2: - resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} - engines: {node: '>=14.0.0'} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + globby@10.0.1: + resolution: {integrity: sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==} + engines: {node: '>=8'} - on-headers@1.1.0: - resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} - engines: {node: '>= 0.8'} + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + globby@16.1.1: + resolution: {integrity: sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==} + engines: {node: '>=20'} - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + got-cjs@12.5.4: + resolution: {integrity: sha512-Uas6lAsP8bRCt5WXGMhjFf/qEHTrm4v4qxGR02rLG2kdG9qedctvlkdwXVcDJ7Cs84X+r4dPU7vdwGjCaspXug==} engines: {node: '>=12'} - oniguruma-parser@0.12.1: - resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} - oniguruma-to-es@4.3.4: - resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} + got@13.0.0: + resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} + engines: {node: '>=16'} - open@10.2.0: - resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} - engines: {node: '>=18'} + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - openapi-types@12.1.3: - resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + gunzip-maybe@1.4.2: + resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} + hasBin: true - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} + gzip-size@7.0.0: + resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - orderedmap@2.1.1: - resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + h3@1.15.6: + resolution: {integrity: sha512-oi15ESLW5LRthZ+qPCi5GNasY/gvynSKUQxgiovrY63bPAtG59wtM+LSrlcwvOHAXzGrXVLnI97brbkdPF9WoQ==} - os-browserify@0.3.0: - resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + happy-dom@20.4.0: + resolution: {integrity: sha512-RDeQm3dT9n0A5f/TszjUmNCLEuPnMGv3Tv4BmNINebz/h17PA6LMBcxJ5FrcqltNBMh9jA/8ufgDdBYUdBt+eg==} + engines: {node: '>=20.0.0'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} - p-any@4.0.0: - resolution: {integrity: sha512-S/B50s+pAVe0wmEZHmBs/9yJXeZ5KhHzOsgKzt0hRdgkoR3DxW9ts46fcsWi/r3VnzsnkKS7q4uimze+zjdryw==} - engines: {node: '>=12.20'} + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} - p-cancelable@2.1.1: - resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - p-cancelable@3.0.0: - resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} - engines: {node: '>=12.20'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - p-each-series@3.0.0: - resolution: {integrity: sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==} - engines: {node: '>=12'} + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} - p-event@6.0.1: - resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} - engines: {node: '>=16.17'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} - p-filter@4.1.0: - resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==} - engines: {node: '>=18'} + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} - p-is-promise@3.0.0: - resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} - engines: {node: '>=8'} + hash-base@3.0.5: + resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} + engines: {node: '>= 0.10'} - p-limit@1.3.0: - resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} - engines: {node: '>=4'} + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} - p-locate@2.0.0: - resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} - engines: {node: '>=4'} + hast-util-embedded@3.0.0: + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} - p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} - p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} - p-map@7.0.4: - resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} - engines: {node: '>=18'} + hast-util-from-parse5@7.1.2: + resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==} - p-reduce@2.1.0: - resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} - engines: {node: '>=8'} + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} - p-reduce@3.0.0: - resolution: {integrity: sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==} - engines: {node: '>=12'} + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} - p-some@6.0.0: - resolution: {integrity: sha512-CJbQCKdfSX3fIh8/QKgS+9rjm7OBNUTmwWswAFQAhc8j1NR1dsEDETUEuVUtQHZpV+J03LqWBEwvu0g1Yn+TYg==} - engines: {node: '>=12.20'} + hast-util-is-body-ok-link@3.0.1: + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} - p-timeout@5.1.0: - resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} - engines: {node: '>=12'} + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} - p-timeout@6.1.4: - resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} - engines: {node: '>=14.16'} + hast-util-minify-whitespace@1.0.1: + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} - p-try@1.0.0: - resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} - engines: {node: '>=4'} + hast-util-parse-selector@3.1.1: + resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} - pac-proxy-agent@7.2.0: - resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} - engines: {node: '>= 14'} + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} + hast-util-phrasing@3.0.1: + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + hast-util-raw@7.2.3: + resolution: {integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==} - pako@0.2.9: - resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + hast-util-sanitize@4.1.0: + resolution: {integrity: sha512-Hd9tU0ltknMGRDv+d6Ro/4XKzBqQnP/EZrpiTbpFYfXv/uOhWeKc+2uajcbEvAEH98VZd7eII2PiXm13RihnLw==} - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + hast-util-to-html@8.0.4: + resolution: {integrity: sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==} - parse-asn1@5.1.9: - resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} - engines: {node: '>= 0.10'} + hast-util-to-html@9.0.4: + resolution: {integrity: sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==} - parse-entities@4.0.2: - resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} - parse-filepath@1.0.2: - resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} - engines: {node: '>=0.8'} + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} - parse-imports-exports@0.2.4: - resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} + hast-util-to-mdast@10.1.0: + resolution: {integrity: sha512-DsL/SvCK9V7+vfc6SLQ+vKIyBDXTk2KLSbfBYkH4zeF/uR1yBajHRhkzuaUSGOB1WJSTieJBdHwxlC+HLKvZZw==} - parse-json@4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} + hast-util-to-mdast@10.1.2: + resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + hast-util-to-parse5@7.1.0: + resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==} - parse-json@8.3.0: - resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} - engines: {node: '>=18'} + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} - parse-latin@7.0.0: - resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} - parse-ms@4.0.0: - resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} - engines: {node: '>=18'} + hast-util-whitespace@2.0.1: + resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} - parse-path@7.1.0: - resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - parse-semver@1.1.1: - resolution: {integrity: sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==} + hastscript@7.2.0: + resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} - parse-statements@1.0.11: - resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} - parse-url@8.1.0: - resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true - parse5-htmlparser2-tree-adapter@6.0.1: - resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} - parse5-htmlparser2-tree-adapter@7.1.0: - resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} - parse5-parser-stream@7.1.2: - resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + hex-rgb@5.0.0: + resolution: {integrity: sha512-NQO+lgVUCtHxZ792FodgW0zflK+ozS9X9dwGp9XvvmPlH7pyxd588cn24TD3rmPm/N0AIRXF10Otah8yKqGw4w==} + engines: {node: '>=12'} - parse5@5.1.1: - resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} - parse5@6.0.1: - resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - parse5@8.0.0: - resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + hono@4.12.1: + resolution: {integrity: sha512-hi9afu8g0lfJVLolxElAZGANCTTl6bewIdsRNhaywfP9K8BPf++F2z6OLrYGIinUwpRKzbZHMhPwvc0ZEpAwGw==} + engines: {node: '>=16.9.0'} - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} + hook-std@4.0.0: + resolution: {integrity: sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==} + engines: {node: '>=20'} - patch-console@2.0.0: - resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + hookable@6.0.1: + resolution: {integrity: sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==} - path-exists@3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} - path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + hosted-git-info@8.1.0: + resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} + engines: {node: ^18.17.0 || >=20.5.0} - path-is-inside@1.0.2: - resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + hosted-git-info@9.0.2: + resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} + engines: {node: ^20.17.0 || >=22.9.0} - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - path-root-regex@0.1.2: - resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} - engines: {node: '>=0.10.0'} + html-void-elements@2.0.1: + resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} - path-root@0.1.1: - resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} - engines: {node: '>=0.10.0'} + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} - path-to-regexp@3.3.0: - resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} - pbkdf2@3.1.5: - resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} - engines: {node: '>= 0.10'} + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true - pdfjs-dist@5.4.624: - resolution: {integrity: sha512-sm6TxKTtWv1Oh6n3C6J6a8odejb5uO4A4zo/2dgkHuC0iu8ZMAXOezEODkVaoVp8nX1Xzr+0WxFJJmUr45hQzg==} - engines: {node: '>=20.16.0 || >=22.3.0'} + http-proxy-middleware@3.0.5: + resolution: {integrity: sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peek-stream@1.1.3: - resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + http-signature@1.4.0: + resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==} + engines: {node: '>=0.10'} - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} + https-browserify@1.0.0: + resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} - pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} - pify@6.1.0: - resolution: {integrity: sha512-KocF8ve28eFjjuBKKGvzOBGzG8ew2OqOOSxTTZhirkzH7h3BI1vyzqlR0qbfcDBve1Yzo3FVlWUAtCRrbVN8Fw==} - engines: {node: '>=14.16'} + httpxy@0.1.7: + resolution: {integrity: sha512-pXNx8gnANKAndgga5ahefxc++tJvNL87CXoRwxn1cJE2ZkWEojF3tNfQIEhZX/vfpt+wzeAzpUI4qkediX1MLQ==} - pinia@2.3.1: - resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==} - peerDependencies: - typescript: '>=4.4.4' - vue: 3.5.25 - peerDependenciesMeta: - typescript: - optional: true + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} - pino-abstract-transport@1.2.0: - resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} - pino-abstract-transport@2.0.0: - resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} - pino-std-serializers@7.1.0: - resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} - pino@9.14.0: - resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} - hasBin: true + ico-endec@0.1.6: + resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==} - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} - pkce-challenge@5.0.1: - resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} - engines: {node: '>=16.20.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} - pkg-conf@2.1.0: - resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} - engines: {node: '>=4'} + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} - pkg-dir@5.0.0: - resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} - engines: {node: '>=10'} + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - pkg-types@2.3.0: - resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - playwright-core@1.58.1: - resolution: {integrity: sha512-bcWzOaTxcW+VOOGBCQgnaKToLJ65d6AqfLVKEWvexyS3AS6rbXl+xdpYRMGSRBClPvyj44njOWoxjNdL/H9UNg==} - engines: {node: '>=18'} - hasBin: true + ignore-walk@8.0.0: + resolution: {integrity: sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==} + engines: {node: ^20.17.0 || >=22.9.0} - playwright@1.58.1: - resolution: {integrity: sha512-+2uTZHxSCcxjvGc5C891LrS1/NlxglGxzrC4seZiVjcYVQfUa87wBL6rTDqzGjuoWNjnBzRqKmF6zRYGMvQUaQ==} - engines: {node: '>=18'} - hasBin: true + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} - pony-cause@1.1.1: - resolution: {integrity: sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==} - engines: {node: '>=12.0.0'} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} + image-meta@0.2.2: + resolution: {integrity: sha512-3MOLanc3sb3LNGWQl1RlQlNWURE5g32aUphrDyFeCsxBTk08iE3VNe4CwsUZ0Qs1X+EfX0+r29Sxdpza4B+yRA==} - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - postcss-nested-import@1.3.0: - resolution: {integrity: sha512-n0uARfX3SRntgA1A+fD1n+JvquCbbD43P5EOrRqbuVgzl2xVXA1J90gdmeZ57Xg7/GYs/j9GRKxQD9dzeBP7AA==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.3.0 - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 + immer@9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} - postcss-prefixwrap@1.57.2: - resolution: {integrity: sha512-HKfOJJCFUtZiUu6CaWmxb6JxYZetn8McOuFUa0t4CJ0ZtcxCPlD8COSPu6804xNc4WPBu34BI0h96wkONLd9lQ==} - peerDependencies: - postcss: '*' + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + import-from-esm@2.0.0: + resolution: {integrity: sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==} + engines: {node: '>=18.20'} - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. - hasBin: true + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} + impound@1.1.5: + resolution: {integrity: sha512-5AUn+QE0UofqNHu5f2Skf6Svukdg4ehOIq8O0EtqIx4jta0CDZYBPqpIHt0zrlUTiFVYlLpeH39DoikXBjPKpA==} - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} - prettier@3.8.1: - resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} - engines: {node: '>=14'} - hasBin: true + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} - pretty-format@27.5.1: - resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} - pretty-ms@9.3.0: - resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} engines: {node: '>=18'} - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - process-warning@1.0.0: - resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - process-warning@5.0.0: - resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} + ini@3.0.1: + resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} - property-information@6.5.0: - resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + ink-spinner@5.0.0: + resolution: {integrity: sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA==} + engines: {node: '>=14.16'} + peerDependencies: + ink: '>=4.0.0' + react: '>=18.0.0' - property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + ink@6.3.0: + resolution: {integrity: sha512-2CbJAa7XeziZYe6pDS5RVLirRY28iSGMQuEV8jRU5NQsONQNfcR/BZHHc9vkMg2lGYTHTM2pskxC1YmY28p6bQ==} + engines: {node: '>=20'} + peerDependencies: + '@types/react': '>=19.0.0' + react: '>=19.0.0' + react-devtools-core: ^4.19.1 + peerDependenciesMeta: + '@types/react': + optional: true + react-devtools-core: + optional: true - prosemirror-commands@1.7.1: - resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} - prosemirror-dropcursor@1.8.2: - resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} + inquirer@12.3.0: + resolution: {integrity: sha512-3NixUXq+hM8ezj2wc7wC37b32/rHq1MwNZDYdvx+d6jokOD+r+i8Q4Pkylh9tISYP114A128LCX8RKhopC5RfQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' - prosemirror-gapcursor@1.4.0: - resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} - prosemirror-history@1.5.0: - resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} + into-stream@7.0.0: + resolution: {integrity: sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==} + engines: {node: '>=12'} - prosemirror-inputrules@1.5.1: - resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} + ioredis@5.10.0: + resolution: {integrity: sha512-HVBe9OFuqs+Z6n64q09PQvP1/R4Bm+30PAyyD4wIEqssh3v9L21QjCVk4kRLucMBcDokJTcLjsGeVRlq/nH6DA==} + engines: {node: '>=12.22.0'} - prosemirror-keymap@1.2.3: - resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + ip-address@10.0.1: + resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} + engines: {node: '>= 12'} - prosemirror-model@1.25.4: - resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} - prosemirror-schema-basic@1.2.4: - resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} + ip-regex@4.3.0: + resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==} + engines: {node: '>=8'} - prosemirror-schema-list@1.5.1: - resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} - prosemirror-state@1.4.4: - resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} - prosemirror-tables@1.8.5: - resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} - prosemirror-test-builder@1.1.1: - resolution: {integrity: sha512-DJ1+4TNTE9ZcYN/ozXCaWJVrGA99UttMoVvZuidvAotRg7FaiNtEYxL/vlDwfZDRnzJDXNYhmM3XPv3EweK7yA==} + is-absolute@1.0.0: + resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} + engines: {node: '>=0.10.0'} - prosemirror-transform@1.11.0: - resolution: {integrity: sha512-4I7Ce4KpygXb9bkiPS3hTEk4dSHorfRw8uI0pE8IhxlK2GXsqv5tIA7JUSxtSu7u8APVOTtbUBxTmnHIxVkIJw==} + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} - prosemirror-view@1.41.5: - resolution: {integrity: sha512-UDQbIPnDrjE8tqUBbPmCOZgtd75htE6W3r0JCmY9bL6W1iemDM37MZEKC49d+tdQ0v/CKx4gjxLoLsfkD2NiZA==} + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - proto-list@1.2.4: - resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} - protocols@2.0.2: - resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - proxy-agent@6.5.0: - resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} - engines: {node: '>= 14'} + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} - pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} - public-encrypt@4.0.3: - resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} - public-ip@5.0.0: - resolution: {integrity: sha512-xaH3pZMni/R2BG7ZXXaWS9Wc9wFlhyDVJF47IJ+3ali0TGv+2PsckKxbmo+rnx3ZxiV2wblVhtdS3bohAP6GGw==} - engines: {node: ^14.13.1 || >=16.0.0} + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} - pump@2.0.1: - resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} - pumpify@1.5.1: - resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} - - punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} - puppeteer-core@22.14.0: - resolution: {integrity: sha512-rl4tOY5LcA3e374GAlsGGHc05HL3eGNf5rZ+uxkl6id9zVZKcwcp1Z+Nd6byb6WPiPeecT/dwz8f/iUm+AZQSw==} - engines: {node: '>=18'} + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} - puppeteer@22.14.0: - resolution: {integrity: sha512-MGTR6/pM8zmWbTdazb6FKnwIihzsSEXBPH49mFFU96DNZpQOevCAZMnjBZGlZRGRzRK6aADCavR6SQtrbv5dQw==} - engines: {node: '>=18'} - deprecated: < 24.15.0 is no longer supported - hasBin: true + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} + is-deflate@1.0.0: + resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} - qs@6.14.1: - resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} - engines: {node: '>=0.6'} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true - querystring-es3@0.2.1: - resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} - engines: {node: '>=0.4.x'} + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} - quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} - quick-lru@5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} - randomfill@1.0.4: - resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} - range-parser@1.2.0: - resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} - engines: {node: '>= 0.6'} + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} + is-gzip@1.0.0: + resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} + engines: {node: '>=0.10.0'} - raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - raw-body@2.5.3: - resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} - engines: {node: '>= 0.8'} + is-in-ci@2.0.0: + resolution: {integrity: sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==} + engines: {node: '>=20'} + hasBin: true - raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} hasBin: true - react-dom@19.2.4: - resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} - peerDependencies: - react: ^19.2.4 + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} - react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + is-ip@3.1.0: + resolution: {integrity: sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==} + engines: {node: '>=8'} - react-reconciler@0.32.0: - resolution: {integrity: sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ==} - engines: {node: '>=0.10.0'} - peerDependencies: - react: ^19.1.0 + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} - react-refresh@0.18.0: - resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} - engines: {node: '>=0.10.0'} + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} - react-remove-scroll@2.7.2: - resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} - react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + is-network-error@1.3.1: + resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + engines: {node: '>=16'} - react@19.2.3: - resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} - engines: {node: '>=0.10.0'} + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} - react@19.2.4: - resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} - engines: {node: '>=0.10.0'} + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} - read-package-up@11.0.0: - resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} - engines: {node: '>=18'} + is-online@10.0.0: + resolution: {integrity: sha512-WCPdKwNDjXJJmUubf2VHLMDBkUZEtuOvpXUfUnUFbEnM6In9ByiScL4f4jKACz/fsb2qDkesFerW3snf/AYz3A==} + engines: {node: '>=14.16'} - read-pkg-up@9.1.0: - resolution: {integrity: sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} - read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - read-pkg@7.1.0: - resolution: {integrity: sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==} - engines: {node: '>=12.20'} + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} - read-pkg@9.0.1: - resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} - engines: {node: '>=18'} + is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} - read@1.0.7: - resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} - engines: {node: '>=0.8'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + is-plain-object@3.0.1: + resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} + engines: {node: '>=0.10.0'} - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + is-port-reachable@4.0.0: + resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} - recma-build-jsx@1.0.0: - resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - recma-jsx@1.0.1: - resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - recma-parse@1.0.0: - resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - recma-stringify@1.0.0: - resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} - redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} + is-relative@1.0.0: + resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} + engines: {node: '>=0.10.0'} - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} - regex-recursion@6.0.2: - resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} - - regex-utilities@2.3.0: - resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} - regex@6.1.0: - resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + is-ssh@1.4.1: + resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} - registry-auth-token@3.3.2: - resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - registry-auth-token@4.2.2: - resolution: {integrity: sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==} - engines: {node: '>=6.0.0'} + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} - registry-auth-token@5.1.1: - resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} - engines: {node: '>=14'} + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} - registry-url@3.1.0: - resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} - engines: {node: '>=0.10.0'} + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} - rehype-katex@7.0.1: - resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + is-text-path@2.0.0: + resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} + engines: {node: '>=8'} - rehype-minify-whitespace@6.0.2: - resolution: {integrity: sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} - rehype-parse@9.0.1: - resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - rehype-recma@1.0.0: - resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + is-unc-path@1.0.0: + resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} + engines: {node: '>=0.10.0'} - rehype-remark@10.0.1: - resolution: {integrity: sha512-EmDndlb5NVwXGfUa4c9GPK+lXeItTilLhE6ADSaQuHr4JUlKw9MidzGzx4HpqZrNCt6vnHmEifXQiiA+CEnjYQ==} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} - rehype-stringify@10.0.1: - resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} - remark-frontmatter@5.0.0: - resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} - remark-gfm@3.0.1: - resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} - remark-gfm@4.0.0: - resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + is-what@3.14.1: + resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} - remark-gfm@4.0.1: - resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} - remark-html@15.0.2: - resolution: {integrity: sha512-/CIOI7wzHJzsh48AiuIyIe1clxVkUtreul73zcCXLub0FmnevQE0UMFDQm7NUx8/3rl/4zCshlMfqBdWScQthw==} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} - remark-math@6.0.0: - resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} - remark-mdx-remove-esm@1.2.2: - resolution: {integrity: sha512-YSaUwqiuJuD6S9XTAD6zmO4JJJZJgsRAdsl2drZO8/ssAVv0HXAg4vkSgHZAP46ORh8ERPFQrC7JWlbkwBwu1A==} - peerDependencies: - unified: ^11 + is64bit@2.0.0: + resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==} + engines: {node: '>=18'} - remark-mdx@3.0.1: - resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - remark-mdx@3.1.0: - resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - remark-mdx@3.1.1: - resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - remark-parse@10.0.2: - resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} - remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} - remark-reference-links@6.0.1: - resolution: {integrity: sha512-34wY2C6HXSuKVTRtyJJwefkUD8zBOZOSHFZ4aSTnU2F656gr9WeuQ2dL6IJDK3NPd2F6xKF2t4XXcQY9MygAXg==} + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} - remark-rehype@11.1.1: - resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} + isomorphic-timers-promises@1.0.1: + resolution: {integrity: sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ==} + engines: {node: '>=10'} - remark-smartypants@3.0.2: - resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} - engines: {node: '>=16.0.0'} + isomorphic.js@0.2.5: + resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} - remark-stringify@10.0.3: - resolution: {integrity: sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==} + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + issue-parser@7.0.1: + resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} + engines: {node: ^18.17 || >=20.6.1} - remark-toc@8.0.1: - resolution: {integrity: sha512-7he2VOm/cy13zilnOTZcyAoyoolV26ULlon6XyCFU+vG54Z/LWJnwphj/xKIDLOt66QmJUgTyUvLVHi2aAElyg==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} - remark@14.0.3: - resolution: {integrity: sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==} + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} - remark@15.0.1: - resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} - resolve-alpn@1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} + java-properties@1.0.2: + resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==} + engines: {node: '>= 0.6.0'} - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} - engines: {node: '>= 0.4'} + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - responselike@2.0.1: - resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - responselike@3.0.0: - resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} - engines: {node: '>=14.16'} + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} - restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} - retext-latin@4.0.0: - resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + js-base64@3.7.8: + resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} - retext-smartypants@6.2.0: - resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + js-beautify@1.15.4: + resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} + engines: {node: '>=14'} + hasBin: true - retext-stringify@4.0.0: - resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} - retext@9.0.0: - resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - ripemd160@2.0.3: - resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} - engines: {node: '>= 0.8'} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true - rolldown-vite@7.3.1: - resolution: {integrity: sha512-LYzdNAjRHhF2yA4JUQm/QyARyi216N2rpJ0lJZb8E9FU2y5v6Vk+xq/U4XBOxMefpWixT5H3TslmAHm1rqIq2w==} - engines: {node: ^20.19.0 || >=22.12.0} + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - esbuild: ^0.27.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - rolldown@1.0.0-beta.53: - resolution: {integrity: sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw==} - engines: {node: ^20.19.0 || >=22.12.0} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - rollup-plugin-copy@3.5.0: - resolution: {integrity: sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==} - engines: {node: '>=8.3'} + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - rollup-plugin-visualizer@5.14.0: - resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} - engines: {node: '>=18'} - hasBin: true + jsdoc-type-pratt-parser@5.1.1: + resolution: {integrity: sha512-DYYlVP1fe4QBMh2xTIs20/YeTz2GYVbWAEZweHSZD+qQ/Cx2d5RShuhhsdk64eTjNq0FeVnteP/qVOgaywSRbg==} + engines: {node: '>=12.0.0'} + + jsdom@27.3.0: + resolution: {integrity: sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - rolldown: 1.x - rollup: 2.x || 3.x || 4.x + canvas: 3.2.1 peerDependenciesMeta: - rolldown: - optional: true - rollup: + canvas: optional: true - rollup@4.57.1: - resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} hasBin: true - rope-sequence@1.3.4: - resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - run-applescript@7.1.0: - resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} - engines: {node: '>=18'} + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - run-async@3.0.0: - resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} - engines: {node: '>=0.12.0'} + json-parse-even-better-errors@5.0.0: + resolution: {integrity: sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==} + engines: {node: ^20.17.0 || >=22.9.0} - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + json-schema-ref-resolver@3.0.0: + resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==} - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - sade@1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true - safe-stable-stringify@1.1.1: - resolution: {integrity: sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} + jsonc-parser@2.2.1: + resolution: {integrity: sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==} - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - sax@1.4.4: - resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} - engines: {node: '>=11.0.0'} + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + jsonpath-plus@10.3.0: + resolution: {integrity: sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==} + engines: {node: '>=18.0.0'} + hasBin: true - seemly@0.3.10: - resolution: {integrity: sha512-2+SMxtG1PcsL0uyhkumlOU6Qo9TAQ/WyH7tthnPIOQB05/12jz9naq6GZ6iZ6ApVsO3rr2gsnTf3++OV63kE1Q==} + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} - semantic-release-commit-filter@1.0.2: - resolution: {integrity: sha512-LpIB1UN78oRmJnqgPdvA/qRgVitih5V1Ybyszv8GcOBAJWJBHGWI1PmSrOfdEmbf1ZvGkdK/NNDdBHbuSQqSyQ==} + jsonwebtoken@9.0.3: + resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} + engines: {node: '>=12', npm: '>=6'} - semantic-release-linear-app@0.7.1: - resolution: {integrity: sha512-UmFCNIFySR/6ZZ2t0RYUwBTLQrLwp9c5eEgePwN7PAU9wLC0Oc3KgZ+bElpyhl9rPOhvhBJhSGsoPNt8Sa2tBw==} - engines: {node: '>=18'} - peerDependencies: - semantic-release: '>=20.0.0' + jsprim@2.0.2: + resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} + engines: {'0': node >=0.6.0} - semantic-release-pnpm@1.0.2: - resolution: {integrity: sha512-jYG+287heOL/uAp8mgwx3wSe+9K9J3RNSnbDNoOd2kcmEDM9HLfA2VnOmv6fx/X3/KijBNITPXQogYcNjLvf3Q==} - engines: {node: '>=16 || ^14.17'} - peerDependencies: - semantic-release: '>=19.0.0' + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} - semantic-release@24.2.9: - resolution: {integrity: sha512-phCkJ6pjDi9ANdhuF5ElS10GGdAKY6R1Pvt9lT3SFhOwM4T7QZE7MLpBDbNruUx/Q3gFD92/UOFringGipRqZA==} - engines: {node: '>=20.8.1'} - hasBin: true + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - semver-diff@5.0.0: - resolution: {integrity: sha512-0HbGtOm+S7T6NGQ/pxJSJipJvc4DK3FcRVMRkhsIwJDJ4Jcz5DQC1cPPzB5GhzyHjwttW878HaWQq46CkL3cqg==} - engines: {node: '>=12'} - deprecated: Deprecated as the semver package now supports this built-in. + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} - semver-regex@4.0.5: - resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} - engines: {node: '>=12'} + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true + karma-source-map-support@1.4.0: + resolution: {integrity: sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + katex@0.16.28: + resolution: {integrity: sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==} hasBin: true - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true + keytar@7.9.0: + resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} - send@0.19.2: - resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} - engines: {node: '>= 0.8.0'} + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} + knitwork@1.3.0: + resolution: {integrity: sha512-4LqMNoONzR43B1W0ek0fhXMsDNW/zxa1NdFAVMY+k28pgZLovR4G3PB5MrpTxCy1QaZCqNoiaKPr5w5qZHfSNw==} - serialize-error@12.0.0: - resolution: {integrity: sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==} - engines: {node: '>=18'} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - serve-handler@6.1.6: - resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==} + konan@2.1.1: + resolution: {integrity: sha512-7ZhYV84UzJ0PR/RJnnsMZcAbn+kLasJhVNWsu8ZyVEJYRpGA5XESQ9d/7zOa08U0Ou4cmB++hMNY/3OSV9KIbg==} - serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} + konva@10.2.0: + resolution: {integrity: sha512-JBoz0Xjbf49UPxCZegZ4WseqOzJ+C4AUDOtJ9eBve5RS5Fcq/u8TdBD5fDl/uPFInpC3a9uycm0sRyZpF4hheg==} - serve-static@1.16.3: - resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} - engines: {node: '>= 0.8.0'} + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} - serve@14.2.5: - resolution: {integrity: sha512-Qn/qMkzCcMFVPb60E/hQy+iRLpiU8PamOfOSYoAHmmF+fFFmpPpqa6Oci2iWYpTdOUM3VF+TINud7CfbQnsZbA==} - engines: {node: '>= 14'} + laravel-vite-plugin@2.1.0: + resolution: {integrity: sha512-z+ck2BSV6KWtYcoIzk9Y5+p4NEjqM+Y4i8/H+VZRLq0OgNjW2DqyADquwYu5j8qRvaXwzNmfCWl1KrMlV1zpsg==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + peerDependencies: + vite: ^7.0.0 - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - - setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + launch-editor@2.13.1: + resolution: {integrity: sha512-lPSddlAAluRKJ7/cjRFoXUFzaX7q/YKI7yPHuEvSJVqoXvFnJov1/Ud87Aa4zULIbA9Nja4mSPK8l0z/7eV2wA==} - sha.js@2.4.12: - resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} - engines: {node: '>= 0.10'} - hasBin: true + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} - sharp-ico@0.1.5: - resolution: {integrity: sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==} + lcm@0.0.3: + resolution: {integrity: sha512-TB+ZjoillV6B26Vspf9l2L/vKaRY/4ep3hahcyVkCGFgsTNRUQdc24bQeNFiZeoxH0vr5+7SfNRMQuPHv/1IrQ==} - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + lefthook-darwin-arm64@1.13.6: + resolution: {integrity: sha512-m6Lb77VGc84/Qo21Lhq576pEvcgFCnvloEiP02HbAHcIXD0RTLy9u2yAInrixqZeaz13HYtdDaI7OBYAAdVt8A==} + cpu: [arm64] + os: [darwin] - sharp@0.34.5: - resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + lefthook-darwin-x64@1.13.6: + resolution: {integrity: sha512-CoRpdzanu9RK3oXR1vbEJA5LN7iB+c7hP+sONeQJzoOXuq4PNKVtEaN84Gl1BrVtCNLHWFAvCQaZPPiiXSy8qg==} + cpu: [x64] + os: [darwin] - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + lefthook-freebsd-arm64@1.13.6: + resolution: {integrity: sha512-X4A7yfvAJ68CoHTqP+XvQzdKbyd935sYy0bQT6Ajz7FL1g7hFiro8dqHSdPdkwei9hs8hXeV7feyTXbYmfjKQQ==} + cpu: [arm64] + os: [freebsd] - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + lefthook-freebsd-x64@1.13.6: + resolution: {integrity: sha512-ai2m+Sj2kGdY46USfBrCqLKe9GYhzeq01nuyDYCrdGISePeZ6udOlD1k3lQKJGQCHb0bRz4St0r5nKDSh1x/2A==} + cpu: [x64] + os: [freebsd] - shell-quote@1.8.3: - resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} - engines: {node: '>= 0.4'} + lefthook-linux-arm64@1.13.6: + resolution: {integrity: sha512-cbo4Wtdq81GTABvikLORJsAWPKAJXE8Q5RXsICFUVznh5PHigS9dFW/4NXywo0+jfFPCT6SYds2zz4tCx6DA0Q==} + cpu: [arm64] + os: [linux] - shiki@3.22.0: - resolution: {integrity: sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==} + lefthook-linux-x64@1.13.6: + resolution: {integrity: sha512-uJl9vjCIIBTBvMZkemxCE+3zrZHlRO7Oc+nZJ+o9Oea3fu+W82jwX7a7clw8jqNfaeBS+8+ZEQgiMHWCloTsGw==} + cpu: [x64] + os: [linux] - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} + lefthook-openbsd-arm64@1.13.6: + resolution: {integrity: sha512-7r153dxrNRQ9ytRs2PmGKKkYdvZYFPre7My7XToSTiRu5jNCq++++eAKVkoyWPduk97dGIA+YWiEr5Noe0TK2A==} + cpu: [arm64] + os: [openbsd] - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} + lefthook-openbsd-x64@1.13.6: + resolution: {integrity: sha512-Z+UhLlcg1xrXOidK3aLLpgH7KrwNyWYE3yb7ITYnzJSEV8qXnePtVu8lvMBHs/myzemjBzeIr/U/+ipjclR06g==} + cpu: [x64] + os: [openbsd] - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} + lefthook-windows-arm64@1.13.6: + resolution: {integrity: sha512-Uxef6qoDxCmUNQwk8eBvddYJKSBFglfwAY9Y9+NnnmiHpWTjjYiObE9gT2mvGVpEgZRJVAatBXc+Ha5oDD/OgQ==} + cpu: [arm64] + os: [win32] - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} + lefthook-windows-x64@1.13.6: + resolution: {integrity: sha512-mOZoM3FQh3o08M8PQ/b3IYuL5oo36D9ehczIw1dAgp1Ly+Tr4fJ96A+4SEJrQuYeRD4mex9bR7Ps56I73sBSZA==} + cpu: [x64] + os: [win32] - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + lefthook@1.13.6: + resolution: {integrity: sha512-ojj4/4IJ29Xn4drd5emqVgilegAPN3Kf0FQM2p/9+lwSTpU+SZ1v4Ig++NF+9MOa99UKY8bElmVrLhnUUNFh5g==} + hasBin: true - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + less-loader@12.3.1: + resolution: {integrity: sha512-JZZmG7gMzoDP3VGeEG8Sh6FW5wygB5jYL7Wp29FFihuRTsIBacqO3LbRPr2yStYD11riVf13selLm/CPFRDBRQ==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || ^1.0.0 || ^2.0.0-0 + less: ^3.5.0 || ^4.0.0 + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + less@4.4.2: + resolution: {integrity: sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==} engines: {node: '>=14'} + hasBin: true - signale@1.4.0: - resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} - signature_pad@5.1.3: - resolution: {integrity: sha512-zyxW5vuJVnQdGcU+kAj9FYl7WaAunY3kA5S7mPg0xJiujL9+sPAWfSQHS5tXaJXDUa4FuZeKhfdCDQ6K3wfkpQ==} - - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + leven@4.1.0: + resolution: {integrity: sha512-KZ9W9nWDT7rF7Dazg8xyLHGLrmpgq2nVNFUckhqdW3szVP6YhCpp/RAnpmVExA9JvrMynjwSLVrEj3AepHR6ew==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - simple-eval@1.0.1: - resolution: {integrity: sha512-LH7FpTAkeD+y5xQC4fzS+tFtaNlvt3Ib1zKzvhjv/Y+cioV4zIuw4IZr2yhRLu67CWL7FR9/6KXKnjRoZTvGGQ==} - engines: {node: '>=12'} + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + lib0@0.2.117: + resolution: {integrity: sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw==} + engines: {node: '>=16'} + hasBin: true - simple-swizzle@0.2.4: - resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + license-webpack-plugin@4.0.2: + resolution: {integrity: sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==} + peerDependencies: + webpack: '*' + peerDependenciesMeta: + webpack: + optional: true - simple-update-notifier@2.0.0: - resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} - engines: {node: '>=10'} + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - sirv@3.0.2: - resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} - engines: {node: '>=18'} + light-my-request@6.6.0: + resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + lightningcss-android-arm64@1.31.1: + resolution: {integrity: sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] - skin-tone@2.0.0: - resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} - engines: {node: '>=8'} + lightningcss-darwin-arm64@1.31.1: + resolution: {integrity: sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + lightningcss-darwin-x64@1.31.1: + resolution: {integrity: sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] - slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} + lightningcss-freebsd-x64@1.31.1: + resolution: {integrity: sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] - slice-ansi@7.1.2: - resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} - engines: {node: '>=18'} + lightningcss-linux-arm-gnueabihf@1.31.1: + resolution: {integrity: sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + lightningcss-linux-arm64-gnu@1.31.1: + resolution: {integrity: sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] - socket.io-adapter@2.5.6: - resolution: {integrity: sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==} + lightningcss-linux-arm64-musl@1.31.1: + resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] - socket.io-parser@4.2.5: - resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} - engines: {node: '>=10.0.0'} + lightningcss-linux-x64-gnu@1.31.1: + resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] - socket.io@4.7.2: - resolution: {integrity: sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==} - engines: {node: '>=10.2.0'} + lightningcss-linux-x64-musl@1.31.1: + resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} + lightningcss-win32-arm64-msvc@1.31.1: + resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] - socks@2.8.7: - resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + lightningcss-win32-x64-msvc@1.31.1: + resolution: {integrity: sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] - sonic-boom@3.8.1: - resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} + lightningcss@1.31.1: + resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} + engines: {node: '>= 12.0.0'} - sonic-boom@4.2.0: - resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} - space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - spawn-error-forwarder@1.0.0: - resolution: {integrity: sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==} + linkify-it@3.0.3: + resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} - spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + listhen@1.9.0: + resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==} + hasBin: true - spdx-exceptions@2.5.0: - resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + listr2@9.0.5: + resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} + engines: {node: '>=20.0.0'} - spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + lmdb@3.5.1: + resolution: {integrity: sha512-NYHA0MRPjvNX+vSw8Xxg6FLKxzAG+e7Pt8RqAQA/EehzHVXq9SxDqJIN3JL1hK0dweb884y8kIh6rkWvPyg9Wg==} + hasBin: true - spdx-expression-parse@4.0.0: - resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} - spdx-license-ids@3.0.22: - resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - split2@1.0.0: - resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + engines: {node: '>=6.11.5'} - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + loader-utils@3.3.1: + resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} + engines: {node: '>= 12.13.0'} - sshpk@1.18.0: - resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} - engines: {node: '>=0.10.0'} - hasBin: true + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} + engines: {node: '>=14'} - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} - engines: {node: '>=12.0.0'} + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} + lockfile@1.0.4: + resolution: {integrity: sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==} - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - steno@0.4.4: - resolution: {integrity: sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==} + lodash.capitalize@4.2.1: + resolution: {integrity: sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==} - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - stream-browserify@3.0.0: - resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - stream-combiner2@1.1.1: - resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} - stream-http@3.2.0: - resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} - streamx@2.23.0: - resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} - string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} + lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - stringify-entities@4.0.4: - resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + lodash.topath@4.5.2: + resolution: {integrity: sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==} - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} - engines: {node: '>=12'} + lodash.uniqby@4.7.0: + resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==} - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} + lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} - strip-final-newline@4.0.0: - resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + log-symbols@7.0.1: + resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} engines: {node: '>=18'} - strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lowdb@1.0.0: + resolution: {integrity: sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==} + engines: {node: '>=4'} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} - strip-json-comments@5.0.3: - resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} - engines: {node: '>=14.16'} + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - strip-literal@3.1.0: - resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - strnum@2.1.2: - resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + lru-cache@11.2.5: + resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==} + engines: {node: 20 || >=22} - style-to-js@1.1.21: - resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - style-to-object@1.0.14: - resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - super-regex@1.1.0: - resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} - engines: {node: '>=18'} + magic-regexp@0.10.0: + resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} - superdoc@1.11.0: - resolution: {integrity: sha512-DY5uObI50Itfxjjog9h8FQKGWLx0o0au2H0h9hbNtBrNXvg8mAeQvekSgYgwmL7xIW+juo/ZMSGY035eLDMmnw==} - peerDependencies: - '@hocuspocus/provider': ^2.13.6 - pdfjs-dist: '>=4.3.136 <=4.6.82' - y-prosemirror: ^1.3.7 - yjs: 13.6.19 + magic-string-ast@1.0.3: + resolution: {integrity: sha512-CvkkH1i81zl7mmb94DsRiFeG9V2fR2JeuK8yDgS8oiZSFa++wWLEgZ5ufEOyLHbvSbD1gTRKv9NdX69Rnvr9JA==} + engines: {node: '>=20.19.0'} - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} - supports-color@9.4.0: - resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} - engines: {node: '>=12'} + make-asynchronous@1.0.1: + resolution: {integrity: sha512-T9BPOmEOhp6SmV25SwLVcHK4E6JyG/coH3C6F1NjNXSziv/fd4GmsqMk8YR6qpPOswfaOCApSNkZv6fxoaYFcQ==} + engines: {node: '>=18'} - supports-hyperlinks@3.2.0: - resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} - engines: {node: '>=14.18'} + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} - symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + make-fetch-happen@15.0.4: + resolution: {integrity: sha512-vM2sG+wbVeVGYcCm16mM3d5fuem9oC28n436HjsGO3LcxoTI8LNVa4rwZDn3f76+cWyT4GGJDxjTYU1I2nr6zw==} + engines: {node: ^20.17.0 || >=22.9.0} - tailwindcss@3.4.4: - resolution: {integrity: sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==} - engines: {node: '>=14.0.0'} - hasBin: true + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} - tar-fs@2.1.4: - resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} - tar-fs@3.1.1: - resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==} + markdown-it@12.3.2: + resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} + hasBin: true - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + marked-terminal@7.3.0: + resolution: {integrity: sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==} + engines: {node: '>=16.0.0'} + peerDependencies: + marked: '>=1 <16' - tar@6.1.15: - resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} - engines: {node: '>=10'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + marked@15.0.12: + resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} + engines: {node: '>= 18'} + hasBin: true - temp-dir@2.0.0: - resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} - engines: {node: '>=8'} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} - temp-dir@3.0.0: - resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} - engines: {node: '>=14.16'} + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} - tempy@1.0.1: - resolution: {integrity: sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==} - engines: {node: '>=10'} + mdast-util-definitions@5.1.2: + resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} - tempy@3.2.0: - resolution: {integrity: sha512-d79HhZya5Djd7am0q+W4RTsSU+D/aJzM+4Y4AGJGuGlgM2L6sx5ZvOYTmZjqPhrDrV6xJTtRSm1JCLj6V6LHLQ==} - engines: {node: '>=14.16'} + mdast-util-find-and-replace@2.2.2: + resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==} - test-exclude@7.0.1: - resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} - engines: {node: '>=18'} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + mdast-util-from-markdown@1.3.1: + resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} - text-extensions@2.4.0: - resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} - engines: {node: '>=8'} + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + mdast-util-gfm-autolink-literal@1.0.3: + resolution: {integrity: sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==} - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} - through2@2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + mdast-util-gfm-footnote@1.0.2: + resolution: {integrity: sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} - time-span@5.1.0: - resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} - engines: {node: '>=12'} + mdast-util-gfm-strikethrough@1.0.3: + resolution: {integrity: sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==} - timers-browserify@2.0.12: - resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} - engines: {node: '>=0.6.0'} + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + mdast-util-gfm-table@1.0.7: + resolution: {integrity: sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} + mdast-util-gfm-task-list-item@1.0.2: + resolution: {integrity: sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} + mdast-util-gfm@2.0.2: + resolution: {integrity: sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==} - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} - tinyspy@4.0.4: - resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} - engines: {node: '>=14.0.0'} + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} - tippy.js@6.3.7: - resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} + mdast-util-inject@1.1.0: + resolution: {integrity: sha512-CcJ0mHa36QYumDKiZ2OIR+ClhfOM7zIzN+Wfy8tRZ1hpH9DKLCS+Mh4DyK5bCxzE9uxMWcbIpeNFWsg1zrj/2g==} - tldts-core@6.1.86: - resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} - tldts-core@7.0.22: - resolution: {integrity: sha512-KgbTDC5wzlL6j/x6np6wCnDSMUq4kucHNm00KXPbfNzmllCmtmvtykJHfmgdHntwIeupW04y8s1N/43S1PkQDw==} + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} - tldts@6.1.86: - resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} - hasBin: true + mdast-util-mdx-jsx@3.1.3: + resolution: {integrity: sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==} - tldts@7.0.22: - resolution: {integrity: sha512-nqpKFC53CgopKPjT6Wfb6tpIcZXHcI6G37hesvikhx0EmUGPkZrujRyAjgnmp1SHNgpQfKVanZ+KfpANFt2Hxw==} - hasBin: true + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} - engines: {node: '>=14.14'} + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} - to-buffer@1.2.2: - resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} - engines: {node: '>= 0.4'} + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} - to-data-view@1.1.0: - resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==} + mdast-util-phrasing@3.0.1: + resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==} - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + mdast-util-to-hast@12.3.0: + resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} - totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} - engines: {node: '>=6'} + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} - touch@3.1.1: - resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} - hasBin: true + mdast-util-to-markdown@1.5.0: + resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} - tough-cookie@5.1.2: - resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} - engines: {node: '>=16'} + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} - tough-cookie@6.0.0: - resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} - engines: {node: '>=16'} + mdast-util-to-string@1.1.0: + resolution: {integrity: sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==} - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + mdast-util-to-string@3.2.0: + resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} - tr46@6.0.0: - resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} - engines: {node: '>=20'} + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - traverse@0.6.8: - resolution: {integrity: sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==} - engines: {node: '>= 0.4'} + mdast-util-toc@6.1.1: + resolution: {integrity: sha512-Er21728Kow8hehecK2GZtb7Ny3omcoPUVrmObiSUwmoRYVZaXLR751QROEFjR8W/vAQdHMLj49Lz20J55XaNpw==} - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} - treemate@0.3.11: - resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} - trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - trim-trailing-lines@2.1.0: - resolution: {integrity: sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==} + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} - trough@2.2.0: - resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} - engines: {node: '>=18.12'} + memfs@4.56.11: + resolution: {integrity: sha512-/GodtwVeKVIHZKLUSr2ZdOxKBC5hHki4JNCU22DoCGPEHr5o2PD5U721zvESKyWwCfTfavFl9WZYgA13OAYK0g==} peerDependencies: - typescript: '>=4.8.4' + tslib: '2' - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - tsup@8.5.1: - resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} - engines: {node: '>=18.0.0'} - hasBin: true + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - tty-browserify@0.0.1: - resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} - tunnel@0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + micromark-core-commonmark@1.1.0: + resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} - twoslash-protocol@0.3.6: - resolution: {integrity: sha512-FHGsJ9Q+EsNr5bEbgG3hnbkvEBdW5STgPU824AHUjB4kw0Dn4p8tABT7Ncg1Ie6V0+mDg3Qpy41VafZXcQhWMA==} + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} - twoslash@0.3.6: - resolution: {integrity: sha512-VuI5OKl+MaUO9UIW3rXKoPgHI3X40ZgB/j12VY6h98Ae1mCBihjPvhOPeJWlxCYcmSbmeZt5ZKkK0dsVtp+6pA==} - peerDependencies: - typescript: ^5.5.0 + micromark-extension-gfm-autolink-literal@1.0.5: + resolution: {integrity: sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==} - typanion@3.14.0: - resolution: {integrity: sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==} + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + micromark-extension-gfm-footnote@1.1.2: + resolution: {integrity: sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==} - type-fest@0.16.0: - resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} - engines: {node: '>=10'} + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} + micromark-extension-gfm-strikethrough@1.0.7: + resolution: {integrity: sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==} - type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - type-fest@1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} + micromark-extension-gfm-table@1.0.7: + resolution: {integrity: sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==} - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} + micromark-extension-gfm-tagfilter@1.0.2: + resolution: {integrity: sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==} - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} + micromark-extension-gfm-task-list-item@1.0.5: + resolution: {integrity: sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==} - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} + micromark-extension-gfm@2.0.3: + resolution: {integrity: sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==} - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} - typed-rest-client@1.8.11: - resolution: {integrity: sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==} + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} - typescript-eslint@8.54.0: - resolution: {integrity: sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' + micromark-extension-mdx-jsx@3.0.1: + resolution: {integrity: sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==} - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} - engines: {node: '>=14.17'} - hasBin: true + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} - uc.micro@1.0.6: - resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} - ufo@1.6.3: - resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + micromark-factory-destination@1.1.0: + resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} - uglify-js@3.19.3: - resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} - engines: {node: '>=0.8.0'} - hasBin: true + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} + micromark-factory-label@1.1.0: + resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} - unbzip2-stream@1.4.3: - resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} - unc-path-regex@0.1.2: - resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} - engines: {node: '>=0.10.0'} + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} - undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} - underscore@1.13.7: - resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + micromark-factory-title@1.1.0: + resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} - undici@7.20.0: - resolution: {integrity: sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==} - engines: {node: '>=20.18.1'} + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} - unicode-emoji-modifier-base@1.0.0: - resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} - engines: {node: '>=4'} + micromark-factory-whitespace@1.1.0: + resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} - unicorn-magic@0.1.0: - resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} - engines: {node: '>=18'} + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} - unicorn-magic@0.3.0: - resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} - engines: {node: '>=18'} + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} - unified@10.1.2: - resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} - unified@11.0.5: - resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + micromark-util-chunked@1.1.0: + resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} - unique-string@2.0.0: - resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} - engines: {node: '>=8'} - - unique-string@3.0.0: - resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} - engines: {node: '>=12'} + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} - unist-builder@3.0.1: - resolution: {integrity: sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ==} + micromark-util-classify-character@1.1.0: + resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} - unist-builder@4.0.0: - resolution: {integrity: sha512-wmRFnH+BLpZnTKpc5L7O67Kac89s9HMrtELpnNaE6TAobq5DTZZs5YaTQfAZBA9bFPECx2uVAPO31c+GVug8mg==} + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} - unist-util-find-after@5.0.0: - resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + micromark-util-combine-extensions@1.1.0: + resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} - unist-util-generated@2.0.1: - resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==} + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} - unist-util-is@5.2.1: - resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + micromark-util-decode-numeric-character-reference@1.1.0: + resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} - unist-util-is@6.0.1: - resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} - unist-util-map@4.0.0: - resolution: {integrity: sha512-HJs1tpkSmRJUzj6fskQrS5oYhBYlmtcvy4SepdDEEsL04FjBrgF0Mgggvxc1/qGBGgW7hRh9+UBK1aqTEnBpIA==} + micromark-util-decode-string@1.1.0: + resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} - unist-util-modify-children@4.0.0: - resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} - unist-util-position-from-estree@2.0.0: - resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + micromark-util-encode@1.1.0: + resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} - unist-util-position@4.0.4: - resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} - unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} - unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + micromark-util-html-tag-name@1.2.0: + resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} - unist-util-remove@4.0.0: - resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} - unist-util-stringify-position@3.0.3: - resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + micromark-util-normalize-identifier@1.1.0: + resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} - unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} - unist-util-visit-children@3.0.0: - resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + micromark-util-resolve-all@1.1.0: + resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} - unist-util-visit-parents@5.1.3: - resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} - unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + micromark-util-sanitize-uri@1.2.0: + resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} - unist-util-visit-parents@6.0.2: - resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - unist-util-visit@4.1.2: - resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} + micromark-util-subtokenize@1.1.0: + resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} - unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} - unist-util-visit@5.1.0: - resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} - universal-user-agent@7.0.3: - resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} - unix-crypt-td-js@1.1.4: - resolution: {integrity: sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==} + micromark@3.2.0: + resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-check@1.5.4: - resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==} + mime-db@1.33.0: + resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} + engines: {node: '>= 0.6'} - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} - urijs@1.19.11: - resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} - url-join@4.0.1: - resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + mime-types@2.1.18: + resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} + engines: {node: '>= 0.6'} - url-join@5.0.0: - resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} - url@0.11.4: - resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} - engines: {node: '>= 0.4'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} - urlpattern-polyfill@10.0.0: - resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true - use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true - use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true + mime@4.1.0: + resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} + engines: {node: '>=16'} + hasBin: true - utif2@4.1.0: - resolution: {integrity: sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==} + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} - util@0.12.5: - resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} - utility-types@3.11.0: - resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} - engines: {node: '>= 4'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} - hasBin: true + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true + mini-css-extract-plugin@2.10.0: + resolution: {integrity: sha512-540P2c5dYnJlyJxTaSloliZexv8rji6rY8FhQN+WF/82iHQfA23j/xtJx97L+mXOML27EqksSek/g4eK7jaL3g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 - uvu@0.5.6: - resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} - engines: {node: '>=8'} - hasBin: true + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - validator@13.15.26: - resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==} - engines: {node: '>= 0.10'} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + engines: {node: 20 || >=22} - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} + minimatch@10.1.2: + resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} + engines: {node: 20 || >=22} - vdirs@0.1.8: - resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} - peerDependencies: - vue: 3.5.25 + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} - verdaccio-audit@13.0.0-next-8.29: - resolution: {integrity: sha512-ZUNONewbFocBq3oWXrwAL8IX4ZovPU70yj0nuYStSVJ9+Vrb74Duc+eI+IIS+jLfyysZe5L0ZAODGN8ny1Lu6w==} - engines: {node: '>=18'} + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - verdaccio-htpasswd@13.0.0-next-8.29: - resolution: {integrity: sha512-JBYCaSTQSUws/EXOqNrh7iOyWPrGLTYSeufCS3Y6BOCJbfDiy2Nh8PbstoZn/L9ZbzUesjPPiIZ4Ou3eUaK0Mw==} - engines: {node: '>=18'} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} - verdaccio@6.2.5: - resolution: {integrity: sha512-sIek+ZF0a1aaRwHo9I5vbONGXzcAgbf5psEmbGVMG9M/MslblIae2wdehG6a2lSxsk4B9c8Ar0j/ZmliTjiStA==} - engines: {node: '>=18'} - hasBin: true + minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} - verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} + minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} - vfile-location@4.1.0: - resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} - vfile-location@5.0.3: - resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - vfile-matter@5.0.1: - resolution: {integrity: sha512-o6roP82AiX0XfkyTHyRCMXgHfltUNlXSEqCIS80f+mbAyiQBE2fxtDVMtseyytGx75sihiJFo/zR6r/4LTs2Cw==} + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} - vfile-message@3.1.4: - resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + minipass-fetch@5.0.2: + resolution: {integrity: sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==} + engines: {node: ^20.17.0 || >=22.9.0} - vfile-message@4.0.3: - resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} - vfile-reporter@7.0.5: - resolution: {integrity: sha512-NdWWXkv6gcd7AZMvDomlQbK3MqFWL1RlGzMn++/O2TI+68+nqxCPTvLugdOtfSzXmjh+xUyhp07HhlrbJjT+mw==} + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} - vfile-sort@3.0.1: - resolution: {integrity: sha512-1os1733XY6y0D5x0ugqSeaVJm9lYgj0j5qdcZQFyxlZOSy1jYarL77lLyb5gK4Wqr1d5OxmuyflSO3zKyFnTFw==} + minipass-sized@2.0.0: + resolution: {integrity: sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==} + engines: {node: '>=8'} - vfile-statistics@2.0.1: - resolution: {integrity: sha512-W6dkECZmP32EG/l+dp2jCLdYzmnDBIw6jwiLZSER81oR5AHRcVqL+k3Z+pfH1R73le6ayDkJRMk0sutj1bMVeg==} + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} - vfile@5.3.7: - resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} - vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} - vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} - vite-plugin-dts@4.5.4: - resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==} - peerDependencies: - typescript: '*' - vite: '*' - peerDependenciesMeta: - vite: - optional: true + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} - vite-plugin-node-polyfills@0.25.0: - resolution: {integrity: sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg==} - peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} - engines: {node: ^20.19.0 || >=22.12.0} + mintlify@4.2.331: + resolution: {integrity: sha512-57mLAnYuZ9EEpTT84NAgUOFK7SSEM0cuO1J+NxNfywJi/RL+JmDijd9Tv74QHOEUhPwHjKPzOkhYR82vMqIdvw==} + engines: {node: '>=18.0.0'} hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 - happy-dom: 20.4.0 - jsdom: 27.3.0 - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/debug': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - vm-browserify@1.1.2: - resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + mlly@1.8.0: + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} - vooks@0.2.12: - resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==} - peerDependencies: - vue: 3.5.25 + mocked-exports@0.1.1: + resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} - vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} - vue-component-type-helpers@2.2.12: - resolution: {integrity: sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} - vue-demi@0.14.10: - resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} - engines: {node: '>=12'} + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msgpackr-extract@3.0.3: + resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} hasBin: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: 3.5.25 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - vue-template-compiler@2.7.16: - resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + msgpackr@1.11.8: + resolution: {integrity: sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==} - vue@3.5.25: - resolution: {integrity: sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - vueuc@0.4.65: - resolution: {integrity: sha512-lXuMl+8gsBmruudfxnMF9HW4be8rFziylXFu1VHVNbLVhRTXXV4njvpRuJapD/8q+oFEMSfQMH16E/85VoWRyQ==} + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + naive-ui@2.43.2: + resolution: {integrity: sha512-YlLMnGrwGTOc+zMj90sG3ubaH5/7czsgLgGcjTLA981IUaz8r6t4WIujNt8r9PNr+dqv6XNEr0vxkARgPPjfBQ==} peerDependencies: vue: 3.5.25 - w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true - w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} + nanotar@0.2.1: + resolution: {integrity: sha512-MUrzzDUcIOPbv7ubhDV/L4CIfVTATd9XhDE2ixFeCrM5yp9AlzUpn91JrnN0HD6hksdxvz9IW9aKANz0Bta0GA==} - web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true - web-worker@1.2.0: - resolution: {integrity: sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==} + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + needle@3.3.1: + resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} + engines: {node: '>= 4.4.x'} + hasBin: true - webidl-conversions@8.0.1: - resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} - engines: {node: '>=20'} + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} - deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation - - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - - whatwg-mimetype@4.0.0: - resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} - engines: {node: '>=18'} - - whatwg-mimetype@5.0.0: - resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} - engines: {node: '>=20'} + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} - whatwg-url@15.1.0: - resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} - engines: {node: '>=20'} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} + neotraverse@0.6.18: + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} + engines: {node: '>= 10'} - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} + nerf-dart@1.0.0: + resolution: {integrity: sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==} - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} + netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} - engines: {node: '>= 0.4'} + next-mdx-remote-client@1.1.4: + resolution: {integrity: sha512-psCMdO50tfoT1kAH7OGXZvhyRfiHVK6IqwjmWFV5gtLo4dnqjAgcjcLNeJ92iI26UNlKShxYrBs1GQ6UXxk97A==} + engines: {node: '>=18.18.0'} + peerDependencies: + react: '>= 18.3.0 < 19.0.0' + react-dom: '>= 18.3.0 < 19.0.0' - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + next@16.1.6: + resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==} + engines: {node: '>=20.9.0'} hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true + nimma@0.2.3: + resolution: {integrity: sha512-1ZOI8J+1PKKGceo/5CT5GfQOG6H8I2BencSK06YarZ2wXwH37BSSUWldqJmMJYA5JfqDqffxDXynt6f11AyKcA==} + engines: {node: ^12.20 || >=14.13} - widest-line@4.0.1: - resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} - engines: {node: '>=12'} + nitropack@2.13.1: + resolution: {integrity: sha512-2dDj89C4wC2uzG7guF3CnyG+zwkZosPEp7FFBGHB3AJo11AywOolWhyQJFHDzve8COvGxJaqscye9wW2IrUsNw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + xml2js: ^0.6.2 + peerDependenciesMeta: + xml2js: + optional: true - widest-line@5.0.0: - resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} - engines: {node: '>=18'} + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} + node-abi@3.87.0: + resolution: {integrity: sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==} + engines: {node: '>=10'} - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} engines: {node: '>=18'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} - ws@8.17.1: - resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} - engines: {node: '>=10.0.0'} + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' + encoding: ^0.1.0 peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: + encoding: optional: true - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' + encoding: ^0.1.0 peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: + encoding: optional: true - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - wsl-utils@0.1.0: - resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} - engines: {node: '>=18'} + node-forge@1.3.3: + resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} + engines: {node: '>= 6.13.0'} - xml-js@1.6.11: - resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} - - xml2js@0.5.0: - resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} - engines: {node: '>=4.0.0'} - - xml2js@0.6.2: - resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} - engines: {node: '>=4.0.0'} - - xmlbuilder@11.0.1: - resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} - engines: {node: '>=4.0'} + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true - xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + node-gyp@12.2.0: + resolution: {integrity: sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} - y-prosemirror@1.3.7: - resolution: {integrity: sha512-NpM99WSdD4Fx4if5xOMDpPtU3oAmTSjlzh5U4353ABbRHl1HtAFUx6HlebLZfyFxXN9jzKMDkVbcRjqOZVkYQg==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} - peerDependencies: - prosemirror-model: ^1.7.1 - prosemirror-state: ^1.2.3 - prosemirror-view: ^1.9.10 - y-protocols: ^1.0.1 - yjs: ^13.5.38 + node-readable-to-web-readable-stream@0.4.2: + resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==} - y-protocols@1.0.7: - resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} - peerDependencies: - yjs: ^13.0.0 + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - y-websocket@3.0.0: - resolution: {integrity: sha512-mUHy7AzkOZ834T/7piqtlA8Yk6AchqKqcrCXjKW8J1w2lPtRDjz8W5/CvXz9higKAHgKRKqpI3T33YkRFLkPtg==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} - peerDependencies: - yjs: ^13.5.6 + node-stdlib-browser@1.3.1: + resolution: {integrity: sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw==} + engines: {node: '>=10'} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + nodemon@3.1.11: + resolution: {integrity: sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==} engines: {node: '>=10'} + hasBin: true - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} - engines: {node: '>= 14.6'} + nopt@9.0.0: + resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} engines: {node: '>=10'} - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - yargs@17.7.1: - resolution: {integrity: sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==} - engines: {node: '>=12'} + normalize-url@8.1.1: + resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} + engines: {node: '>=14.16'} - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + npm-bundled@5.0.0: + resolution: {integrity: sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==} + engines: {node: ^20.17.0 || >=22.9.0} - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + npm-install-checks@8.0.0: + resolution: {integrity: sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==} + engines: {node: ^20.17.0 || >=22.9.0} - yazl@2.5.1: - resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} + npm-normalize-package-bin@5.0.0: + resolution: {integrity: sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==} + engines: {node: ^20.17.0 || >=22.9.0} - yjs@13.6.19: - resolution: {integrity: sha512-GNKw4mEUn5yWU2QPHRx8jppxmCm9KzbBhB4qJLUJFiiYD0g/tDVgXQ7aPkyh01YO28kbs2J/BEbWBagjuWyejw==} - engines: {node: '>=16.0.0', npm: '>=8.0.0'} + npm-package-arg@13.0.2: + resolution: {integrity: sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==} + engines: {node: ^20.17.0 || >=22.9.0} - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + npm-packlist@10.0.4: + resolution: {integrity: sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==} + engines: {node: ^20.17.0 || >=22.9.0} - yocto-queue@1.2.2: - resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} - engines: {node: '>=12.20'} + npm-pick-manifest@11.0.3: + resolution: {integrity: sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==} + engines: {node: ^20.17.0 || >=22.9.0} - yoctocolors-cjs@2.1.3: - resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} - engines: {node: '>=18'} + npm-registry-fetch@19.1.1: + resolution: {integrity: sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==} + engines: {node: ^20.17.0 || >=22.9.0} - yoctocolors@2.1.2: - resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} engines: {node: '>=18'} - yoga-layout@3.2.1: - resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + npm@10.9.4: + resolution: {integrity: sha512-OnUG836FwboQIbqtefDNlyR0gTHzIfwRfE3DuiNewBvnMnWEpB0VEXwBlFVgqpNzIgYo/MHh3d2Hel/pszapAA==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + bundledDependencies: + - '@isaacs/string-locale-compare' + - '@npmcli/arborist' + - '@npmcli/config' + - '@npmcli/fs' + - '@npmcli/map-workspaces' + - '@npmcli/package-json' + - '@npmcli/promise-spawn' + - '@npmcli/redact' + - '@npmcli/run-script' + - '@sigstore/tuf' + - abbrev + - archy + - cacache + - chalk + - ci-info + - cli-columns + - fastest-levenshtein + - fs-minipass + - glob + - graceful-fs + - hosted-git-info + - ini + - init-package-json + - is-cidr + - json-parse-even-better-errors + - libnpmaccess + - libnpmdiff + - libnpmexec + - libnpmfund + - libnpmhook + - libnpmorg + - libnpmpack + - libnpmpublish + - libnpmsearch + - libnpmteam + - libnpmversion + - make-fetch-happen + - minimatch + - minipass + - minipass-pipeline + - ms + - node-gyp + - nopt + - normalize-package-data + - npm-audit-report + - npm-install-checks + - npm-package-arg + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - p-map + - pacote + - parse-conflict-json + - proc-log + - qrcode-terminal + - read + - semver + - spdx-expression-parse + - ssri + - supports-color + - tar + - text-table + - tiny-relative-date + - treeverse + - validate-npm-package-name + - which + - write-file-atomic - zod-to-json-schema@3.20.4: - resolution: {integrity: sha512-Un9+kInJ2Zt63n6Z7mLqBifzzPcOyX+b+Exuzf7L1+xqck9Q2EPByyTRduV3kmSPaXaRer1JCsucubpgL1fipg==} - peerDependencies: - zod: ^3.20.0 + npm@8.19.4: + resolution: {integrity: sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + bundledDependencies: + - '@isaacs/string-locale-compare' + - '@npmcli/arborist' + - '@npmcli/ci-detect' + - '@npmcli/config' + - '@npmcli/fs' + - '@npmcli/map-workspaces' + - '@npmcli/package-json' + - '@npmcli/run-script' + - abbrev + - archy + - cacache + - chalk + - chownr + - cli-columns + - cli-table3 + - columnify + - fastest-levenshtein + - fs-minipass + - glob + - graceful-fs + - hosted-git-info + - ini + - init-package-json + - is-cidr + - json-parse-even-better-errors + - libnpmaccess + - libnpmdiff + - libnpmexec + - libnpmfund + - libnpmhook + - libnpmorg + - libnpmpack + - libnpmpublish + - libnpmsearch + - libnpmteam + - libnpmversion + - make-fetch-happen + - minimatch + - minipass + - minipass-pipeline + - mkdirp + - mkdirp-infer-owner + - ms + - node-gyp + - nopt + - npm-audit-report + - npm-install-checks + - npm-package-arg + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - npmlog + - opener + - p-map + - pacote + - parse-conflict-json + - proc-log + - qrcode-terminal + - read + - read-package-json + - read-package-json-fast + - readdir-scoped-modules + - rimraf + - semver + - ssri + - tar + - text-table + - tiny-relative-date + - treeverse + - validate-npm-package-name + - which + - write-file-atomic - zod-to-json-schema@3.25.1: - resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} - peerDependencies: - zod: ^3.25 || ^4 + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - zod-validation-error@4.0.2: - resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} - engines: {node: '>=18.0.0'} + nuxt@4.3.1: + resolution: {integrity: sha512-bl+0rFcT5Ax16aiWFBFPyWcsTob19NTZaDL5P6t0MQdK63AtgS6fN6fwvwdbXtnTk6/YdCzlmuLzXhSM22h0OA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true peerDependencies: - zod: ^3.25.0 || ^4.0.0 + '@parcel/watcher': ^2.1.0 + '@types/node': '>=18.12.0' + peerDependenciesMeta: + '@parcel/watcher': + optional: true + '@types/node': + optional: true - zod@3.21.4: - resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} + nypm@0.6.5: + resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} + engines: {node: '>=18'} + hasBin: true - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} - zod@3.24.0: - resolution: {integrity: sha512-Hz+wiY8yD0VLA2k/+nsg2Abez674dDGTai33SwNvMPuf9uIrBC9eFgIMQxBBbHFxVXi8W+5nX9DcAh9YNSQm/w==} + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} - zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} -snapshots: + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} - '@acemir/cssom@0.9.31': {} + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} - '@adobe/css-tools@4.4.4': {} + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} - '@alcalzone/ansi-tokenize@0.2.4': - dependencies: - ansi-styles: 6.2.3 - is-fullwidth-code-point: 5.1.0 + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} - '@alloc/quick-lru@5.2.0': {} + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} - '@ark/schema@0.55.0': - dependencies: - '@ark/util': 0.55.0 + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - '@ark/schema@0.56.0': - dependencies: - '@ark/util': 0.56.0 + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - '@ark/util@0.55.0': {} + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} - '@ark/util@0.56.0': {} + ofetch@2.0.0-alpha.3: + resolution: {integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==} - '@asamuzakjp/css-color@4.1.1': - dependencies: - '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) - '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) - '@csstools/css-tokenizer': 3.0.4 - lru-cache: 11.2.5 + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - '@asamuzakjp/dom-selector@6.7.7': - dependencies: - '@asamuzakjp/nwsapi': 2.3.9 - bidi-js: 1.0.3 - css-tree: 3.1.0 - is-potential-custom-element-name: 1.0.1 - lru-cache: 11.2.5 + on-change@6.0.2: + resolution: {integrity: sha512-08+12qcOVEA0fS9g/VxKS27HaT94nRutUT77J2dr8zv/unzXopvhBuF8tNLWsoLQ5IgrQ6eptGeGqUYat82U1w==} + engines: {node: '>=20'} - '@asamuzakjp/nwsapi@2.3.9': {} + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} - '@asyncapi/parser@3.4.0': - dependencies: - '@asyncapi/specs': 6.11.1 - '@openapi-contrib/openapi-schema-to-json-schema': 3.2.0 - '@stoplight/json': 3.21.0 - '@stoplight/json-ref-readers': 1.2.2 - '@stoplight/json-ref-resolver': 3.1.6 - '@stoplight/spectral-core': 1.21.0 - '@stoplight/spectral-functions': 1.10.1 - '@stoplight/spectral-parsers': 1.0.5 - '@stoplight/spectral-ref-resolver': 1.0.5 - '@stoplight/types': 13.20.0 - '@types/json-schema': 7.0.15 - '@types/urijs': 1.19.26 - ajv: 8.17.1 - ajv-errors: 3.0.0(ajv@8.17.1) - ajv-formats: 2.1.1(ajv@8.17.1) - avsc: 5.7.9 - js-yaml: 4.1.1 - jsonpath-plus: 10.3.0 - node-fetch: 2.6.7 - transitivePeerDependencies: - - encoding + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} - '@asyncapi/specs@6.11.1': - dependencies: - '@types/json-schema': 7.0.15 + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} - '@asyncapi/specs@6.8.1': - dependencies: - '@types/json-schema': 7.0.15 + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - '@aws-crypto/crc32@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 - tslib: 2.8.1 + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} - '@aws-crypto/crc32c@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 - tslib: 2.8.1 + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} - '@aws-crypto/sha1-browser@5.2.0': - dependencies: - '@aws-crypto/supports-web-crypto': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-locate-window': 3.965.4 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} - '@aws-crypto/sha256-browser@5.2.0': - dependencies: - '@aws-crypto/sha256-js': 5.2.0 - '@aws-crypto/supports-web-crypto': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-locate-window': 3.965.4 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} - '@aws-crypto/sha256-js@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 - tslib: 2.8.1 + oniguruma-to-es@4.3.4: + resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} - '@aws-crypto/supports-web-crypto@5.2.0': - dependencies: - tslib: 2.8.1 + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} - '@aws-crypto/util@5.2.0': - dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 + open@11.0.0: + resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + engines: {node: '>=20'} - '@aws-sdk/client-s3@3.988.0': - dependencies: - '@aws-crypto/sha1-browser': 5.2.0 - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.8 - '@aws-sdk/credential-provider-node': 3.972.7 - '@aws-sdk/middleware-bucket-endpoint': 3.972.3 - '@aws-sdk/middleware-expect-continue': 3.972.3 - '@aws-sdk/middleware-flexible-checksums': 3.972.6 - '@aws-sdk/middleware-host-header': 3.972.3 - '@aws-sdk/middleware-location-constraint': 3.972.3 - '@aws-sdk/middleware-logger': 3.972.3 - '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-sdk-s3': 3.972.8 - '@aws-sdk/middleware-ssec': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.8 - '@aws-sdk/region-config-resolver': 3.972.3 - '@aws-sdk/signature-v4-multi-region': 3.988.0 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.988.0 - '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.6 - '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 - '@smithy/eventstream-serde-browser': 4.2.8 - '@smithy/eventstream-serde-config-resolver': 4.3.8 - '@smithy/eventstream-serde-node': 4.2.8 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/hash-blob-browser': 4.2.9 - '@smithy/hash-node': 4.2.8 - '@smithy/hash-stream-node': 4.2.8 - '@smithy/invalid-dependency': 4.2.8 - '@smithy/md5-js': 4.2.8 - '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 - '@smithy/middleware-serde': 4.2.9 - '@smithy/middleware-stack': 4.2.8 - '@smithy/node-config-provider': 4.3.8 - '@smithy/node-http-handler': 4.4.10 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 - '@smithy/util-endpoints': 3.2.8 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-retry': 4.2.8 - '@smithy/util-stream': 4.5.12 - '@smithy/util-utf8': 4.2.0 - '@smithy/util-waiter': 4.2.8 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} - '@aws-sdk/client-sso@3.988.0': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.8 - '@aws-sdk/middleware-host-header': 3.972.3 - '@aws-sdk/middleware-logger': 3.972.3 - '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.8 - '@aws-sdk/region-config-resolver': 3.972.3 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.988.0 - '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.6 - '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/hash-node': 4.2.8 - '@smithy/invalid-dependency': 4.2.8 - '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 - '@smithy/middleware-serde': 4.2.9 - '@smithy/middleware-stack': 4.2.8 - '@smithy/node-config-provider': 4.3.8 - '@smithy/node-http-handler': 4.4.10 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 - '@smithy/util-endpoints': 3.2.8 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-retry': 4.2.8 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} - '@aws-sdk/core@3.973.8': - dependencies: - '@aws-sdk/types': 3.973.1 - '@aws-sdk/xml-builder': 3.972.4 - '@smithy/core': 3.23.0 - '@smithy/node-config-provider': 4.3.8 - '@smithy/property-provider': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/signature-v4': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/util-base64': 4.3.0 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} - '@aws-sdk/crc64-nvme@3.972.0': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 + ora@9.3.0: + resolution: {integrity: sha512-lBX72MWFduWEf7v7uWf5DHp9Jn5BI8bNPGuFgtXMmr2uDz2Gz2749y3am3agSDdkhHPHYmmxEGSKH85ZLGzgXw==} + engines: {node: '>=20'} - '@aws-sdk/credential-provider-env@3.972.6': - dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + ordered-binary@1.6.1: + resolution: {integrity: sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==} - '@aws-sdk/credential-provider-http@3.972.8': - dependencies: + orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + + os-browserify@0.3.0: + resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + oxc-minify@0.112.0: + resolution: {integrity: sha512-rkVSeeIRSt+RYI9uX6xonBpLUpvZyegxIg0UL87ev7YAfUqp7IIZlRjkgQN5Us1lyXD//TOo0Dcuuro/TYOWoQ==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-parser@0.112.0: + resolution: {integrity: sha512-7rQ3QdJwobMQLMZwQaPuPYMEF2fDRZwf51lZ//V+bA37nejjKW5ifMHbbCwvA889Y4RLhT+/wLJpPRhAoBaZYw==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-transform@0.112.0: + resolution: {integrity: sha512-cIRRvZgrHfsAHrkt8LWdAX4+Do8R0MzQSfeo9yzErzHeYiuyNiP4PCTPbOy/wBXL4MYzt3ebrBa5jt3akQkKAg==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-walker@0.7.0: + resolution: {integrity: sha512-54B4KUhrzbzc4sKvKwVYm7E2PgeROpGba0/2nlNZMqfDyca+yOor5IMb4WLGBatGDT0nkzYdYuzylg7n3YfB7A==} + peerDependencies: + oxc-parser: '>=0.98.0' + + p-any@4.0.0: + resolution: {integrity: sha512-S/B50s+pAVe0wmEZHmBs/9yJXeZ5KhHzOsgKzt0hRdgkoR3DxW9ts46fcsWi/r3VnzsnkKS7q4uimze+zjdryw==} + engines: {node: '>=12.20'} + + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-each-series@3.0.0: + resolution: {integrity: sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==} + engines: {node: '>=12'} + + p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} + engines: {node: '>=16.17'} + + p-filter@4.1.0: + resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==} + engines: {node: '>=18'} + + p-is-promise@3.0.0: + resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} + engines: {node: '>=8'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + + p-reduce@2.1.0: + resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} + engines: {node: '>=8'} + + p-reduce@3.0.0: + resolution: {integrity: sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==} + engines: {node: '>=12'} + + p-retry@6.2.1: + resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} + engines: {node: '>=16.17'} + + p-some@6.0.0: + resolution: {integrity: sha512-CJbQCKdfSX3fIh8/QKgS+9rjm7OBNUTmwWswAFQAhc8j1NR1dsEDETUEuVUtQHZpV+J03LqWBEwvu0g1Yn+TYg==} + engines: {node: '>=12.20'} + + p-timeout@5.1.0: + resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} + engines: {node: '>=12'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + pac-proxy-agent@7.2.0: + resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} + engines: {node: '>= 14'} + + pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + pacote@21.3.1: + resolution: {integrity: sha512-O0EDXi85LF4AzdjG74GUwEArhdvawi/YOHcsW6IijKNj7wm8IvEWNF5GnfuxNpQ/ZpO3L37+v8hqdVh8GgWYhg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-asn1@5.1.9: + resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} + engines: {node: '>= 0.10'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-filepath@1.0.2: + resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} + engines: {node: '>=0.8'} + + parse-imports-exports@0.2.4: + resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse-node-version@1.0.1: + resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} + engines: {node: '>= 0.10'} + + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + + parse-semver@1.1.1: + resolution: {integrity: sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==} + + parse-statements@1.0.11: + resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} + + parse-url@8.1.0: + resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==} + + parse5-html-rewriting-stream@8.0.0: + resolution: {integrity: sha512-wzh11mj8KKkno1pZEu+l2EVeWsuKDfR5KNWZOTsslfUX8lPDZx77m9T0kIoAVkFtD1nx6YF8oh4BnPHvxMtNMw==} + + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5-sax-parser@8.0.0: + resolution: {integrity: sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + parse5@8.0.0: + resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + patch-console@2.0.0: + resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-root-regex@0.1.2: + resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} + engines: {node: '>=0.10.0'} + + path-root@0.1.1: + resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} + engines: {node: '>=0.10.0'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + path-to-regexp@3.3.0: + resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} + + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} + + pdfjs-dist@5.4.624: + resolution: {integrity: sha512-sm6TxKTtWv1Oh6n3C6J6a8odejb5uO4A4zo/2dgkHuC0iu8ZMAXOezEODkVaoVp8nX1Xzr+0WxFJJmUr45hQzg==} + engines: {node: '>=20.16.0 || >=22.3.0'} + + peek-stream@1.1.3: + resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pify@6.1.0: + resolution: {integrity: sha512-KocF8ve28eFjjuBKKGvzOBGzG8ew2OqOOSxTTZhirkzH7h3BI1vyzqlR0qbfcDBve1Yzo3FVlWUAtCRrbVN8Fw==} + engines: {node: '>=14.16'} + + pinia@2.3.1: + resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==} + peerDependencies: + typescript: '>=4.4.4' + vue: 3.5.25 + peerDependenciesMeta: + typescript: + optional: true + + pino-abstract-transport@1.2.0: + resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + + pino@9.14.0: + resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} + hasBin: true + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + piscina@5.1.4: + resolution: {integrity: sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==} + engines: {node: '>=20.x'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + pkg-conf@2.1.0: + resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} + engines: {node: '>=4'} + + pkg-dir@5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + pkijs@3.3.3: + resolution: {integrity: sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==} + engines: {node: '>=16.0.0'} + + playwright-core@1.58.1: + resolution: {integrity: sha512-bcWzOaTxcW+VOOGBCQgnaKToLJ65d6AqfLVKEWvexyS3AS6rbXl+xdpYRMGSRBClPvyj44njOWoxjNdL/H9UNg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.58.1: + resolution: {integrity: sha512-+2uTZHxSCcxjvGc5C891LrS1/NlxglGxzrC4seZiVjcYVQfUa87wBL6rTDqzGjuoWNjnBzRqKmF6zRYGMvQUaQ==} + engines: {node: '>=18'} + hasBin: true + + pony-cause@1.1.1: + resolution: {integrity: sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==} + engines: {node: '>=12.0.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-calc@10.1.1: + resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@7.0.6: + resolution: {integrity: sha512-oXM2mdx6IBTRm39797QguYzVEWzbdlFiMNfq88fCCN1Wepw3CYmJ/1/Ifa/KjWo+j5ZURDl2NTldLJIw51IeNQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-convert-values@7.0.9: + resolution: {integrity: sha512-l6uATQATZaCa0bckHV+r6dLXfWtUBKXxO3jK+AtxxJJtgMPD+VhhPCCx51I4/5w8U5uHV67g3w7PXj+V3wlMlg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-comments@7.0.6: + resolution: {integrity: sha512-Sq+Fzj1Eg5/CPf1ERb0wS1Im5cvE2gDXCE+si4HCn1sf+jpQZxDI4DXEp8t77B/ImzDceWE2ebJQFXdqZ6GRJw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-duplicates@7.0.2: + resolution: {integrity: sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-empty@7.0.1: + resolution: {integrity: sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-overridden@7.0.1: + resolution: {integrity: sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-loader@8.2.0: + resolution: {integrity: sha512-tHX+RkpsXVcc7st4dSdDGliI+r4aAQDuv+v3vFYHixb6YgjreG5AG4SEB0kDK8u2s6htqEEpKlkhSBUTvWKYnA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + postcss-media-query-parser@0.2.3: + resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} + + postcss-merge-longhand@7.0.5: + resolution: {integrity: sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-merge-rules@7.0.8: + resolution: {integrity: sha512-BOR1iAM8jnr7zoQSlpeBmCsWV5Uudi/+5j7k05D0O/WP3+OFMPD86c1j/20xiuRtyt45bhxw/7hnhZNhW2mNFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-font-values@7.0.1: + resolution: {integrity: sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-gradients@7.0.1: + resolution: {integrity: sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-params@7.0.6: + resolution: {integrity: sha512-YOn02gC68JijlaXVuKvFSCvQOhTpblkcfDre2hb/Aaa58r2BIaK4AtE/cyZf2wV7YKAG+UlP9DT+By0ry1E4VQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-selectors@7.0.6: + resolution: {integrity: sha512-lIbC0jy3AAwDxEgciZlBullDiMBeBCT+fz5G8RcA9MWqh/hfUkpOI3vNDUNEZHgokaoiv0juB9Y8fGcON7rU/A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-nested-import@1.3.0: + resolution: {integrity: sha512-n0uARfX3SRntgA1A+fD1n+JvquCbbD43P5EOrRqbuVgzl2xVXA1J90gdmeZ57Xg7/GYs/j9GRKxQD9dzeBP7AA==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.0 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-normalize-charset@7.0.1: + resolution: {integrity: sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-display-values@7.0.1: + resolution: {integrity: sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-positions@7.0.1: + resolution: {integrity: sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-repeat-style@7.0.1: + resolution: {integrity: sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-string@7.0.1: + resolution: {integrity: sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-timing-functions@7.0.1: + resolution: {integrity: sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-unicode@7.0.6: + resolution: {integrity: sha512-z6bwTV84YW6ZvvNoaNLuzRW4/uWxDKYI1iIDrzk6D2YTL7hICApy+Q1LP6vBEsljX8FM7YSuV9qI79XESd4ddQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-url@7.0.1: + resolution: {integrity: sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-whitespace@7.0.1: + resolution: {integrity: sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-ordered-values@7.0.2: + resolution: {integrity: sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-prefixwrap@1.57.2: + resolution: {integrity: sha512-HKfOJJCFUtZiUu6CaWmxb6JxYZetn8McOuFUa0t4CJ0ZtcxCPlD8COSPu6804xNc4WPBu34BI0h96wkONLd9lQ==} + peerDependencies: + postcss: '*' + + postcss-reduce-initial@7.0.6: + resolution: {integrity: sha512-G6ZyK68AmrPdMB6wyeA37ejnnRG2S8xinJrZJnOv+IaRKf6koPAVbQsiC7MfkmXaGmF1UO+QCijb27wfpxuRNg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-reduce-transforms@7.0.1: + resolution: {integrity: sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + engines: {node: '>=18.0'} + peerDependencies: + postcss: ^8.4.31 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-svgo@7.1.1: + resolution: {integrity: sha512-zU9H9oEDrUFKa0JB7w+IYL7Qs9ey1mZyjhbf0KLxwJDdDRtoPvCmaEfknzqfHj44QS9VD6c5sJnBAVYTLRg/Sg==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.4.32 + + postcss-unique-selectors@7.0.5: + resolution: {integrity: sha512-3QoYmEt4qg/rUWDn6Tc8+ZVPmbp4G1hXDtCNWDx0st8SjtCbRcxRXDDM1QrEiXGG3A45zscSJFb4QH90LViyxg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + pretty-bytes@7.1.0: + resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==} + engines: {node: '>=20'} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + + proc-log@6.1.0: + resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process-warning@4.0.1: + resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} + + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + prosemirror-commands@1.7.1: + resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} + + prosemirror-dropcursor@1.8.2: + resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} + + prosemirror-gapcursor@1.4.0: + resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==} + + prosemirror-history@1.5.0: + resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} + + prosemirror-inputrules@1.5.1: + resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} + + prosemirror-keymap@1.2.3: + resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + + prosemirror-model@1.25.4: + resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} + + prosemirror-schema-basic@1.2.4: + resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} + + prosemirror-schema-list@1.5.1: + resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + + prosemirror-state@1.4.4: + resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} + + prosemirror-tables@1.8.5: + resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} + + prosemirror-test-builder@1.1.1: + resolution: {integrity: sha512-DJ1+4TNTE9ZcYN/ozXCaWJVrGA99UttMoVvZuidvAotRg7FaiNtEYxL/vlDwfZDRnzJDXNYhmM3XPv3EweK7yA==} + + prosemirror-transform@1.11.0: + resolution: {integrity: sha512-4I7Ce4KpygXb9bkiPS3hTEk4dSHorfRw8uI0pE8IhxlK2GXsqv5tIA7JUSxtSu7u8APVOTtbUBxTmnHIxVkIJw==} + + prosemirror-view@1.41.5: + resolution: {integrity: sha512-UDQbIPnDrjE8tqUBbPmCOZgtd75htE6W3r0JCmY9bL6W1iemDM37MZEKC49d+tdQ0v/CKx4gjxLoLsfkD2NiZA==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + protocols@2.0.2: + resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-agent@6.5.0: + resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} + engines: {node: '>= 14'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + + public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + + public-ip@5.0.0: + resolution: {integrity: sha512-xaH3pZMni/R2BG7ZXXaWS9Wc9wFlhyDVJF47IJ+3ali0TGv+2PsckKxbmo+rnx3ZxiV2wblVhtdS3bohAP6GGw==} + engines: {node: ^14.13.1 || >=16.0.0} + + pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + + pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + puppeteer-core@22.14.0: + resolution: {integrity: sha512-rl4tOY5LcA3e374GAlsGGHc05HL3eGNf5rZ+uxkl6id9zVZKcwcp1Z+Nd6byb6WPiPeecT/dwz8f/iUm+AZQSw==} + engines: {node: '>=18'} + + puppeteer@22.14.0: + resolution: {integrity: sha512-MGTR6/pM8zmWbTdazb6FKnwIihzsSEXBPH49mFFU96DNZpQOevCAZMnjBZGlZRGRzRK6aADCavR6SQtrbv5dQw==} + engines: {node: '>=18'} + deprecated: < 24.15.0 is no longer supported + hasBin: true + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + qs@6.14.1: + resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + engines: {node: '>=0.6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + querystring-es3@0.2.1: + resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} + engines: {node: '>=0.4.x'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + + range-parser@1.2.0: + resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} + engines: {node: '>= 0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + rc9@3.0.0: + resolution: {integrity: sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-reconciler@0.32.0: + resolution: {integrity: sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^19.1.0 + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + read-package-up@11.0.0: + resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} + engines: {node: '>=18'} + + read-pkg-up@9.1.0: + resolution: {integrity: sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + read-pkg@7.1.0: + resolution: {integrity: sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==} + engines: {node: '>=12.20'} + + read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} + + read@1.0.7: + resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} + engines: {node: '>=0.8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regex-parser@2.3.1: + resolution: {integrity: sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + registry-auth-token@3.3.2: + resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==} + + registry-auth-token@4.2.2: + resolution: {integrity: sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==} + engines: {node: '>=6.0.0'} + + registry-auth-token@5.1.1: + resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} + engines: {node: '>=14'} + + registry-url@3.1.0: + resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} + engines: {node: '>=0.10.0'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.0: + resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} + hasBin: true + + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + + rehype-minify-whitespace@6.0.2: + resolution: {integrity: sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + rehype-remark@10.0.1: + resolution: {integrity: sha512-EmDndlb5NVwXGfUa4c9GPK+lXeItTilLhE6ADSaQuHr4JUlKw9MidzGzx4HpqZrNCt6vnHmEifXQiiA+CEnjYQ==} + + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@3.0.1: + resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} + + remark-gfm@4.0.0: + resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-html@15.0.2: + resolution: {integrity: sha512-/CIOI7wzHJzsh48AiuIyIe1clxVkUtreul73zcCXLub0FmnevQE0UMFDQm7NUx8/3rl/4zCshlMfqBdWScQthw==} + + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + + remark-mdx-remove-esm@1.2.2: + resolution: {integrity: sha512-YSaUwqiuJuD6S9XTAD6zmO4JJJZJgsRAdsl2drZO8/ssAVv0HXAg4vkSgHZAP46ORh8ERPFQrC7JWlbkwBwu1A==} + peerDependencies: + unified: ^11 + + remark-mdx@3.0.1: + resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==} + + remark-mdx@3.1.0: + resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@10.0.2: + resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-reference-links@6.0.1: + resolution: {integrity: sha512-34wY2C6HXSuKVTRtyJJwefkUD8zBOZOSHFZ4aSTnU2F656gr9WeuQ2dL6IJDK3NPd2F6xKF2t4XXcQY9MygAXg==} + + remark-rehype@11.1.1: + resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@10.0.3: + resolution: {integrity: sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remark-toc@8.0.1: + resolution: {integrity: sha512-7he2VOm/cy13zilnOTZcyAoyoolV26ULlon6XyCFU+vG54Z/LWJnwphj/xKIDLOt66QmJUgTyUvLVHi2aAElyg==} + + remark@14.0.3: + resolution: {integrity: sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==} + + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve-url-loader@5.0.0: + resolution: {integrity: sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==} + engines: {node: '>=12'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + ret@0.5.0: + resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} + engines: {node: '>=10'} + + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} + + rolldown-vite@7.3.1: + resolution: {integrity: sha512-LYzdNAjRHhF2yA4JUQm/QyARyi216N2rpJ0lJZb8E9FU2y5v6Vk+xq/U4XBOxMefpWixT5H3TslmAHm1rqIq2w==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + esbuild: ^0.27.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + rolldown@1.0.0-beta.53: + resolution: {integrity: sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rolldown@1.0.0-rc.4: + resolution: {integrity: sha512-V2tPDUrY3WSevrvU2E41ijZlpF+5PbZu4giH+VpNraaadsJGHa4fR6IFwsocVwEXDoAdIv5qgPPxgrvKAOIPtA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup-plugin-copy@3.5.0: + resolution: {integrity: sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==} + engines: {node: '>=8.3'} + + rollup-plugin-visualizer@5.14.0: + resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + rolldown: 1.x + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + + rollup-plugin-visualizer@6.0.11: + resolution: {integrity: sha512-TBwVHVY7buHjIKVLqr9scTVFwqZqMXINcCphPwIWKPDCOBIa+jCQfafvbjRJDZgXdq/A996Dy6yGJ/+/NtAXDQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + rolldown: 1.x || ^1.0.0-beta + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + + rollup@4.57.1: + resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + + rou3@0.7.12: + resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-regex2@5.0.0: + resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} + + safe-stable-stringify@1.1.1: + resolution: {integrity: sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass-loader@16.0.7: + resolution: {integrity: sha512-w6q+fRHourZ+e+xA1kcsF27iGM6jdB8teexYCfdUw0sYgcDNeZESnDNT9sUmmPm3ooziwUJXGwZJSTF3kOdBfA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || ^1.0.0 || ^2.0.0-0 + node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + sass: ^1.3.0 + sass-embedded: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + node-sass: + optional: true + sass: + optional: true + sass-embedded: + optional: true + webpack: + optional: true + + sass@1.97.3: + resolution: {integrity: sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==} + engines: {node: '>=14.0.0'} + hasBin: true + + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} + + sax@1.5.0: + resolution: {integrity: sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==} + engines: {node: '>=11.0.0'} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + secure-json-parse@4.1.0: + resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} + + seemly@0.3.10: + resolution: {integrity: sha512-2+SMxtG1PcsL0uyhkumlOU6Qo9TAQ/WyH7tthnPIOQB05/12jz9naq6GZ6iZ6ApVsO3rr2gsnTf3++OV63kE1Q==} + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + selfsigned@5.5.0: + resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} + engines: {node: '>=18'} + + semantic-release-commit-filter@1.0.2: + resolution: {integrity: sha512-LpIB1UN78oRmJnqgPdvA/qRgVitih5V1Ybyszv8GcOBAJWJBHGWI1PmSrOfdEmbf1ZvGkdK/NNDdBHbuSQqSyQ==} + + semantic-release-linear-app@0.7.1: + resolution: {integrity: sha512-UmFCNIFySR/6ZZ2t0RYUwBTLQrLwp9c5eEgePwN7PAU9wLC0Oc3KgZ+bElpyhl9rPOhvhBJhSGsoPNt8Sa2tBw==} + engines: {node: '>=18'} + peerDependencies: + semantic-release: '>=20.0.0' + + semantic-release-pnpm@1.0.2: + resolution: {integrity: sha512-jYG+287heOL/uAp8mgwx3wSe+9K9J3RNSnbDNoOd2kcmEDM9HLfA2VnOmv6fx/X3/KijBNITPXQogYcNjLvf3Q==} + engines: {node: '>=16 || ^14.17'} + peerDependencies: + semantic-release: '>=19.0.0' + + semantic-release@24.2.9: + resolution: {integrity: sha512-phCkJ6pjDi9ANdhuF5ElS10GGdAKY6R1Pvt9lT3SFhOwM4T7QZE7MLpBDbNruUx/Q3gFD92/UOFringGipRqZA==} + engines: {node: '>=20.8.1'} + hasBin: true + + semver-diff@5.0.0: + resolution: {integrity: sha512-0HbGtOm+S7T6NGQ/pxJSJipJvc4DK3FcRVMRkhsIwJDJ4Jcz5DQC1cPPzB5GhzyHjwttW878HaWQq46CkL3cqg==} + engines: {node: '>=12'} + deprecated: Deprecated as the semver package now supports this built-in. + + semver-regex@4.0.5: + resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} + engines: {node: '>=12'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serialize-error@12.0.0: + resolution: {integrity: sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==} + engines: {node: '>=18'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serialize-javascript@7.0.4: + resolution: {integrity: sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg==} + engines: {node: '>=20.0.0'} + + seroval@1.5.1: + resolution: {integrity: sha512-OwrZRZAfhHww0WEnKHDY8OM0U/Qs8OTfIDWhUD4BLpNJUfXK4cGmjiagGze086m+mhI+V2nD0gfbHEnJjb9STA==} + engines: {node: '>=10'} + + serve-handler@6.1.6: + resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==} + + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} + engines: {node: '>= 0.8.0'} + + serve-placeholder@2.0.2: + resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + serve@14.2.5: + resolution: {integrity: sha512-Qn/qMkzCcMFVPb60E/hQy+iRLpiU8PamOfOSYoAHmmF+fFFmpPpqa6Oci2iWYpTdOUM3VF+TINud7CfbQnsZbA==} + engines: {node: '>= 14'} + hasBin: true + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + sharp-ico@0.1.5: + resolution: {integrity: sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + shiki@3.22.0: + resolution: {integrity: sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + signale@1.4.0: + resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} + engines: {node: '>=6'} + + signature_pad@5.1.3: + resolution: {integrity: sha512-zyxW5vuJVnQdGcU+kAj9FYl7WaAunY3kA5S7mPg0xJiujL9+sPAWfSQHS5tXaJXDUa4FuZeKhfdCDQ6K3wfkpQ==} + + sigstore@4.1.0: + resolution: {integrity: sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==} + engines: {node: ^20.17.0 || >=22.9.0} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-eval@1.0.1: + resolution: {integrity: sha512-LH7FpTAkeD+y5xQC4fzS+tFtaNlvt3Ib1zKzvhjv/Y+cioV4zIuw4IZr2yhRLu67CWL7FR9/6KXKnjRoZTvGGQ==} + engines: {node: '>=12'} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + simple-git@3.32.3: + resolution: {integrity: sha512-56a5oxFdWlsGygOXHWrG+xjj5w9ZIt2uQbzqiIGdR/6i5iococ7WQ/bNPzWxCJdEUGUCmyMH0t9zMpRJTaKxmw==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} + engines: {node: '>=18'} + + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + smob@1.6.1: + resolution: {integrity: sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==} + engines: {node: '>=20.0.0'} + + socket.io-adapter@2.5.6: + resolution: {integrity: sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==} + + socket.io-parser@4.2.5: + resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} + engines: {node: '>=10.0.0'} + + socket.io@4.7.2: + resolution: {integrity: sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==} + engines: {node: '>=10.2.0'} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sonic-boom@3.8.1: + resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-loader@5.0.0: + resolution: {integrity: sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.72.1 + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spawn-error-forwarder@1.0.0: + resolution: {integrity: sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + + spdx-license-ids@3.0.22: + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + split2@1.0.0: + resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + srvx@0.11.9: + resolution: {integrity: sha512-97wWJS6F0KTKAhDlHVmBzMvlBOp5FiNp3XrLoodIgYJpXxgG5tE9rX4Pg7s46n2shI4wtEsMATTS1+rI3/ubzA==} + engines: {node: '>=20.16.0'} + hasBin: true + + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + ssri@13.0.1: + resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + stable-hash-x@0.2.0: + resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + engines: {node: '>=12.0.0'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + stdin-discarder@0.3.1: + resolution: {integrity: sha512-reExS1kSGoElkextOcPkel4NE99S0BWxjUHQeDFnR8S993JxpPX7KU4MNmO19NXhlJp+8dmdCbKQVNgLJh2teA==} + engines: {node: '>=18'} + + steno@0.4.4: + resolution: {integrity: sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + stream-browserify@3.0.0: + resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + + stream-combiner2@1.1.1: + resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} + + stream-http@3.2.0: + resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + streamx@2.23.0: + resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.2.0: + resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} + engines: {node: '>=20'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + + strnum@2.1.2: + resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + + structured-clone-es@1.0.0: + resolution: {integrity: sha512-FL8EeKFFyNQv5cMnXI31CIMCsFarSVI2bF0U0ImeNE3g/F1IvJQyqzOXxPBRXiwQfyBTlbNe88jh1jFW0O/jiQ==} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylehacks@7.0.8: + resolution: {integrity: sha512-I3f053GBLIiS5Fg6OMFhq/c+yW+5Hc2+1fgq7gElDMMSqwlRb3tBf2ef6ucLStYRpId4q//bQO1FjcyNyy4yDQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + super-regex@1.1.0: + resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} + engines: {node: '>=18'} + + superdoc@1.11.0: + resolution: {integrity: sha512-DY5uObI50Itfxjjog9h8FQKGWLx0o0au2H0h9hbNtBrNXvg8mAeQvekSgYgwmL7xIW+juo/ZMSGY035eLDMmnw==} + peerDependencies: + '@hocuspocus/provider': ^2.13.6 + pdfjs-dist: '>=4.3.136 <=4.6.82' + y-prosemirror: ^1.3.7 + yjs: 13.6.19 + + superdoc@1.18.0: + resolution: {integrity: sha512-RRkjsq0+Mb4oZwKZR+6HAuLF4LKkX6UQ8onoerm/LjdOqw00hPL2e5A7WY9yUxMaM3couW1UstUe4YlGeBtcIg==} + peerDependencies: + '@hocuspocus/provider': ^2.13.6 + pdfjs-dist: ^5.4.296 + y-prosemirror: ^1.3.7 + yjs: 13.6.19 + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + + supports-hyperlinks@3.2.0: + resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} + engines: {node: '>=14.18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svgo@4.0.1: + resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} + engines: {node: '>=16'} + hasBin: true + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + system-architecture@0.1.0: + resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} + engines: {node: '>=18'} + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + tailwindcss@3.4.4: + resolution: {integrity: sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==} + engines: {node: '>=14.0.0'} + hasBin: true + + tailwindcss@4.2.1: + resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-fs@3.1.1: + resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + tar@6.1.15: + resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} + engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + tar@7.5.11: + resolution: {integrity: sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==} + engines: {node: '>=18'} + + temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + + temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + + tempy@1.0.1: + resolution: {integrity: sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==} + engines: {node: '>=10'} + + tempy@3.2.0: + resolution: {integrity: sha512-d79HhZya5Djd7am0q+W4RTsSU+D/aJzM+4Y4AGJGuGlgM2L6sx5ZvOYTmZjqPhrDrV6xJTtRSm1JCLj6V6LHLQ==} + engines: {node: '>=14.16'} + + terser-webpack-plugin@5.3.17: + resolution: {integrity: sha512-YR7PtUp6GMU91BgSJmlaX/rS2lGDbAF7D+Wtq7hRO+MiljNmodYvqslzCFiYVAgW+Qoaaia/QUIP4lGXufjdZw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + + text-extensions@2.4.0: + resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} + engines: {node: '>=8'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thingies@2.5.0: + resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} + + timers-browserify@2.0.12: + resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} + engines: {node: '>=0.6.0'} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + + tippy.js@6.3.7: + resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} + + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts-core@7.0.22: + resolution: {integrity: sha512-KgbTDC5wzlL6j/x6np6wCnDSMUq4kucHNm00KXPbfNzmllCmtmvtykJHfmgdHntwIeupW04y8s1N/43S1PkQDw==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + + tldts@7.0.22: + resolution: {integrity: sha512-nqpKFC53CgopKPjT6Wfb6tpIcZXHcI6G37hesvikhx0EmUGPkZrujRyAjgnmp1SHNgpQfKVanZ+KfpANFt2Hxw==} + hasBin: true + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + to-data-view@1.1.0: + resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toad-cache@3.7.0: + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} + engines: {node: '>=12'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + + tough-cookie@6.0.0: + resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + engines: {node: '>=16'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + + traverse@0.6.8: + resolution: {integrity: sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==} + engines: {node: '>= 0.4'} + + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + treemate@0.3.11: + resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trim-trailing-lines@2.1.0: + resolution: {integrity: sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + + tty-browserify@0.0.1: + resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} + + tuf-js@4.1.0: + resolution: {integrity: sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + twoslash-protocol@0.3.6: + resolution: {integrity: sha512-FHGsJ9Q+EsNr5bEbgG3hnbkvEBdW5STgPU824AHUjB4kw0Dn4p8tABT7Ncg1Ie6V0+mDg3Qpy41VafZXcQhWMA==} + + twoslash@0.3.6: + resolution: {integrity: sha512-VuI5OKl+MaUO9UIW3rXKoPgHI3X40ZgB/j12VY6h98Ae1mCBihjPvhOPeJWlxCYcmSbmeZt5ZKkK0dsVtp+6pA==} + peerDependencies: + typescript: ^5.5.0 + + typanion@3.14.0: + resolution: {integrity: sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-fest@5.4.4: + resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==} + engines: {node: '>=20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + type-level-regexp@0.1.17: + resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typed-assert@1.0.9: + resolution: {integrity: sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==} + + typed-rest-client@1.8.11: + resolution: {integrity: sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==} + + typescript-eslint@8.54.0: + resolution: {integrity: sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + ultrahtml@1.6.0: + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + + unc-path-regex@0.1.2: + resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} + engines: {node: '>=0.10.0'} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + unctx@2.5.0: + resolution: {integrity: sha512-p+Rz9x0R7X+CYDkT+Xg8/GhpcShTlU8n+cf9OtOEf7zEQsNcCZO1dPKNRDqvUTaq+P32PMMkxWHwfrxkqfqAYg==} + + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + + underscore@1.13.7: + resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici@7.20.0: + resolution: {integrity: sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==} + engines: {node: '>=20.18.1'} + + undici@7.22.0: + resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} + engines: {node: '>=20.18.1'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + + unhead@2.1.10: + resolution: {integrity: sha512-We8l9uNF8zz6U8lfQaVG70+R/QBfQx1oPIgXin4BtZnK2IQpz6yazQ0qjMNVBDw2ADgF2ea58BtvSK+XX5AS7g==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + + unified@10.1.2: + resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unimport@5.7.0: + resolution: {integrity: sha512-njnL6sp8lEA8QQbZrt+52p/g4X0rw3bnGGmUcJnt1jeG8+iiqO779aGz0PirCtydAIVcuTBRlJ52F0u46z309Q==} + engines: {node: '>=18.12.0'} + + unique-filename@5.0.0: + resolution: {integrity: sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==} + engines: {node: ^20.17.0 || >=22.9.0} + + unique-slug@6.0.0: + resolution: {integrity: sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==} + engines: {node: ^20.17.0 || >=22.9.0} + + unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + unist-builder@3.0.1: + resolution: {integrity: sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ==} + + unist-builder@4.0.0: + resolution: {integrity: sha512-wmRFnH+BLpZnTKpc5L7O67Kac89s9HMrtELpnNaE6TAobq5DTZZs5YaTQfAZBA9bFPECx2uVAPO31c+GVug8mg==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-generated@2.0.1: + resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==} + + unist-util-is@5.2.1: + resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-map@4.0.0: + resolution: {integrity: sha512-HJs1tpkSmRJUzj6fskQrS5oYhBYlmtcvy4SepdDEEsL04FjBrgF0Mgggvxc1/qGBGgW7hRh9+UBK1aqTEnBpIA==} + + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@4.0.4: + resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-remove@4.0.0: + resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} + + unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + unist-util-visit-parents@5.1.3: + resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@4.1.2: + resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universal-user-agent@7.0.3: + resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unix-crypt-td-js@1.1.4: + resolution: {integrity: sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-utils@0.3.1: + resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} + engines: {node: '>=20.19.0'} + + unplugin-vue-router@0.19.2: + resolution: {integrity: sha512-u5dgLBarxE5cyDK/hzJGfpCTLIAyiTXGlo85COuD4Nssj6G7NxS+i9mhCWz/1p/ud1eMwdcUbTXehQe41jYZUA==} + deprecated: 'Merged into vuejs/router. Migrate: https://router.vuejs.org/guide/migration/v4-to-v5.html' + peerDependencies: + '@vue/compiler-sfc': 3.5.25 + vue-router: ^4.6.0 + peerDependenciesMeta: + vue-router: + optional: true + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + + unplugin@3.0.0: + resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==} + engines: {node: ^20.19.0 || >=22.12.0} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + unstorage@1.17.4: + resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + untun@0.1.3: + resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} + hasBin: true + + untyped@2.0.0: + resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} + hasBin: true + + unwasm@0.5.3: + resolution: {integrity: sha512-keBgTSfp3r6+s9ZcSma+0chwxQdmLbB5+dAD9vjtB21UTMYuKAxHXCU1K2CbCtnP09EaWeRvACnXk0EJtUx+hw==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-check@1.5.4: + resolution: {integrity: sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==} + + uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urijs@1.19.11: + resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + + url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + + url-join@5.0.0: + resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + urlpattern-polyfill@10.0.0: + resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + utif2@4.1.0: + resolution: {integrity: sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@7.0.2: + resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} + engines: {node: ^20.17.0 || >=22.9.0} + + validator@13.15.26: + resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==} + engines: {node: '>= 0.10'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vdirs@0.1.8: + resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} + peerDependencies: + vue: 3.5.25 + + verdaccio-audit@13.0.0-next-8.29: + resolution: {integrity: sha512-ZUNONewbFocBq3oWXrwAL8IX4ZovPU70yj0nuYStSVJ9+Vrb74Duc+eI+IIS+jLfyysZe5L0ZAODGN8ny1Lu6w==} + engines: {node: '>=18'} + + verdaccio-htpasswd@13.0.0-next-8.29: + resolution: {integrity: sha512-JBYCaSTQSUws/EXOqNrh7iOyWPrGLTYSeufCS3Y6BOCJbfDiy2Nh8PbstoZn/L9ZbzUesjPPiIZ4Ou3eUaK0Mw==} + engines: {node: '>=18'} + + verdaccio@6.2.5: + resolution: {integrity: sha512-sIek+ZF0a1aaRwHo9I5vbONGXzcAgbf5psEmbGVMG9M/MslblIae2wdehG6a2lSxsk4B9c8Ar0j/ZmliTjiStA==} + engines: {node: '>=18'} + hasBin: true + + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + + vfile-location@4.1.0: + resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-matter@5.0.1: + resolution: {integrity: sha512-o6roP82AiX0XfkyTHyRCMXgHfltUNlXSEqCIS80f+mbAyiQBE2fxtDVMtseyytGx75sihiJFo/zR6r/4LTs2Cw==} + + vfile-message@3.1.4: + resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile-reporter@7.0.5: + resolution: {integrity: sha512-NdWWXkv6gcd7AZMvDomlQbK3MqFWL1RlGzMn++/O2TI+68+nqxCPTvLugdOtfSzXmjh+xUyhp07HhlrbJjT+mw==} + + vfile-sort@3.0.1: + resolution: {integrity: sha512-1os1733XY6y0D5x0ugqSeaVJm9lYgj0j5qdcZQFyxlZOSy1jYarL77lLyb5gK4Wqr1d5OxmuyflSO3zKyFnTFw==} + + vfile-statistics@2.0.1: + resolution: {integrity: sha512-W6dkECZmP32EG/l+dp2jCLdYzmnDBIw6jwiLZSER81oR5AHRcVqL+k3Z+pfH1R73le6ayDkJRMk0sutj1bMVeg==} + + vfile@5.3.7: + resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-dev-rpc@1.1.0: + resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 + + vite-hot-client@2.1.0: + resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-node@5.3.0: + resolution: {integrity: sha512-8f20COPYJujc3OKPX6OuyBy3ZIv2det4eRRU4GY1y2MjbeGSUmPjedxg1b72KnTagCofwvZ65ThzjxDW2AtQFQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + vite-plugin-checker@0.12.0: + resolution: {integrity: sha512-CmdZdDOGss7kdQwv73UyVgLPv0FVYe5czAgnmRX2oKljgEvSrODGuClaV3PDR2+3ou7N/OKGauDDBjy2MB07Rg==} + engines: {node: '>=16.11'} + peerDependencies: + '@biomejs/biome': '>=1.7' + eslint: '>=9.39.1' + meow: ^13.2.0 + optionator: ^0.9.4 + oxlint: '>=1' + stylelint: '>=16' + typescript: '*' + vite: '>=5.4.21' + vls: '*' + vti: '*' + vue-tsc: ~2.2.10 || ^3.0.0 + peerDependenciesMeta: + '@biomejs/biome': + optional: true + eslint: + optional: true + meow: + optional: true + optionator: + optional: true + oxlint: + optional: true + stylelint: + optional: true + typescript: + optional: true + vls: + optional: true + vti: + optional: true + vue-tsc: + optional: true + + vite-plugin-dts@4.5.4: + resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==} + peerDependencies: + typescript: '*' + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite-plugin-full-reload@1.2.0: + resolution: {integrity: sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==} + + vite-plugin-inspect@11.3.3: + resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-node-polyfills@0.25.0: + resolution: {integrity: sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg==} + peerDependencies: + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + + vite-plugin-vue-tracer@1.2.0: + resolution: {integrity: sha512-a9Z/TLpxwmoE9kIcv28wqQmiszM7ec4zgndXWEsVD/2lEZLRGzcg7ONXmplzGF/UP5W59QNtS809OdywwpUWQQ==} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 + vue: 3.5.25 + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: 20.4.0 + jsdom: 27.3.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vm-browserify@1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + + vooks@0.2.12: + resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==} + peerDependencies: + vue: 3.5.25 + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-bundle-renderer@2.2.0: + resolution: {integrity: sha512-sz/0WEdYH1KfaOm0XaBmRZOWgYTEvUDt6yPYaUzl4E52qzgWLlknaPPTTZmp6benaPTlQAI/hN1x3tAzZygycg==} + + vue-component-type-helpers@2.2.12: + resolution: {integrity: sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: 3.5.25 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-devtools-stub@0.1.0: + resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} + + vue-router@4.6.4: + resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==} + peerDependencies: + vue: 3.5.25 + + vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + + vue@3.5.25: + resolution: {integrity: sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vueuc@0.4.65: + resolution: {integrity: sha512-lXuMl+8gsBmruudfxnMF9HW4be8rFziylXFu1VHVNbLVhRTXXV4njvpRuJapD/8q+oFEMSfQMH16E/85VoWRyQ==} + peerDependencies: + vue: 3.5.25 + + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + weak-lru-cache@1.2.2: + resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + web-worker@1.2.0: + resolution: {integrity: sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} + + webpack-dev-middleware@7.4.5: + resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + + webpack-dev-server@5.2.3: + resolution: {integrity: sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==} + engines: {node: '>= 18.12.0'} + hasBin: true + peerDependencies: + webpack: ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + + webpack-sources@3.3.4: + resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} + engines: {node: '>=10.13.0'} + + webpack-subresource-integrity@5.1.0: + resolution: {integrity: sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==} + engines: {node: '>= 12'} + peerDependencies: + html-webpack-plugin: '>= 5.0.0-beta.1 < 6' + webpack: ^5.12.0 + peerDependenciesMeta: + html-webpack-plugin: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + webpack@5.105.2: + resolution: {integrity: sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} + + whatwg-url@15.1.0: + resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} + engines: {node: '>=20'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + wsl-utils@0.3.1: + resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + engines: {node: '>=20'} + + xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y-indexeddb@9.0.12: + resolution: {integrity: sha512-9oCFRSPPzBK7/w5vOkJBaVCQZKHXB/v6SIT+WYhnJxlEC61juqG0hBrAf+y3gmSMLFLwICNH9nQ53uscuse6Hg==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + yjs: ^13.0.0 + + y-prosemirror@1.3.7: + resolution: {integrity: sha512-NpM99WSdD4Fx4if5xOMDpPtU3oAmTSjlzh5U4353ABbRHl1HtAFUx6HlebLZfyFxXN9jzKMDkVbcRjqOZVkYQg==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + prosemirror-model: ^1.7.1 + prosemirror-state: ^1.2.3 + prosemirror-view: ^1.9.10 + y-protocols: ^1.0.1 + yjs: ^13.5.38 + + y-protocols@1.0.7: + resolution: {integrity: sha512-YSVsLoXxO67J6eE/nV4AtFtT3QEotZf5sK5BHxFBXso7VDUT3Tx07IfA6hsu5Q5OmBdMkQVmFZ9QOA7fikWvnw==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + yjs: ^13.0.0 + + y-websocket@3.0.0: + resolution: {integrity: sha512-mUHy7AzkOZ834T/7piqtlA8Yk6AchqKqcrCXjKW8J1w2lPtRDjz8W5/CvXz9higKAHgKRKqpI3T33YkRFLkPtg==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + peerDependencies: + yjs: ^13.5.6 + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.1: + resolution: {integrity: sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yazl@2.5.1: + resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} + + yjs@13.6.19: + resolution: {integrity: sha512-GNKw4mEUn5yWU2QPHRx8jppxmCm9KzbBhB4qJLUJFiiYD0g/tDVgXQ7aPkyh01YO28kbs2J/BEbWBagjuWyejw==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.0: + resolution: {integrity: sha512-cYekNh2tUoU+voS11X0D0UQntVCSO6LQ1h10VriQGmfbpf0mnGTruwZICts23UUNiZCXm8H8hQBtRrdsbhuNNg==} + + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + + zod-to-json-schema@3.20.4: + resolution: {integrity: sha512-Un9+kInJ2Zt63n6Z7mLqBifzzPcOyX+b+Exuzf7L1+xqck9Q2EPByyTRduV3kmSPaXaRer1JCsucubpgL1fipg==} + peerDependencies: + zod: ^3.20.0 + + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + peerDependencies: + zod: ^3.25 || ^4 + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@3.21.4: + resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + + zod@3.24.0: + resolution: {integrity: sha512-Hz+wiY8yD0VLA2k/+nsg2Abez674dDGTai33SwNvMPuf9uIrBC9eFgIMQxBBbHFxVXi8W+5nX9DcAh9YNSQm/w==} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zone.js@0.16.1: + resolution: {integrity: sha512-dpvY17vxYIW3+bNrP0ClUlaiY0CiIRK3tnoLaGoQsQcY9/I/NpzIWQ7tQNhbV7LacQMpCII6wVzuL3tuWOyfuA==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@acemir/cssom@0.9.31': {} + + '@adobe/css-tools@4.4.4': {} + + '@alcalzone/ansi-tokenize@0.2.4': + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + '@algolia/abtesting@1.14.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/client-abtesting@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/client-analytics@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/client-common@5.48.1': {} + + '@algolia/client-insights@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/client-personalization@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/client-query-suggestions@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/client-search@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/ingestion@1.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/monitoring@1.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/recommend@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + + '@algolia/requester-browser-xhr@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + + '@algolia/requester-fetch@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + + '@algolia/requester-node-http@5.48.1': + dependencies: + '@algolia/client-common': 5.48.1 + + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@angular-devkit/architect@0.2102.1(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 21.2.1(chokidar@5.0.0) + rxjs: 7.8.2 + transitivePeerDependencies: + - chokidar + + '@angular-devkit/build-angular@21.2.1(@angular/compiler-cli@21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3))(@angular/compiler@21.2.2)(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)))(@types/node@22.19.8)(chokidar@5.0.0)(jiti@2.6.1)(tailwindcss@4.2.1)(tsx@4.21.0)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular-devkit/architect': 0.2102.1(chokidar@5.0.0) + '@angular-devkit/build-webpack': 0.2102.1(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)))(webpack@5.105.2(esbuild@0.27.3)) + '@angular-devkit/core': 21.2.1(chokidar@5.0.0) + '@angular/build': 21.2.1(@angular/compiler-cli@21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3))(@angular/compiler@21.2.2)(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)))(@types/node@22.19.8)(chokidar@5.0.0)(jiti@2.6.1)(less@4.4.2)(postcss@8.5.6)(tailwindcss@4.2.1)(terser@5.46.0)(tslib@2.8.1)(tsx@4.21.0)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2) + '@angular/compiler-cli': 21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3) + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) + '@babel/runtime': 7.28.6 + '@discoveryjs/json-ext': 0.6.3 + '@ngtools/webpack': 21.2.1(@angular/compiler-cli@21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.2(esbuild@0.27.3)) + ansi-colors: 4.1.3 + autoprefixer: 10.4.27(postcss@8.5.6) + babel-loader: 10.0.0(@babel/core@7.29.0)(webpack@5.105.2(esbuild@0.27.3)) + browserslist: 4.28.1 + copy-webpack-plugin: 14.0.0(webpack@5.105.2(esbuild@0.27.3)) + css-loader: 7.1.3(webpack@5.105.2(esbuild@0.27.3)) + esbuild-wasm: 0.27.3 + http-proxy-middleware: 3.0.5 + istanbul-lib-instrument: 6.0.3 + jsonc-parser: 3.3.1 + karma-source-map-support: 1.4.0 + less: 4.4.2 + less-loader: 12.3.1(less@4.4.2)(webpack@5.105.2(esbuild@0.27.3)) + license-webpack-plugin: 4.0.2(webpack@5.105.2(esbuild@0.27.3)) + loader-utils: 3.3.1 + mini-css-extract-plugin: 2.10.0(webpack@5.105.2(esbuild@0.27.3)) + open: 11.0.0 + ora: 9.3.0 + picomatch: 4.0.3 + piscina: 5.1.4 + postcss: 8.5.6 + postcss-loader: 8.2.0(postcss@8.5.6)(typescript@5.9.3)(webpack@5.105.2(esbuild@0.27.3)) + resolve-url-loader: 5.0.0 + rxjs: 7.8.2 + sass: 1.97.3 + sass-loader: 16.0.7(sass@1.97.3)(webpack@5.105.2(esbuild@0.27.3)) + semver: 7.7.4 + source-map-loader: 5.0.0(webpack@5.105.2(esbuild@0.27.3)) + source-map-support: 0.5.21 + terser: 5.46.0 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + tslib: 2.8.1 + typescript: 5.9.3 + webpack: 5.105.2(esbuild@0.27.3) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)) + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)) + webpack-merge: 6.0.1 + webpack-subresource-integrity: 5.1.0(webpack@5.105.2(esbuild@0.27.3)) + optionalDependencies: + '@angular/core': 21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': 21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)) + esbuild: 0.27.3 + tailwindcss: 4.2.1 + transitivePeerDependencies: + - '@angular/compiler' + - '@rspack/core' + - '@swc/core' + - '@types/node' + - bufferutil + - chokidar + - debug + - html-webpack-plugin + - jiti + - node-sass + - sass-embedded + - stylus + - sugarss + - supports-color + - tsx + - uglify-js + - utf-8-validate + - vitest + - webpack-cli + - yaml + + '@angular-devkit/build-webpack@0.2102.1(chokidar@5.0.0)(webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)))(webpack@5.105.2(esbuild@0.27.3))': + dependencies: + '@angular-devkit/architect': 0.2102.1(chokidar@5.0.0) + rxjs: 7.8.2 + webpack: 5.105.2(esbuild@0.27.3) + webpack-dev-server: 5.2.3(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)) + transitivePeerDependencies: + - chokidar + + '@angular-devkit/core@21.2.1(chokidar@5.0.0)': + dependencies: + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + jsonc-parser: 3.3.1 + picomatch: 4.0.3 + rxjs: 7.8.2 + source-map: 0.7.6 + optionalDependencies: + chokidar: 5.0.0 + + '@angular-devkit/schematics@21.2.1(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 21.2.1(chokidar@5.0.0) + jsonc-parser: 3.3.1 + magic-string: 0.30.21 + ora: 9.3.0 + rxjs: 7.8.2 + transitivePeerDependencies: + - chokidar + + '@angular/build@21.2.1(@angular/compiler-cli@21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3))(@angular/compiler@21.2.2)(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)))(@types/node@22.19.8)(chokidar@5.0.0)(jiti@2.6.1)(less@4.4.2)(postcss@8.5.6)(tailwindcss@4.2.1)(terser@5.46.0)(tslib@2.8.1)(tsx@4.21.0)(typescript@5.9.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(yaml@2.8.2)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular-devkit/architect': 0.2102.1(chokidar@5.0.0) + '@angular/compiler': 21.2.2 + '@angular/compiler-cli': 21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3) + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-split-export-declaration': 7.24.7 + '@inquirer/confirm': 5.1.21(@types/node@22.19.8) + '@vitejs/plugin-basic-ssl': 2.1.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + beasties: 0.4.1 + browserslist: 4.28.1 + esbuild: 0.27.3 + https-proxy-agent: 7.0.6 + istanbul-lib-instrument: 6.0.3 + jsonc-parser: 3.3.1 + listr2: 9.0.5 + magic-string: 0.30.21 + mrmime: 2.0.1 + parse5-html-rewriting-stream: 8.0.0 + picomatch: 4.0.3 + piscina: 5.1.4 + rolldown: 1.0.0-rc.4 + sass: 1.97.3 + semver: 7.7.4 + source-map-support: 0.5.21 + tinyglobby: 0.2.15 + tslib: 2.8.1 + typescript: 5.9.3 + undici: 7.22.0 + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + watchpack: 2.5.1 + optionalDependencies: + '@angular/core': 21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': 21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)) + less: 4.4.2 + lmdb: 3.5.1 + postcss: 8.5.6 + tailwindcss: 4.2.1 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - chokidar + - jiti + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + '@angular/cli@21.2.1(@types/node@22.19.8)(chokidar@5.0.0)': + dependencies: + '@angular-devkit/architect': 0.2102.1(chokidar@5.0.0) + '@angular-devkit/core': 21.2.1(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.1(chokidar@5.0.0) + '@inquirer/prompts': 7.10.1(@types/node@22.19.8) + '@listr2/prompt-adapter-inquirer': 3.0.5(@inquirer/prompts@7.10.1(@types/node@22.19.8))(@types/node@22.19.8)(listr2@9.0.5) + '@modelcontextprotocol/sdk': 1.26.0(zod@4.3.6) + '@schematics/angular': 21.2.1(chokidar@5.0.0) + '@yarnpkg/lockfile': 1.1.0 + algoliasearch: 5.48.1 + ini: 6.0.0 + jsonc-parser: 3.3.1 + listr2: 9.0.5 + npm-package-arg: 13.0.2 + pacote: 21.3.1 + parse5-html-rewriting-stream: 8.0.0 + semver: 7.7.4 + yargs: 18.0.0 + zod: 4.3.6 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@types/node' + - chokidar + - supports-color + + '@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2)': + dependencies: + '@angular/core': 21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@angular/compiler-cli@21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3)': + dependencies: + '@angular/compiler': 21.2.2 + '@babel/core': 7.29.0 + '@jridgewell/sourcemap-codec': 1.5.5 + chokidar: 5.0.0 + convert-source-map: 1.9.0 + reflect-metadata: 0.2.2 + semver: 7.7.3 + tslib: 2.8.1 + yargs: 18.0.0 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@angular/compiler@21.2.2': + dependencies: + tslib: 2.8.1 + + '@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)': + dependencies: + rxjs: 7.8.2 + tslib: 2.8.1 + optionalDependencies: + '@angular/compiler': 21.2.2 + zone.js: 0.16.1 + + '@angular/platform-browser-dynamic@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/compiler@21.2.2)(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)))': + dependencies: + '@angular/common': 21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/compiler': 21.2.2 + '@angular/core': 21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': 21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1)) + tslib: 2.8.1 + + '@angular/platform-browser@21.2.2(@angular/common@21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))': + dependencies: + '@angular/common': 21.2.2(@angular/core@21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/core': 21.2.2(@angular/compiler@21.2.2)(rxjs@7.8.2)(zone.js@0.16.1) + tslib: 2.8.1 + + '@ark/schema@0.55.0': + dependencies: + '@ark/util': 0.55.0 + + '@ark/schema@0.56.0': + dependencies: + '@ark/util': 0.56.0 + + '@ark/util@0.55.0': {} + + '@ark/util@0.56.0': {} + + '@asamuzakjp/css-color@4.1.1': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 11.2.5 + + '@asamuzakjp/dom-selector@6.7.7': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.1.0 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.2.5 + + '@asamuzakjp/nwsapi@2.3.9': {} + + '@asyncapi/parser@3.4.0': + dependencies: + '@asyncapi/specs': 6.11.1 + '@openapi-contrib/openapi-schema-to-json-schema': 3.2.0 + '@stoplight/json': 3.21.0 + '@stoplight/json-ref-readers': 1.2.2 + '@stoplight/json-ref-resolver': 3.1.6 + '@stoplight/spectral-core': 1.21.0 + '@stoplight/spectral-functions': 1.10.1 + '@stoplight/spectral-parsers': 1.0.5 + '@stoplight/spectral-ref-resolver': 1.0.5 + '@stoplight/types': 13.20.0 + '@types/json-schema': 7.0.15 + '@types/urijs': 1.19.26 + ajv: 8.17.1 + ajv-errors: 3.0.0(ajv@8.17.1) + ajv-formats: 2.1.1(ajv@8.17.1) + avsc: 5.7.9 + js-yaml: 4.1.1 + jsonpath-plus: 10.3.0 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + + '@asyncapi/specs@6.11.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@asyncapi/specs@6.8.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.1 + tslib: 2.8.1 + + '@aws-crypto/crc32c@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.1 + tslib: 2.8.1 + + '@aws-crypto/sha1-browser@5.2.0': + dependencies: + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-locate-window': 3.965.4 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-browser@5.2.0': + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-locate-window': 3.965.4 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.1 + tslib: 2.8.1 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.8.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/client-s3@3.988.0': + dependencies: + '@aws-crypto/sha1-browser': 5.2.0 + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.8 + '@aws-sdk/credential-provider-node': 3.972.7 + '@aws-sdk/middleware-bucket-endpoint': 3.972.3 + '@aws-sdk/middleware-expect-continue': 3.972.3 + '@aws-sdk/middleware-flexible-checksums': 3.972.6 + '@aws-sdk/middleware-host-header': 3.972.3 + '@aws-sdk/middleware-location-constraint': 3.972.3 + '@aws-sdk/middleware-logger': 3.972.3 + '@aws-sdk/middleware-recursion-detection': 3.972.3 + '@aws-sdk/middleware-sdk-s3': 3.972.8 + '@aws-sdk/middleware-ssec': 3.972.3 + '@aws-sdk/middleware-user-agent': 3.972.8 + '@aws-sdk/region-config-resolver': 3.972.3 + '@aws-sdk/signature-v4-multi-region': 3.988.0 + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-endpoints': 3.988.0 + '@aws-sdk/util-user-agent-browser': 3.972.3 + '@aws-sdk/util-user-agent-node': 3.972.6 + '@smithy/config-resolver': 4.4.6 + '@smithy/core': 3.23.0 + '@smithy/eventstream-serde-browser': 4.2.8 + '@smithy/eventstream-serde-config-resolver': 4.3.8 + '@smithy/eventstream-serde-node': 4.2.8 + '@smithy/fetch-http-handler': 5.3.9 + '@smithy/hash-blob-browser': 4.2.9 + '@smithy/hash-node': 4.2.8 + '@smithy/hash-stream-node': 4.2.8 + '@smithy/invalid-dependency': 4.2.8 + '@smithy/md5-js': 4.2.8 + '@smithy/middleware-content-length': 4.2.8 + '@smithy/middleware-endpoint': 4.4.14 + '@smithy/middleware-retry': 4.4.31 + '@smithy/middleware-serde': 4.2.9 + '@smithy/middleware-stack': 4.2.8 + '@smithy/node-config-provider': 4.3.8 + '@smithy/node-http-handler': 4.4.10 + '@smithy/protocol-http': 5.3.8 + '@smithy/smithy-client': 4.11.3 + '@smithy/types': 4.12.0 + '@smithy/url-parser': 4.2.8 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.30 + '@smithy/util-defaults-mode-node': 4.2.33 + '@smithy/util-endpoints': 3.2.8 + '@smithy/util-middleware': 4.2.8 + '@smithy/util-retry': 4.2.8 + '@smithy/util-stream': 4.5.12 + '@smithy/util-utf8': 4.2.0 + '@smithy/util-waiter': 4.2.8 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sso@3.988.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.8 + '@aws-sdk/middleware-host-header': 3.972.3 + '@aws-sdk/middleware-logger': 3.972.3 + '@aws-sdk/middleware-recursion-detection': 3.972.3 + '@aws-sdk/middleware-user-agent': 3.972.8 + '@aws-sdk/region-config-resolver': 3.972.3 + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-endpoints': 3.988.0 + '@aws-sdk/util-user-agent-browser': 3.972.3 + '@aws-sdk/util-user-agent-node': 3.972.6 + '@smithy/config-resolver': 4.4.6 + '@smithy/core': 3.23.0 + '@smithy/fetch-http-handler': 5.3.9 + '@smithy/hash-node': 4.2.8 + '@smithy/invalid-dependency': 4.2.8 + '@smithy/middleware-content-length': 4.2.8 + '@smithy/middleware-endpoint': 4.4.14 + '@smithy/middleware-retry': 4.4.31 + '@smithy/middleware-serde': 4.2.9 + '@smithy/middleware-stack': 4.2.8 + '@smithy/node-config-provider': 4.3.8 + '@smithy/node-http-handler': 4.4.10 + '@smithy/protocol-http': 5.3.8 + '@smithy/smithy-client': 4.11.3 + '@smithy/types': 4.12.0 + '@smithy/url-parser': 4.2.8 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.30 + '@smithy/util-defaults-mode-node': 4.2.33 + '@smithy/util-endpoints': 3.2.8 + '@smithy/util-middleware': 4.2.8 + '@smithy/util-retry': 4.2.8 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/core@3.973.8': + dependencies: + '@aws-sdk/types': 3.973.1 + '@aws-sdk/xml-builder': 3.972.4 + '@smithy/core': 3.23.0 + '@smithy/node-config-provider': 4.3.8 + '@smithy/property-provider': 4.2.8 + '@smithy/protocol-http': 5.3.8 + '@smithy/signature-v4': 5.3.8 + '@smithy/smithy-client': 4.11.3 + '@smithy/types': 4.12.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-middleware': 4.2.8 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@aws-sdk/crc64-nvme@3.972.0': + dependencies: + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.6': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/types': 3.973.1 + '@smithy/property-provider': 4.2.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.8': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/types': 3.973.1 + '@smithy/fetch-http-handler': 5.3.9 + '@smithy/node-http-handler': 4.4.10 + '@smithy/property-provider': 4.2.8 + '@smithy/protocol-http': 5.3.8 + '@smithy/smithy-client': 4.11.3 + '@smithy/types': 4.12.0 + '@smithy/util-stream': 4.5.12 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.972.6': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/credential-provider-env': 3.972.6 + '@aws-sdk/credential-provider-http': 3.972.8 + '@aws-sdk/credential-provider-login': 3.972.6 + '@aws-sdk/credential-provider-process': 3.972.6 + '@aws-sdk/credential-provider-sso': 3.972.6 + '@aws-sdk/credential-provider-web-identity': 3.972.6 + '@aws-sdk/nested-clients': 3.988.0 + '@aws-sdk/types': 3.973.1 + '@smithy/credential-provider-imds': 4.2.8 + '@smithy/property-provider': 4.2.8 + '@smithy/shared-ini-file-loader': 4.4.3 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-login@3.972.6': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/nested-clients': 3.988.0 + '@aws-sdk/types': 3.973.1 + '@smithy/property-provider': 4.2.8 + '@smithy/protocol-http': 5.3.8 + '@smithy/shared-ini-file-loader': 4.4.3 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-node@3.972.7': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.6 + '@aws-sdk/credential-provider-http': 3.972.8 + '@aws-sdk/credential-provider-ini': 3.972.6 + '@aws-sdk/credential-provider-process': 3.972.6 + '@aws-sdk/credential-provider-sso': 3.972.6 + '@aws-sdk/credential-provider-web-identity': 3.972.6 + '@aws-sdk/types': 3.973.1 + '@smithy/credential-provider-imds': 4.2.8 + '@smithy/property-provider': 4.2.8 + '@smithy/shared-ini-file-loader': 4.4.3 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-process@3.972.6': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/types': 3.973.1 + '@smithy/property-provider': 4.2.8 + '@smithy/shared-ini-file-loader': 4.4.3 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.972.6': + dependencies: + '@aws-sdk/client-sso': 3.988.0 + '@aws-sdk/core': 3.973.8 + '@aws-sdk/token-providers': 3.988.0 + '@aws-sdk/types': 3.973.1 + '@smithy/property-provider': 4.2.8 + '@smithy/shared-ini-file-loader': 4.4.3 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-web-identity@3.972.6': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/nested-clients': 3.988.0 + '@aws-sdk/types': 3.973.1 + '@smithy/property-provider': 4.2.8 + '@smithy/shared-ini-file-loader': 4.4.3 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/middleware-bucket-endpoint@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-arn-parser': 3.972.2 + '@smithy/node-config-provider': 4.3.8 + '@smithy/protocol-http': 5.3.8 + '@smithy/types': 4.12.0 + '@smithy/util-config-provider': 4.2.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-expect-continue@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/protocol-http': 5.3.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-flexible-checksums@3.972.6': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@aws-crypto/crc32c': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/core': 3.973.8 + '@aws-sdk/crc64-nvme': 3.972.0 + '@aws-sdk/types': 3.973.1 + '@smithy/is-array-buffer': 4.2.0 + '@smithy/node-config-provider': 4.3.8 + '@smithy/protocol-http': 5.3.8 + '@smithy/types': 4.12.0 + '@smithy/util-middleware': 4.2.8 + '@smithy/util-stream': 4.5.12 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-host-header@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/protocol-http': 5.3.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-location-constraint@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-logger@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-recursion-detection@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@aws/lambda-invoke-store': 0.2.3 + '@smithy/protocol-http': 5.3.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-sdk-s3@3.972.8': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-arn-parser': 3.972.2 + '@smithy/core': 3.23.0 + '@smithy/node-config-provider': 4.3.8 + '@smithy/protocol-http': 5.3.8 + '@smithy/signature-v4': 5.3.8 + '@smithy/smithy-client': 4.11.3 + '@smithy/types': 4.12.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-middleware': 4.2.8 + '@smithy/util-stream': 4.5.12 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-ssec@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/middleware-user-agent@3.972.8': + dependencies: + '@aws-sdk/core': 3.973.8 + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-endpoints': 3.988.0 + '@smithy/core': 3.23.0 + '@smithy/protocol-http': 5.3.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.988.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.8 + '@aws-sdk/middleware-host-header': 3.972.3 + '@aws-sdk/middleware-logger': 3.972.3 + '@aws-sdk/middleware-recursion-detection': 3.972.3 + '@aws-sdk/middleware-user-agent': 3.972.8 + '@aws-sdk/region-config-resolver': 3.972.3 + '@aws-sdk/types': 3.973.1 + '@aws-sdk/util-endpoints': 3.988.0 + '@aws-sdk/util-user-agent-browser': 3.972.3 + '@aws-sdk/util-user-agent-node': 3.972.6 + '@smithy/config-resolver': 4.4.6 + '@smithy/core': 3.23.0 + '@smithy/fetch-http-handler': 5.3.9 + '@smithy/hash-node': 4.2.8 + '@smithy/invalid-dependency': 4.2.8 + '@smithy/middleware-content-length': 4.2.8 + '@smithy/middleware-endpoint': 4.4.14 + '@smithy/middleware-retry': 4.4.31 + '@smithy/middleware-serde': 4.2.9 + '@smithy/middleware-stack': 4.2.8 + '@smithy/node-config-provider': 4.3.8 + '@smithy/node-http-handler': 4.4.10 + '@smithy/protocol-http': 5.3.8 + '@smithy/smithy-client': 4.11.3 + '@smithy/types': 4.12.0 + '@smithy/url-parser': 4.2.8 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-body-length-node': 4.2.1 + '@smithy/util-defaults-mode-browser': 4.3.30 + '@smithy/util-defaults-mode-node': 4.2.33 + '@smithy/util-endpoints': 3.2.8 + '@smithy/util-middleware': 4.2.8 + '@smithy/util-retry': 4.2.8 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/region-config-resolver@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/config-resolver': 4.4.6 + '@smithy/node-config-provider': 4.3.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/signature-v4-multi-region@3.988.0': + dependencies: + '@aws-sdk/middleware-sdk-s3': 3.972.8 + '@aws-sdk/types': 3.973.1 + '@smithy/protocol-http': 5.3.8 + '@smithy/signature-v4': 5.3.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.988.0': + dependencies: '@aws-sdk/core': 3.973.8 + '@aws-sdk/nested-clients': 3.988.0 + '@aws-sdk/types': 3.973.1 + '@smithy/property-provider': 4.2.8 + '@smithy/shared-ini-file-loader': 4.4.3 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/types@3.973.1': + dependencies: + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/util-arn-parser@3.972.2': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/util-endpoints@3.988.0': + dependencies: '@aws-sdk/types': 3.973.1 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/node-http-handler': 4.4.10 - '@smithy/property-provider': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 '@smithy/types': 4.12.0 - '@smithy/util-stream': 4.5.12 + '@smithy/url-parser': 4.2.8 + '@smithy/util-endpoints': 3.2.8 + tslib: 2.8.1 + + '@aws-sdk/util-locate-window@3.965.4': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-browser@3.972.3': + dependencies: + '@aws-sdk/types': 3.973.1 + '@smithy/types': 4.12.0 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-node@3.972.6': + dependencies: + '@aws-sdk/middleware-user-agent': 3.972.8 + '@aws-sdk/types': 3.973.1 + '@smithy/node-config-provider': 4.3.8 + '@smithy/types': 4.12.0 + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.4': + dependencies: + '@smithy/types': 4.12.0 + fast-xml-parser: 5.3.4 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.2.3': {} + + '@azure/abort-controller@2.1.2': + dependencies: + tslib: 2.8.1 + + '@azure/core-auth@1.10.1': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-util': 1.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-client@1.10.1': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.10.1 + '@azure/core-rest-pipeline': 1.22.2 + '@azure/core-tracing': 1.3.1 + '@azure/core-util': 1.13.1 + '@azure/logger': 1.3.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-rest-pipeline@1.22.2': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.10.1 + '@azure/core-tracing': 1.3.1 + '@azure/core-util': 1.13.1 + '@azure/logger': 1.3.0 + '@typespec/ts-http-runtime': 0.3.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-tracing@1.3.1': + dependencies: + tslib: 2.8.1 + + '@azure/core-util@1.13.1': + dependencies: + '@azure/abort-controller': 2.1.2 + '@typespec/ts-http-runtime': 0.3.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/identity@4.13.0': + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-auth': 1.10.1 + '@azure/core-client': 1.10.1 + '@azure/core-rest-pipeline': 1.22.2 + '@azure/core-tracing': 1.3.1 + '@azure/core-util': 1.13.1 + '@azure/logger': 1.3.0 + '@azure/msal-browser': 4.28.1 + '@azure/msal-node': 3.8.6 + open: 10.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/logger@1.3.0': + dependencies: + '@typespec/ts-http-runtime': 0.3.2 tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/msal-browser@4.28.1': + dependencies: + '@azure/msal-common': 15.14.1 + + '@azure/msal-common@15.14.1': {} + + '@azure/msal-node@3.8.6': + dependencies: + '@azure/msal-common': 15.14.1 + jsonwebtoken: 9.0.3 + uuid: 8.3.2 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@5.5.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3(supports-color@5.5.0) + lodash.debounce: 4.0.8 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 - '@aws-sdk/credential-provider-ini@3.972.6': + '@babel/parser@7.29.0': dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/credential-provider-env': 3.972.6 - '@aws-sdk/credential-provider-http': 3.972.8 - '@aws-sdk/credential-provider-login': 3.972.6 - '@aws-sdk/credential-provider-process': 3.972.6 - '@aws-sdk/credential-provider-sso': 3.972.6 - '@aws-sdk/credential-provider-web-identity': 3.972.6 - '@aws-sdk/nested-clients': 3.988.0 - '@aws-sdk/types': 3.973.1 - '@smithy/credential-provider-imds': 4.2.8 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + '@babel/types': 7.29.0 - '@aws-sdk/credential-provider-login@3.972.6': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/nested-clients': 3.988.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - - aws-crt + - supports-color - '@aws-sdk/credential-provider-node@3.972.7': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/credential-provider-env': 3.972.6 - '@aws-sdk/credential-provider-http': 3.972.8 - '@aws-sdk/credential-provider-ini': 3.972.6 - '@aws-sdk/credential-provider-process': 3.972.6 - '@aws-sdk/credential-provider-sso': 3.972.6 - '@aws-sdk/credential-provider-web-identity': 3.972.6 - '@aws-sdk/types': 3.973.1 - '@smithy/credential-provider-imds': 4.2.8 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/credential-provider-process@3.972.6': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/credential-provider-sso@3.972.6': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/client-sso': 3.988.0 - '@aws-sdk/core': 3.973.8 - '@aws-sdk/token-providers': 3.988.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - - aws-crt + - supports-color - '@aws-sdk/credential-provider-web-identity@3.972.6': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/nested-clients': 3.988.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - - aws-crt + - supports-color - '@aws-sdk/middleware-bucket-endpoint@3.972.3': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-arn-parser': 3.972.2 - '@smithy/node-config-provider': 4.3.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - '@smithy/util-config-provider': 4.2.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 - '@aws-sdk/middleware-expect-continue@3.972.3': + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/middleware-flexible-checksums@3.972.6': + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-crypto/crc32': 5.2.0 - '@aws-crypto/crc32c': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.973.8 - '@aws-sdk/crc64-nvme': 3.972.0 - '@aws-sdk/types': 3.973.1 - '@smithy/is-array-buffer': 4.2.0 - '@smithy/node-config-provider': 4.3.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-stream': 4.5.12 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/middleware-host-header@3.972.3': + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/middleware-location-constraint@3.972.3': + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/middleware-logger@3.972.3': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/middleware-recursion-detection@3.972.3': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@aws/lambda-invoke-store': 0.2.3 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/middleware-sdk-s3@3.972.8': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-arn-parser': 3.972.2 - '@smithy/core': 3.23.0 - '@smithy/node-config-provider': 4.3.8 - '@smithy/protocol-http': 5.3.8 - '@smithy/signature-v4': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/util-config-provider': 4.2.0 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-stream': 4.5.12 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color - '@aws-sdk/middleware-ssec@3.972.3': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color - '@aws-sdk/middleware-user-agent@3.972.8': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.988.0 - '@smithy/core': 3.23.0 - '@smithy/protocol-http': 5.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/nested-clients@3.988.0': + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.8 - '@aws-sdk/middleware-host-header': 3.972.3 - '@aws-sdk/middleware-logger': 3.972.3 - '@aws-sdk/middleware-recursion-detection': 3.972.3 - '@aws-sdk/middleware-user-agent': 3.972.8 - '@aws-sdk/region-config-resolver': 3.972.3 - '@aws-sdk/types': 3.973.1 - '@aws-sdk/util-endpoints': 3.988.0 - '@aws-sdk/util-user-agent-browser': 3.972.3 - '@aws-sdk/util-user-agent-node': 3.972.6 - '@smithy/config-resolver': 4.4.6 - '@smithy/core': 3.23.0 - '@smithy/fetch-http-handler': 5.3.9 - '@smithy/hash-node': 4.2.8 - '@smithy/invalid-dependency': 4.2.8 - '@smithy/middleware-content-length': 4.2.8 - '@smithy/middleware-endpoint': 4.4.14 - '@smithy/middleware-retry': 4.4.31 - '@smithy/middleware-serde': 4.2.9 - '@smithy/middleware-stack': 4.2.8 - '@smithy/node-config-provider': 4.3.8 - '@smithy/node-http-handler': 4.4.10 - '@smithy/protocol-http': 5.3.8 - '@smithy/smithy-client': 4.11.3 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-base64': 4.3.0 - '@smithy/util-body-length-browser': 4.2.0 - '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.30 - '@smithy/util-defaults-mode-node': 4.2.33 - '@smithy/util-endpoints': 3.2.8 - '@smithy/util-middleware': 4.2.8 - '@smithy/util-retry': 4.2.8 - '@smithy/util-utf8': 4.2.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - - aws-crt + - supports-color - '@aws-sdk/region-config-resolver@3.972.3': + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/config-resolver': 4.4.6 - '@smithy/node-config-provider': 4.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/signature-v4-multi-region@3.988.0': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.8 - '@aws-sdk/types': 3.973.1 - '@smithy/protocol-http': 5.3.8 - '@smithy/signature-v4': 5.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/token-providers@3.988.0': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - '@aws-sdk/core': 3.973.8 - '@aws-sdk/nested-clients': 3.988.0 - '@aws-sdk/types': 3.973.1 - '@smithy/property-provider': 4.2.8 - '@smithy/shared-ini-file-loader': 4.4.3 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) transitivePeerDependencies: - - aws-crt + - supports-color - '@aws-sdk/types@3.973.1': + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/util-arn-parser@3.972.2': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': dependencies: - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/util-endpoints@3.988.0': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 - '@smithy/url-parser': 4.2.8 - '@smithy/util-endpoints': 3.2.8 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color - '@aws-sdk/util-locate-window@3.965.4': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': dependencies: - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color - '@aws-sdk/util-user-agent-browser@3.972.3': + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/types': 4.12.0 - bowser: 2.14.1 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/util-user-agent-node@3.972.6': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.8 - '@aws-sdk/types': 3.973.1 - '@smithy/node-config-provider': 4.3.8 - '@smithy/types': 4.12.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws-sdk/xml-builder@3.972.4': + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': dependencies: - '@smithy/types': 4.12.0 - fast-xml-parser: 5.3.4 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@aws/lambda-invoke-store@0.2.3': {} + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@azure/abort-controller@2.1.2': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': dependencies: - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color - '@azure/core-auth@1.10.1': + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-util': 1.13.1 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@azure/core-client@1.10.1': + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.10.1 - '@azure/core-rest-pipeline': 1.22.2 - '@azure/core-tracing': 1.3.1 - '@azure/core-util': 1.13.1 - '@azure/logger': 1.3.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@azure/core-rest-pipeline@1.22.2': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.10.1 - '@azure/core-tracing': 1.3.1 - '@azure/core-util': 1.13.1 - '@azure/logger': 1.3.0 - '@typespec/ts-http-runtime': 0.3.2 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@azure/core-tracing@1.3.1': + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': dependencies: - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@azure/core-util@1.13.1': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': dependencies: - '@azure/abort-controller': 2.1.2 - '@typespec/ts-http-runtime': 0.3.2 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@azure/identity@4.13.0': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': dependencies: - '@azure/abort-controller': 2.1.2 - '@azure/core-auth': 1.10.1 - '@azure/core-client': 1.10.1 - '@azure/core-rest-pipeline': 1.22.2 - '@azure/core-tracing': 1.3.1 - '@azure/core-util': 1.13.1 - '@azure/logger': 1.3.0 - '@azure/msal-browser': 4.28.1 - '@azure/msal-node': 3.8.6 - open: 10.2.0 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@azure/logger@1.3.0': + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': dependencies: - '@typespec/ts-http-runtime': 0.3.2 - tslib: 2.8.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@azure/msal-browser@4.28.1': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': dependencies: - '@azure/msal-common': 15.14.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@azure/msal-common@15.14.1': {} + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color - '@azure/msal-node@3.8.6': + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': dependencies: - '@azure/msal-common': 15.14.1 - jsonwebtoken: 9.0.3 - uuid: 8.3.2 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color - '@babel/code-frame@7.29.0': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/helper-validator-identifier': 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/compat-data@7.29.0': {} + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/core@7.29.0': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.28.6 - '@babel/parser': 7.29.0 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@5.5.0) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/generator@7.29.1': + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-compilation-targets@7.28.6': + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 - lru-cache: 5.1.1 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.16(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.7(@babel/core@7.29.0) semver: 6.3.1 + transitivePeerDependencies: + - supports-color - '@babel/helper-globals@7.28.0': {} + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-module-imports@7.28.6': + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color + '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-plugin-utils@7.28.6': {} + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-string-parser@7.27.1': {} + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color - '@babel/helper-validator-option@7.27.1': {} + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/helpers@7.28.6': + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/parser@7.29.0': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/types': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + '@babel/preset-env@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.16(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.1(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.7(@babel/core@7.29.0) + core-js-compat: 3.48.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 + esutils: 2.0.3 '@babel/runtime@7.28.6': {} @@ -12129,6 +18152,11 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} + '@bomb.sh/tab@0.0.12(cac@6.7.14)(citty@0.2.1)': + optionalDependencies: + cac: 6.7.14 + citty: 0.2.1 + '@canvas/image-data@1.1.0': {} '@clack/core@1.0.0': @@ -12151,6 +18179,8 @@ snapshots: '@clack/core': 1.1.0 sisteransi: 1.0.5 + '@cloudflare/kv-asset-handler@0.4.2': {} + '@colors/colors@1.5.0': optional: true @@ -12268,6 +18298,10 @@ snapshots: dependencies: css-render: 0.15.14 + '@css-render/vue3-ssr@0.15.14(vue@3.5.25(typescript@5.5.4))': + dependencies: + vue: 3.5.25(typescript@5.5.4) + '@css-render/vue3-ssr@0.15.14(vue@3.5.25(typescript@5.9.3))': dependencies: vue: 3.5.25(typescript@5.9.3) @@ -12315,6 +18349,20 @@ snapshots: tunnel-agent: 0.6.0 uuid: 8.3.2 + '@discoveryjs/json-ext@0.6.3': {} + + '@dxup/nuxt@0.3.2(magicast@0.5.2)': + dependencies: + '@dxup/unimport': 0.1.2 + '@nuxt/kit': 4.3.1(magicast@0.5.2) + chokidar: 5.0.0 + pathe: 2.0.3 + tinyglobby: 0.2.15 + transitivePeerDependencies: + - magicast + + '@dxup/unimport@0.1.2': {} + '@emnapi/core@1.8.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -12347,156 +18395,234 @@ snapshots: '@esbuild/aix-ppc64@0.27.2': optional: true + '@esbuild/aix-ppc64@0.27.3': + optional: true + '@esbuild/android-arm64@0.25.12': optional: true '@esbuild/android-arm64@0.27.2': optional: true + '@esbuild/android-arm64@0.27.3': + optional: true + '@esbuild/android-arm@0.25.12': optional: true '@esbuild/android-arm@0.27.2': optional: true + '@esbuild/android-arm@0.27.3': + optional: true + '@esbuild/android-x64@0.25.12': optional: true '@esbuild/android-x64@0.27.2': optional: true + '@esbuild/android-x64@0.27.3': + optional: true + '@esbuild/darwin-arm64@0.25.12': optional: true '@esbuild/darwin-arm64@0.27.2': optional: true + '@esbuild/darwin-arm64@0.27.3': + optional: true + '@esbuild/darwin-x64@0.25.12': optional: true '@esbuild/darwin-x64@0.27.2': optional: true + '@esbuild/darwin-x64@0.27.3': + optional: true + '@esbuild/freebsd-arm64@0.25.12': optional: true '@esbuild/freebsd-arm64@0.27.2': optional: true + '@esbuild/freebsd-arm64@0.27.3': + optional: true + '@esbuild/freebsd-x64@0.25.12': optional: true '@esbuild/freebsd-x64@0.27.2': optional: true + '@esbuild/freebsd-x64@0.27.3': + optional: true + '@esbuild/linux-arm64@0.25.12': optional: true '@esbuild/linux-arm64@0.27.2': optional: true + '@esbuild/linux-arm64@0.27.3': + optional: true + '@esbuild/linux-arm@0.25.12': optional: true '@esbuild/linux-arm@0.27.2': optional: true + '@esbuild/linux-arm@0.27.3': + optional: true + '@esbuild/linux-ia32@0.25.12': optional: true '@esbuild/linux-ia32@0.27.2': optional: true + '@esbuild/linux-ia32@0.27.3': + optional: true + '@esbuild/linux-loong64@0.25.12': optional: true '@esbuild/linux-loong64@0.27.2': optional: true + '@esbuild/linux-loong64@0.27.3': + optional: true + '@esbuild/linux-mips64el@0.25.12': optional: true '@esbuild/linux-mips64el@0.27.2': optional: true + '@esbuild/linux-mips64el@0.27.3': + optional: true + '@esbuild/linux-ppc64@0.25.12': optional: true '@esbuild/linux-ppc64@0.27.2': optional: true + '@esbuild/linux-ppc64@0.27.3': + optional: true + '@esbuild/linux-riscv64@0.25.12': optional: true '@esbuild/linux-riscv64@0.27.2': optional: true + '@esbuild/linux-riscv64@0.27.3': + optional: true + '@esbuild/linux-s390x@0.25.12': optional: true '@esbuild/linux-s390x@0.27.2': optional: true + '@esbuild/linux-s390x@0.27.3': + optional: true + '@esbuild/linux-x64@0.25.12': optional: true '@esbuild/linux-x64@0.27.2': optional: true + '@esbuild/linux-x64@0.27.3': + optional: true + '@esbuild/netbsd-arm64@0.25.12': optional: true '@esbuild/netbsd-arm64@0.27.2': optional: true + '@esbuild/netbsd-arm64@0.27.3': + optional: true + '@esbuild/netbsd-x64@0.25.12': optional: true '@esbuild/netbsd-x64@0.27.2': optional: true + '@esbuild/netbsd-x64@0.27.3': + optional: true + '@esbuild/openbsd-arm64@0.25.12': optional: true '@esbuild/openbsd-arm64@0.27.2': optional: true + '@esbuild/openbsd-arm64@0.27.3': + optional: true + '@esbuild/openbsd-x64@0.25.12': optional: true '@esbuild/openbsd-x64@0.27.2': optional: true + '@esbuild/openbsd-x64@0.27.3': + optional: true + '@esbuild/openharmony-arm64@0.25.12': optional: true '@esbuild/openharmony-arm64@0.27.2': optional: true + '@esbuild/openharmony-arm64@0.27.3': + optional: true + '@esbuild/sunos-x64@0.25.12': optional: true '@esbuild/sunos-x64@0.27.2': optional: true + '@esbuild/sunos-x64@0.27.3': + optional: true + '@esbuild/win32-arm64@0.25.12': optional: true '@esbuild/win32-arm64@0.27.2': optional: true + '@esbuild/win32-arm64@0.27.3': + optional: true + '@esbuild/win32-ia32@0.25.12': optional: true '@esbuild/win32-ia32@0.27.2': optional: true + '@esbuild/win32-ia32@0.27.3': + optional: true + '@esbuild/win32-x64@0.25.12': optional: true '@esbuild/win32-x64@0.27.2': optional: true + '@esbuild/win32-x64@0.27.3': + optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))': dependencies: eslint: 9.39.2(jiti@2.6.1) @@ -12543,6 +18669,38 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@fastify/ajv-compiler@4.0.5': + dependencies: + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-uri: 3.1.0 + + '@fastify/error@4.2.0': {} + + '@fastify/fast-json-stringify-compiler@5.0.3': + dependencies: + fast-json-stringify: 6.3.0 + + '@fastify/forwarded@3.0.1': {} + + '@fastify/merge-json-schemas@0.2.1': + dependencies: + dequal: 2.0.3 + + '@fastify/proxy-addr@5.1.0': + dependencies: + '@fastify/forwarded': 3.0.1 + ipaddr.js: 2.3.0 + + '@fastify/websocket@11.2.0': + dependencies: + duplexify: 4.1.3 + fastify-plugin: 5.1.0 + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@floating-ui/core@1.7.4': dependencies: '@floating-ui/utils': 0.2.10 @@ -12560,6 +18718,13 @@ snapshots: '@floating-ui/utils@0.2.10': {} + '@gar/promise-retry@1.0.2': + dependencies: + retry: 0.13.1 + + '@harperfast/extended-iterable@1.0.3': + optional: true + '@hocuspocus/common@2.15.3': dependencies: lib0: 0.2.117 @@ -12855,6 +19020,21 @@ snapshots: optionalDependencies: '@types/node': 22.19.8 + '@inquirer/prompts@7.10.1(@types/node@22.19.8)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@22.19.8) + '@inquirer/confirm': 5.1.21(@types/node@22.19.8) + '@inquirer/editor': 4.2.23(@types/node@22.19.8) + '@inquirer/expand': 4.0.23(@types/node@22.19.8) + '@inquirer/input': 4.3.1(@types/node@22.19.8) + '@inquirer/number': 3.0.23(@types/node@22.19.8) + '@inquirer/password': 4.0.23(@types/node@22.19.8) + '@inquirer/rawlist': 4.1.11(@types/node@22.19.8) + '@inquirer/search': 3.2.2(@types/node@22.19.8) + '@inquirer/select': 4.4.2(@types/node@22.19.8) + optionalDependencies: + '@types/node': 22.19.8 + '@inquirer/prompts@7.9.0(@types/node@22.19.8)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@22.19.8) @@ -12901,6 +19081,8 @@ snapshots: optionalDependencies: '@types/node': 22.19.8 + '@ioredis/commands@1.5.1': {} + '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.1': @@ -12916,6 +19098,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@istanbuljs/schema@0.1.3': {} '@jridgewell/gen-mapping@0.3.13': @@ -12930,6 +19116,11 @@ snapshots: '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/sourcemap-codec@1.5.5': {} '@jridgewell/trace-mapping@0.3.31': @@ -12937,23 +19128,231 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/ternary@1.1.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/base64@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-core@4.56.11(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.11(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-fsa@4.56.11(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.11(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-builtins@4.56.11(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-to-fsa@4.56.11(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-fsa': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.11(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-utils@4.56.11(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.56.11(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node@4.56.11(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.56.11(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.56.11(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.56.11(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-snapshot@4.56.11(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@juggle/resize-observer@3.4.0': {} + + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.4.3(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@lifeomic/attempt@3.1.0': {} + + '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.10.1(@types/node@22.19.8))(@types/node@22.19.8)(listr2@9.0.5)': + dependencies: + '@inquirer/prompts': 7.10.1(@types/node@22.19.8) + '@inquirer/type': 3.0.10(@types/node@22.19.8) + listr2: 9.0.5 + transitivePeerDependencies: + - '@types/node' + + '@liveblocks/client@3.15.1(@types/json-schema@7.0.15)': + dependencies: + '@liveblocks/core': 3.15.1(@types/json-schema@7.0.15) + transitivePeerDependencies: + - '@types/json-schema' + + '@liveblocks/core@3.15.1(@types/json-schema@7.0.15)': dependencies: - jsep: 1.4.0 + '@types/json-schema': 7.0.15 - '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + '@liveblocks/node@3.15.1(@types/json-schema@7.0.15)': dependencies: - jsep: 1.4.0 + '@liveblocks/core': 3.15.1(@types/json-schema@7.0.15) + '@stablelib/base64': 1.0.1 + fast-sha256: 1.3.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - '@types/json-schema' + - encoding - '@jsep-plugin/ternary@1.1.4(jsep@1.4.0)': + '@liveblocks/yjs@3.15.1(@types/json-schema@7.0.15)(yjs@13.6.19)': dependencies: - jsep: 1.4.0 + '@liveblocks/client': 3.15.1(@types/json-schema@7.0.15) + '@liveblocks/core': 3.15.1(@types/json-schema@7.0.15) + '@noble/hashes': 1.8.0 + js-base64: 3.7.8 + y-indexeddb: 9.0.12(yjs@13.6.19) + yjs: 13.6.19 + transitivePeerDependencies: + - '@types/json-schema' - '@juggle/resize-observer@3.4.0': {} + '@lmdb/lmdb-darwin-arm64@3.5.1': + optional: true - '@leichtgewicht/ip-codec@2.0.5': {} + '@lmdb/lmdb-darwin-x64@3.5.1': + optional: true - '@lifeomic/attempt@3.1.0': {} + '@lmdb/lmdb-linux-arm64@3.5.1': + optional: true + + '@lmdb/lmdb-linux-arm@3.5.1': + optional: true + + '@lmdb/lmdb-linux-x64@3.5.1': + optional: true + + '@lmdb/lmdb-win32-arm64@3.5.1': + optional: true + + '@lmdb/lmdb-win32-x64@3.5.1': + optional: true + + '@mapbox/node-pre-gyp@2.0.3': + dependencies: + consola: 3.4.2 + detect-libc: 2.1.2 + https-proxy-agent: 7.0.6 + node-fetch: 2.7.0 + nopt: 8.1.0 + semver: 7.7.4 + tar: 7.5.11 + transitivePeerDependencies: + - encoding + - supports-color '@mdx-js/mdx@3.1.1': dependencies: @@ -13208,442 +19607,1243 @@ snapshots: - '@radix-ui/react-popover' - '@types/react' - debug - - encoding + - encoding + - react + - react-dom + - supports-color + - ts-node + - typescript + + '@mintlify/link-rot@3.0.872(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + dependencies: + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/prebuild': 1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/previewing': 4.0.905(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3) + '@mintlify/scraping': 4.0.522(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + fs-extra: 11.1.0 + unist-util-visit: 4.1.2 + transitivePeerDependencies: + - '@radix-ui/react-popover' + - '@types/react' + - bare-abort-controller + - bare-buffer + - bufferutil + - debug + - encoding + - react + - react-devtools-core + - react-dom + - react-native-b4a + - supports-color + - ts-node + - typescript + - utf-8-validate + + '@mintlify/mdx@3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + dependencies: + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) + '@shikijs/transformers': 3.22.0 + '@shikijs/twoslash': 3.22.0(typescript@5.9.3) + arktype: 2.1.29 + hast-util-to-string: 3.0.1 + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm: 3.1.0 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-to-hast: 13.2.1 + next-mdx-remote-client: 1.1.4(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(unified@11.0.5) + react: 19.2.3 + react-dom: 19.2.4(react@19.2.3) + rehype-katex: 7.0.1 + remark-gfm: 4.0.1 + remark-math: 6.0.0 + remark-smartypants: 3.0.2 + shiki: 3.22.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + transitivePeerDependencies: + - '@types/react' + - supports-color + - typescript + + '@mintlify/models@0.0.255': + dependencies: + axios: 1.10.0 + openapi-types: 12.1.3 + transitivePeerDependencies: + - debug + + '@mintlify/models@0.0.268': + dependencies: + axios: 1.13.2 + openapi-types: 12.1.3 + transitivePeerDependencies: + - debug + + '@mintlify/openapi-parser@0.0.8': + dependencies: + ajv: 8.17.1 + ajv-draft-04: 1.0.0(ajv@8.17.1) + ajv-formats: 3.0.1(ajv@8.17.1) + jsonpointer: 5.0.1 + leven: 4.1.0 + yaml: 2.8.2 + + '@mintlify/prebuild@1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + dependencies: + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/openapi-parser': 0.0.8 + '@mintlify/scraping': 4.0.574(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + chalk: 5.3.0 + favicons: 7.2.0 + front-matter: 4.0.2 + fs-extra: 11.1.0 + js-yaml: 4.1.0 + openapi-types: 12.1.3 + sharp: 0.33.5 + sharp-ico: 0.1.5 + unist-util-visit: 4.1.2 + uuid: 11.1.0 + transitivePeerDependencies: + - '@radix-ui/react-popover' + - '@types/react' + - bare-abort-controller + - bare-buffer + - bufferutil + - debug + - encoding + - react + - react-dom + - react-native-b4a + - supports-color + - ts-node + - typescript + - utf-8-validate + + '@mintlify/previewing@4.0.905(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3)': + dependencies: + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/prebuild': 1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + better-opn: 3.0.2 + chalk: 5.2.0 + chokidar: 3.5.3 + express: 4.18.2 + front-matter: 4.0.2 + fs-extra: 11.1.0 + got: 13.0.0 + ink: 6.3.0(@types/react@19.2.11)(react@19.2.3) + ink-spinner: 5.0.0(ink@6.3.0(@types/react@19.2.11)(react@19.2.3))(react@19.2.3) + is-online: 10.0.0 + js-yaml: 4.1.0 + openapi-types: 12.1.3 + react: 19.2.3 + socket.io: 4.7.2 + tar: 6.1.15 + unist-util-visit: 4.1.2 + yargs: 17.7.1 + transitivePeerDependencies: + - '@radix-ui/react-popover' + - '@types/react' + - bare-abort-controller + - bare-buffer + - bufferutil + - debug + - encoding + - react-devtools-core + - react-dom + - react-native-b4a + - supports-color + - ts-node + - typescript + - utf-8-validate + + '@mintlify/scraping@4.0.522(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + dependencies: + '@mintlify/common': 1.0.661(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/openapi-parser': 0.0.8 + fs-extra: 11.1.1 + hast-util-to-mdast: 10.1.0 + js-yaml: 4.1.0 + mdast-util-mdx-jsx: 3.1.3 + neotraverse: 0.6.18 + puppeteer: 22.14.0(typescript@5.9.3) + rehype-parse: 9.0.1 + remark-gfm: 4.0.0 + remark-mdx: 3.0.1 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + yargs: 17.7.1 + zod: 3.21.4 + transitivePeerDependencies: + - '@radix-ui/react-popover' + - '@types/react' + - bare-abort-controller + - bare-buffer + - bufferutil + - debug + - encoding + - react + - react-dom + - react-native-b4a + - supports-color + - ts-node + - typescript + - utf-8-validate + + '@mintlify/scraping@4.0.574(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + dependencies: + '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/openapi-parser': 0.0.8 + fs-extra: 11.1.1 + hast-util-to-mdast: 10.1.0 + js-yaml: 4.1.0 + mdast-util-mdx-jsx: 3.1.3 + neotraverse: 0.6.18 + puppeteer: 22.14.0(typescript@5.9.3) + rehype-parse: 9.0.1 + remark-gfm: 4.0.0 + remark-mdx: 3.0.1 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + yargs: 17.7.1 + zod: 3.24.0 + transitivePeerDependencies: + - '@radix-ui/react-popover' + - '@types/react' + - bare-abort-controller + - bare-buffer + - bufferutil + - debug + - encoding + - react + - react-dom + - react-native-b4a + - supports-color + - ts-node + - typescript + - utf-8-validate + + '@mintlify/validation@0.1.555(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + dependencies: + '@mintlify/mdx': 3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/models': 0.0.255 + arktype: 2.1.27 + js-yaml: 4.1.0 + lcm: 0.0.3 + lodash: 4.17.21 + object-hash: 3.0.0 + openapi-types: 12.1.3 + uuid: 11.1.0 + zod: 3.21.4 + zod-to-json-schema: 3.20.4(zod@3.21.4) + transitivePeerDependencies: + - '@radix-ui/react-popover' + - '@types/react' + - debug - react - react-dom - supports-color - - ts-node - typescript - '@mintlify/link-rot@3.0.872(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@mintlify/validation@0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': dependencies: - '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/prebuild': 1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/previewing': 4.0.905(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3) - '@mintlify/scraping': 4.0.522(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - fs-extra: 11.1.0 - unist-util-visit: 4.1.2 + '@mintlify/mdx': 3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + '@mintlify/models': 0.0.268 + arktype: 2.1.27 + js-yaml: 4.1.0 + lcm: 0.0.3 + lodash: 4.17.21 + object-hash: 3.0.0 + openapi-types: 12.1.3 + uuid: 11.1.0 + zod: 3.24.0 + zod-to-json-schema: 3.20.4(zod@3.24.0) transitivePeerDependencies: - '@radix-ui/react-popover' - '@types/react' - - bare-abort-controller - - bare-buffer - - bufferutil - debug - - encoding - react - - react-devtools-core - react-dom - - react-native-b4a - supports-color - - ts-node - typescript - - utf-8-validate - '@mintlify/mdx@3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)': dependencies: - '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3) - '@shikijs/transformers': 3.22.0 - '@shikijs/twoslash': 3.22.0(typescript@5.9.3) - arktype: 2.1.29 - hast-util-to-string: 3.0.1 - mdast-util-from-markdown: 2.0.2 - mdast-util-gfm: 3.1.0 - mdast-util-mdx-jsx: 3.2.0 - mdast-util-to-hast: 13.2.1 - next-mdx-remote-client: 1.1.4(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(unified@11.0.5) - react: 19.2.3 - react-dom: 19.2.4(react@19.2.3) - rehype-katex: 7.0.1 - remark-gfm: 4.0.1 - remark-math: 6.0.0 - remark-smartypants: 3.0.2 - shiki: 3.22.0 - unified: 11.0.5 - unist-util-visit: 5.1.0 + '@hono/node-server': 1.19.9(hono@4.12.1) + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.2.1(express@5.2.1) + hono: 4.12.1 + jose: 6.1.3 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + optional: true + + '@napi-rs/canvas-android-arm64@0.1.91': + optional: true + + '@napi-rs/canvas-darwin-arm64@0.1.91': + optional: true + + '@napi-rs/canvas-darwin-x64@0.1.91': + optional: true + + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.91': + optional: true + + '@napi-rs/canvas-linux-arm64-gnu@0.1.91': + optional: true + + '@napi-rs/canvas-linux-arm64-musl@0.1.91': + optional: true + + '@napi-rs/canvas-linux-riscv64-gnu@0.1.91': + optional: true + + '@napi-rs/canvas-linux-x64-gnu@0.1.91': + optional: true + + '@napi-rs/canvas-linux-x64-musl@0.1.91': + optional: true + + '@napi-rs/canvas-win32-arm64-msvc@0.1.91': + optional: true + + '@napi-rs/canvas-win32-x64-msvc@0.1.91': + optional: true + + '@napi-rs/canvas@0.1.91': + optionalDependencies: + '@napi-rs/canvas-android-arm64': 0.1.91 + '@napi-rs/canvas-darwin-arm64': 0.1.91 + '@napi-rs/canvas-darwin-x64': 0.1.91 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.91 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.91 + '@napi-rs/canvas-linux-arm64-musl': 0.1.91 + '@napi-rs/canvas-linux-riscv64-gnu': 0.1.91 + '@napi-rs/canvas-linux-x64-gnu': 0.1.91 + '@napi-rs/canvas-linux-x64-musl': 0.1.91 + '@napi-rs/canvas-win32-arm64-msvc': 0.1.91 + '@napi-rs/canvas-win32-x64-msvc': 0.1.91 + optional: true + + '@napi-rs/nice-android-arm-eabi@1.1.1': + optional: true + + '@napi-rs/nice-android-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-x64@1.1.1': + optional: true + + '@napi-rs/nice-freebsd-x64@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-musl@1.1.1': + optional: true + + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-musl@1.1.1': + optional: true + + '@napi-rs/nice-openharmony-arm64@1.1.1': + optional: true + + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-x64-msvc@1.1.1': + optional: true + + '@napi-rs/nice@1.1.1': + optionalDependencies: + '@napi-rs/nice-android-arm-eabi': 1.1.1 + '@napi-rs/nice-android-arm64': 1.1.1 + '@napi-rs/nice-darwin-arm64': 1.1.1 + '@napi-rs/nice-darwin-x64': 1.1.1 + '@napi-rs/nice-freebsd-x64': 1.1.1 + '@napi-rs/nice-linux-arm-gnueabihf': 1.1.1 + '@napi-rs/nice-linux-arm64-gnu': 1.1.1 + '@napi-rs/nice-linux-arm64-musl': 1.1.1 + '@napi-rs/nice-linux-ppc64-gnu': 1.1.1 + '@napi-rs/nice-linux-riscv64-gnu': 1.1.1 + '@napi-rs/nice-linux-s390x-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-musl': 1.1.1 + '@napi-rs/nice-openharmony-arm64': 1.1.1 + '@napi-rs/nice-win32-arm64-msvc': 1.1.1 + '@napi-rs/nice-win32-ia32-msvc': 1.1.1 + '@napi-rs/nice-win32-x64-msvc': 1.1.1 + optional: true + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@next/env@16.1.6': {} + + '@next/eslint-plugin-next@16.1.6': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@16.1.6': + optional: true + + '@next/swc-darwin-x64@16.1.6': + optional: true + + '@next/swc-linux-arm64-gnu@16.1.6': + optional: true + + '@next/swc-linux-arm64-musl@16.1.6': + optional: true + + '@next/swc-linux-x64-gnu@16.1.6': + optional: true + + '@next/swc-linux-x64-musl@16.1.6': + optional: true + + '@next/swc-win32-arm64-msvc@16.1.6': + optional: true + + '@next/swc-win32-x64-msvc@16.1.6': + optional: true + + '@ngtools/webpack@21.2.1(@angular/compiler-cli@21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3))(typescript@5.9.3)(webpack@5.105.2(esbuild@0.27.3))': + dependencies: + '@angular/compiler-cli': 21.2.2(@angular/compiler@21.2.2)(typescript@5.9.3) + typescript: 5.9.3 + webpack: 5.105.2(esbuild@0.27.3) + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@npmcli/agent@4.0.0': + dependencies: + agent-base: 7.1.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 11.2.5 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + '@npmcli/fs@5.0.0': + dependencies: + semver: 7.7.4 + + '@npmcli/git@7.0.2': + dependencies: + '@gar/promise-retry': 1.0.2 + '@npmcli/promise-spawn': 9.0.1 + ini: 6.0.0 + lru-cache: 11.2.5 + npm-pick-manifest: 11.0.3 + proc-log: 6.1.0 + semver: 7.7.4 + which: 6.0.1 + + '@npmcli/installed-package-contents@4.0.0': + dependencies: + npm-bundled: 5.0.0 + npm-normalize-package-bin: 5.0.0 + + '@npmcli/node-gyp@5.0.0': {} + + '@npmcli/package-json@7.0.5': + dependencies: + '@npmcli/git': 7.0.2 + glob: 13.0.6 + hosted-git-info: 9.0.2 + json-parse-even-better-errors: 5.0.0 + proc-log: 6.1.0 + semver: 7.7.4 + spdx-expression-parse: 4.0.0 + + '@npmcli/promise-spawn@9.0.1': + dependencies: + which: 6.0.1 + + '@npmcli/redact@4.0.0': {} + + '@npmcli/run-script@10.0.4': + dependencies: + '@npmcli/node-gyp': 5.0.0 + '@npmcli/package-json': 7.0.5 + '@npmcli/promise-spawn': 9.0.1 + node-gyp: 12.2.0 + proc-log: 6.1.0 transitivePeerDependencies: - - '@types/react' - supports-color - - typescript - '@mintlify/models@0.0.255': + '@nuxt/cli@3.33.1(@nuxt/schema@4.3.1)(cac@6.7.14)(magicast@0.5.2)': dependencies: - axios: 1.10.0 - openapi-types: 12.1.3 + '@bomb.sh/tab': 0.0.12(cac@6.7.14)(citty@0.2.1) + '@clack/prompts': 1.1.0 + c12: 3.3.3(magicast@0.5.2) + citty: 0.2.1 + confbox: 0.2.4 + consola: 3.4.2 + copy-paste: 2.2.0 + debug: 4.4.3(supports-color@5.5.0) + defu: 6.1.4 + exsolve: 1.0.8 + fuse.js: 7.1.0 + fzf: 0.5.2 + giget: 3.1.2 + jiti: 2.6.1 + listhen: 1.9.0 + nypm: 0.6.5 + ofetch: 1.5.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + scule: 1.3.0 + semver: 7.7.4 + srvx: 0.11.9 + std-env: 3.10.0 + tinyexec: 1.0.2 + ufo: 1.6.3 + youch: 4.1.0 + optionalDependencies: + '@nuxt/schema': 4.3.1 transitivePeerDependencies: - - debug + - cac + - commander + - magicast + - supports-color - '@mintlify/models@0.0.268': + '@nuxt/devalue@2.0.2': {} + + '@nuxt/devtools-kit@3.2.3(magicast@0.5.2)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: - axios: 1.13.2 - openapi-types: 12.1.3 + '@nuxt/kit': 4.3.1(magicast@0.5.2) + execa: 8.0.1 + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - - debug + - magicast - '@mintlify/openapi-parser@0.0.8': + '@nuxt/devtools-wizard@3.2.3': dependencies: - ajv: 8.17.1 - ajv-draft-04: 1.0.0(ajv@8.17.1) - ajv-formats: 3.0.1(ajv@8.17.1) - jsonpointer: 5.0.1 - leven: 4.1.0 - yaml: 2.8.2 + '@clack/prompts': 1.1.0 + consola: 3.4.2 + diff: 8.0.3 + execa: 8.0.1 + magicast: 0.5.2 + pathe: 2.0.3 + pkg-types: 2.3.0 + semver: 7.7.4 - '@mintlify/prebuild@1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@nuxt/devtools@3.2.3(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': dependencies: - '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/openapi-parser': 0.0.8 - '@mintlify/scraping': 4.0.574(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - chalk: 5.3.0 - favicons: 7.2.0 - front-matter: 4.0.2 - fs-extra: 11.1.0 - js-yaml: 4.1.0 - openapi-types: 12.1.3 - sharp: 0.33.5 - sharp-ico: 0.1.5 - unist-util-visit: 4.1.2 - uuid: 11.1.0 + '@nuxt/devtools-kit': 3.2.3(magicast@0.5.2)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@nuxt/devtools-wizard': 3.2.3 + '@nuxt/kit': 4.3.1(magicast@0.5.2) + '@vue/devtools-core': 8.0.7(vue@3.5.25(typescript@5.9.3)) + '@vue/devtools-kit': 8.0.7 + birpc: 4.0.0 + consola: 3.4.2 + destr: 2.0.5 + error-stack-parser-es: 1.0.5 + execa: 8.0.1 + fast-npm-meta: 1.4.2 + get-port-please: 3.2.0 + hookable: 6.0.1 + image-meta: 0.2.2 + is-installed-globally: 1.0.0 + launch-editor: 2.13.1 + local-pkg: 1.1.2 + magicast: 0.5.2 + nypm: 0.6.5 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + semver: 7.7.4 + simple-git: 3.32.3 + sirv: 3.0.2 + structured-clone-es: 1.0.0 + tinyglobby: 0.2.15 + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-plugin-inspect: 11.3.3(@nuxt/kit@4.3.1(magicast@0.5.2))(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite-plugin-vue-tracer: 1.2.0(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + which: 5.0.0 + ws: 8.19.0 transitivePeerDependencies: - - '@radix-ui/react-popover' - - '@types/react' - - bare-abort-controller - - bare-buffer - bufferutil - - debug - - encoding - - react - - react-dom - - react-native-b4a - supports-color - - ts-node - - typescript - utf-8-validate + - vue - '@mintlify/previewing@4.0.905(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3)': + '@nuxt/kit@4.3.1(magicast@0.5.2)': dependencies: - '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/prebuild': 1.0.849(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/validation': 0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - better-opn: 3.0.2 - chalk: 5.2.0 - chokidar: 3.5.3 - express: 4.18.2 - front-matter: 4.0.2 - fs-extra: 11.1.0 - got: 13.0.0 - ink: 6.3.0(@types/react@19.2.11)(react@19.2.3) - ink-spinner: 5.0.0(ink@6.3.0(@types/react@19.2.11)(react@19.2.3))(react@19.2.3) - is-online: 10.0.0 - js-yaml: 4.1.0 - openapi-types: 12.1.3 - react: 19.2.3 - socket.io: 4.7.2 - tar: 6.1.15 - unist-util-visit: 4.1.2 - yargs: 17.7.1 + c12: 3.3.3(magicast@0.5.2) + consola: 3.4.2 + defu: 6.1.4 + destr: 2.0.5 + errx: 0.1.0 + exsolve: 1.0.8 + ignore: 7.0.5 + jiti: 2.6.1 + klona: 2.0.6 + mlly: 1.8.0 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.3.0 + rc9: 3.0.0 + scule: 1.3.0 + semver: 7.7.4 + tinyglobby: 0.2.15 + ufo: 1.6.3 + unctx: 2.5.0 + untyped: 2.0.0 transitivePeerDependencies: - - '@radix-ui/react-popover' - - '@types/react' - - bare-abort-controller - - bare-buffer - - bufferutil - - debug - - encoding - - react-devtools-core - - react-dom - - react-native-b4a - - supports-color - - ts-node - - typescript - - utf-8-validate + - magicast - '@mintlify/scraping@4.0.522(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@nuxt/nitro-server@4.3.1(@azure/identity@4.13.0)(db0@0.3.4)(ioredis@5.10.0)(magicast@0.5.2)(nuxt@4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2))(rolldown@1.0.0-rc.4)(typescript@5.9.3)(xml2js@0.6.2)': dependencies: - '@mintlify/common': 1.0.661(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/openapi-parser': 0.0.8 - fs-extra: 11.1.1 - hast-util-to-mdast: 10.1.0 - js-yaml: 4.1.0 - mdast-util-mdx-jsx: 3.1.3 - neotraverse: 0.6.18 - puppeteer: 22.14.0(typescript@5.9.3) - rehype-parse: 9.0.1 - remark-gfm: 4.0.0 - remark-mdx: 3.0.1 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.5 - unist-util-visit: 5.0.0 - yargs: 17.7.1 - zod: 3.21.4 + '@nuxt/devalue': 2.0.2 + '@nuxt/kit': 4.3.1(magicast@0.5.2) + '@unhead/vue': 2.1.10(vue@3.5.25(typescript@5.9.3)) + '@vue/shared': 3.5.25 + consola: 3.4.2 + defu: 6.1.4 + destr: 2.0.5 + devalue: 5.6.3 + errx: 0.1.0 + escape-string-regexp: 5.0.0 + exsolve: 1.0.8 + h3: 1.15.6 + impound: 1.1.5 + klona: 2.0.6 + mocked-exports: 0.1.1 + nitropack: 2.13.1(@azure/identity@4.13.0)(rolldown@1.0.0-rc.4)(xml2js@0.6.2) + nuxt: 4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2) + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.3.0 + rou3: 0.7.12 + std-env: 3.10.0 + ufo: 1.6.3 + unctx: 2.5.0 + unstorage: 1.17.4(@azure/identity@4.13.0)(db0@0.3.4)(ioredis@5.10.0) + vue: 3.5.25(typescript@5.9.3) + vue-bundle-renderer: 2.2.0 + vue-devtools-stub: 0.1.0 transitivePeerDependencies: - - '@radix-ui/react-popover' - - '@types/react' + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch - bare-abort-controller - - bare-buffer - - bufferutil - - debug + - better-sqlite3 + - db0 + - drizzle-orm - encoding - - react - - react-dom + - idb-keyval + - ioredis + - magicast + - mysql2 - react-native-b4a + - rolldown + - sqlite3 - supports-color - - ts-node - typescript - - utf-8-validate + - uploadthing + - xml2js - '@mintlify/scraping@4.0.574(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@nuxt/schema@4.3.1': dependencies: - '@mintlify/common': 1.0.713(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/openapi-parser': 0.0.8 - fs-extra: 11.1.1 - hast-util-to-mdast: 10.1.0 - js-yaml: 4.1.0 - mdast-util-mdx-jsx: 3.1.3 - neotraverse: 0.6.18 - puppeteer: 22.14.0(typescript@5.9.3) - rehype-parse: 9.0.1 - remark-gfm: 4.0.0 - remark-mdx: 3.0.1 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.5 - unist-util-visit: 5.0.0 - yargs: 17.7.1 - zod: 3.24.0 + '@vue/shared': 3.5.25 + defu: 6.1.4 + pathe: 2.0.3 + pkg-types: 2.3.0 + std-env: 3.10.0 + + '@nuxt/telemetry@2.7.0(@nuxt/kit@4.3.1(magicast@0.5.2))': + dependencies: + '@nuxt/kit': 4.3.1(magicast@0.5.2) + citty: 0.2.1 + consola: 3.4.2 + ofetch: 2.0.0-alpha.3 + rc9: 3.0.0 + std-env: 3.10.0 + + '@nuxt/vite-builder@4.3.1(@types/node@22.19.8)(eslint@9.39.2(jiti@2.6.1))(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(nuxt@4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2))(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))(yaml@2.8.2)': + dependencies: + '@nuxt/kit': 4.3.1(magicast@0.5.2) + '@rollup/plugin-replace': 6.0.3(rollup@4.57.1) + '@vitejs/plugin-vue': 6.0.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + '@vitejs/plugin-vue-jsx': 5.1.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + autoprefixer: 10.4.27(postcss@8.5.6) + consola: 3.4.2 + cssnano: 7.1.3(postcss@8.5.6) + defu: 6.1.4 + esbuild: 0.27.3 + escape-string-regexp: 5.0.0 + exsolve: 1.0.8 + get-port-please: 3.2.0 + jiti: 2.6.1 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.0 + mocked-exports: 0.1.1 + nuxt: 4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2) + pathe: 2.0.3 + pkg-types: 2.3.0 + postcss: 8.5.6 + rollup-plugin-visualizer: 6.0.11(rolldown@1.0.0-rc.4)(rollup@4.57.1) + seroval: 1.5.1 + std-env: 3.10.0 + ufo: 1.6.3 + unenv: 2.0.0-rc.24 + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 5.3.0(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-plugin-checker: 0.12.0(eslint@9.39.2(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(typescript@5.9.3) + vue: 3.5.25(typescript@5.9.3) + vue-bundle-renderer: 2.2.0 + optionalDependencies: + rolldown: 1.0.0-rc.4 transitivePeerDependencies: - - '@radix-ui/react-popover' - - '@types/react' - - bare-abort-controller - - bare-buffer - - bufferutil - - debug - - encoding - - react - - react-dom - - react-native-b4a + - '@biomejs/biome' + - '@types/node' + - eslint + - less + - magicast + - meow + - optionator + - oxlint + - rollup + - sass + - sass-embedded + - stylelint + - stylus + - sugarss - supports-color - - ts-node + - terser + - tsx - typescript - - utf-8-validate + - vls + - vti + - vue-tsc + - yaml + + '@octokit/auth-token@6.0.0': {} + + '@octokit/core@7.0.6': + dependencies: + '@octokit/auth-token': 6.0.0 + '@octokit/graphql': 9.0.3 + '@octokit/request': 10.0.7 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + before-after-hook: 4.0.0 + universal-user-agent: 7.0.3 + + '@octokit/endpoint@11.0.2': + dependencies: + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/graphql@9.0.3': + dependencies: + '@octokit/request': 10.0.7 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/openapi-types@26.0.0': {} + + '@octokit/openapi-types@27.0.0': {} + + '@octokit/plugin-paginate-rest@13.2.1(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 15.0.2 + + '@octokit/plugin-retry@8.0.3(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 + + '@octokit/plugin-throttling@11.0.3(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 - '@mintlify/validation@0.1.555(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@octokit/request-error@7.1.0': dependencies: - '@mintlify/mdx': 3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/models': 0.0.255 - arktype: 2.1.27 - js-yaml: 4.1.0 - lcm: 0.0.3 - lodash: 4.17.21 - object-hash: 3.0.0 - openapi-types: 12.1.3 - uuid: 11.1.0 - zod: 3.21.4 - zod-to-json-schema: 3.20.4(zod@3.21.4) - transitivePeerDependencies: - - '@radix-ui/react-popover' - - '@types/react' - - debug - - react - - react-dom - - supports-color - - typescript + '@octokit/types': 16.0.0 - '@mintlify/validation@0.1.585(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3)': + '@octokit/request@10.0.7': dependencies: - '@mintlify/mdx': 3.0.4(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(typescript@5.9.3) - '@mintlify/models': 0.0.268 - arktype: 2.1.27 - js-yaml: 4.1.0 - lcm: 0.0.3 - lodash: 4.17.21 - object-hash: 3.0.0 - openapi-types: 12.1.3 - uuid: 11.1.0 - zod: 3.24.0 - zod-to-json-schema: 3.20.4(zod@3.24.0) - transitivePeerDependencies: - - '@radix-ui/react-popover' - - '@types/react' - - debug - - react - - react-dom - - supports-color - - typescript + '@octokit/endpoint': 11.0.2 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + fast-content-type-parse: 3.0.0 + universal-user-agent: 7.0.3 - '@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)': + '@octokit/types@15.0.2': dependencies: - '@hono/node-server': 1.19.9(hono@4.12.1) - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - content-type: 1.0.5 - cors: 2.8.6 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.0.6 - express: 5.2.1 - express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.12.1 - jose: 6.1.3 - json-schema-typed: 8.0.2 - pkce-challenge: 5.0.1 - raw-body: 3.0.2 - zod: 4.3.6 - zod-to-json-schema: 3.25.1(zod@4.3.6) - transitivePeerDependencies: - - supports-color + '@octokit/openapi-types': 26.0.0 - '@napi-rs/canvas-android-arm64@0.1.91': + '@octokit/types@16.0.0': + dependencies: + '@octokit/openapi-types': 27.0.0 + + '@one-ini/wasm@0.1.1': {} + + '@openapi-contrib/openapi-schema-to-json-schema@3.2.0': + dependencies: + fast-deep-equal: 3.1.3 + + '@oxc-minify/binding-android-arm-eabi@0.112.0': optional: true - '@napi-rs/canvas-darwin-arm64@0.1.91': + '@oxc-minify/binding-android-arm64@0.112.0': optional: true - '@napi-rs/canvas-darwin-x64@0.1.91': + '@oxc-minify/binding-darwin-arm64@0.112.0': optional: true - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.91': + '@oxc-minify/binding-darwin-x64@0.112.0': optional: true - '@napi-rs/canvas-linux-arm64-gnu@0.1.91': + '@oxc-minify/binding-freebsd-x64@0.112.0': optional: true - '@napi-rs/canvas-linux-arm64-musl@0.1.91': + '@oxc-minify/binding-linux-arm-gnueabihf@0.112.0': optional: true - '@napi-rs/canvas-linux-riscv64-gnu@0.1.91': + '@oxc-minify/binding-linux-arm-musleabihf@0.112.0': optional: true - '@napi-rs/canvas-linux-x64-gnu@0.1.91': + '@oxc-minify/binding-linux-arm64-gnu@0.112.0': optional: true - '@napi-rs/canvas-linux-x64-musl@0.1.91': + '@oxc-minify/binding-linux-arm64-musl@0.112.0': optional: true - '@napi-rs/canvas-win32-arm64-msvc@0.1.91': + '@oxc-minify/binding-linux-ppc64-gnu@0.112.0': optional: true - '@napi-rs/canvas-win32-x64-msvc@0.1.91': + '@oxc-minify/binding-linux-riscv64-gnu@0.112.0': optional: true - '@napi-rs/canvas@0.1.91': - optionalDependencies: - '@napi-rs/canvas-android-arm64': 0.1.91 - '@napi-rs/canvas-darwin-arm64': 0.1.91 - '@napi-rs/canvas-darwin-x64': 0.1.91 - '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.91 - '@napi-rs/canvas-linux-arm64-gnu': 0.1.91 - '@napi-rs/canvas-linux-arm64-musl': 0.1.91 - '@napi-rs/canvas-linux-riscv64-gnu': 0.1.91 - '@napi-rs/canvas-linux-x64-gnu': 0.1.91 - '@napi-rs/canvas-linux-x64-musl': 0.1.91 - '@napi-rs/canvas-win32-arm64-msvc': 0.1.91 - '@napi-rs/canvas-win32-x64-msvc': 0.1.91 + '@oxc-minify/binding-linux-riscv64-musl@0.112.0': optional: true - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 + '@oxc-minify/binding-linux-s390x-gnu@0.112.0': optional: true - '@napi-rs/wasm-runtime@1.1.1': - dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 - '@tybys/wasm-util': 0.10.1 + '@oxc-minify/binding-linux-x64-gnu@0.112.0': optional: true - '@nodelib/fs.scandir@2.1.5': + '@oxc-minify/binding-linux-x64-musl@0.112.0': + optional: true + + '@oxc-minify/binding-openharmony-arm64@0.112.0': + optional: true + + '@oxc-minify/binding-wasm32-wasi@0.112.0': dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + '@napi-rs/wasm-runtime': 1.1.1 + optional: true - '@nodelib/fs.stat@2.0.5': {} + '@oxc-minify/binding-win32-arm64-msvc@0.112.0': + optional: true - '@nodelib/fs.walk@1.2.8': + '@oxc-minify/binding-win32-ia32-msvc@0.112.0': + optional: true + + '@oxc-minify/binding-win32-x64-msvc@0.112.0': + optional: true + + '@oxc-parser/binding-android-arm-eabi@0.112.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.112.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.112.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.112.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.112.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.112.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.112.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.112.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.112.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.112.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.112.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.112.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.112.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.112.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.112.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.112.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.112.0': dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 + '@napi-rs/wasm-runtime': 1.1.1 + optional: true - '@octokit/auth-token@6.0.0': {} + '@oxc-parser/binding-win32-arm64-msvc@0.112.0': + optional: true - '@octokit/core@7.0.6': + '@oxc-parser/binding-win32-ia32-msvc@0.112.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.112.0': + optional: true + + '@oxc-project/runtime@0.101.0': {} + + '@oxc-project/types@0.101.0': {} + + '@oxc-project/types@0.112.0': {} + + '@oxc-project/types@0.113.0': {} + + '@oxc-transform/binding-android-arm-eabi@0.112.0': + optional: true + + '@oxc-transform/binding-android-arm64@0.112.0': + optional: true + + '@oxc-transform/binding-darwin-arm64@0.112.0': + optional: true + + '@oxc-transform/binding-darwin-x64@0.112.0': + optional: true + + '@oxc-transform/binding-freebsd-x64@0.112.0': + optional: true + + '@oxc-transform/binding-linux-arm-gnueabihf@0.112.0': + optional: true + + '@oxc-transform/binding-linux-arm-musleabihf@0.112.0': + optional: true + + '@oxc-transform/binding-linux-arm64-gnu@0.112.0': + optional: true + + '@oxc-transform/binding-linux-arm64-musl@0.112.0': + optional: true + + '@oxc-transform/binding-linux-ppc64-gnu@0.112.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-gnu@0.112.0': + optional: true + + '@oxc-transform/binding-linux-riscv64-musl@0.112.0': + optional: true + + '@oxc-transform/binding-linux-s390x-gnu@0.112.0': + optional: true + + '@oxc-transform/binding-linux-x64-gnu@0.112.0': + optional: true + + '@oxc-transform/binding-linux-x64-musl@0.112.0': + optional: true + + '@oxc-transform/binding-openharmony-arm64@0.112.0': + optional: true + + '@oxc-transform/binding-wasm32-wasi@0.112.0': dependencies: - '@octokit/auth-token': 6.0.0 - '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.7 - '@octokit/request-error': 7.1.0 - '@octokit/types': 16.0.0 - before-after-hook: 4.0.0 - universal-user-agent: 7.0.3 + '@napi-rs/wasm-runtime': 1.1.1 + optional: true - '@octokit/endpoint@11.0.2': + '@oxc-transform/binding-win32-arm64-msvc@0.112.0': + optional: true + + '@oxc-transform/binding-win32-ia32-msvc@0.112.0': + optional: true + + '@oxc-transform/binding-win32-x64-msvc@0.112.0': + optional: true + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-wasm@2.5.6': dependencies: - '@octokit/types': 16.0.0 - universal-user-agent: 7.0.3 + is-glob: 4.0.3 + picomatch: 4.0.3 - '@octokit/graphql@9.0.3': - dependencies: - '@octokit/request': 10.0.7 - '@octokit/types': 16.0.0 - universal-user-agent: 7.0.3 + '@parcel/watcher-win32-arm64@2.5.6': + optional: true - '@octokit/openapi-types@26.0.0': {} + '@parcel/watcher-win32-ia32@2.5.6': + optional: true - '@octokit/openapi-types@27.0.0': {} + '@parcel/watcher-win32-x64@2.5.6': + optional: true - '@octokit/plugin-paginate-rest@13.2.1(@octokit/core@7.0.6)': + '@parcel/watcher@2.5.6': dependencies: - '@octokit/core': 7.0.6 - '@octokit/types': 15.0.2 + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.3 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + + '@peculiar/asn1-cms@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 - '@octokit/plugin-retry@8.0.3(@octokit/core@7.0.6)': + '@peculiar/asn1-csr@2.6.1': dependencies: - '@octokit/core': 7.0.6 - '@octokit/request-error': 7.1.0 - '@octokit/types': 16.0.0 - bottleneck: 2.19.5 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 - '@octokit/plugin-throttling@11.0.3(@octokit/core@7.0.6)': + '@peculiar/asn1-ecc@2.6.1': dependencies: - '@octokit/core': 7.0.6 - '@octokit/types': 16.0.0 - bottleneck: 2.19.5 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 - '@octokit/request-error@7.1.0': + '@peculiar/asn1-pfx@2.6.1': dependencies: - '@octokit/types': 16.0.0 + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + tslib: 2.8.1 - '@octokit/request@10.0.7': + '@peculiar/asn1-pkcs8@2.6.1': dependencies: - '@octokit/endpoint': 11.0.2 - '@octokit/request-error': 7.1.0 - '@octokit/types': 16.0.0 - fast-content-type-parse: 3.0.0 - universal-user-agent: 7.0.3 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 - '@octokit/types@15.0.2': + '@peculiar/asn1-pkcs9@2.6.1': dependencies: - '@octokit/openapi-types': 26.0.0 + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-pfx': 2.6.1 + '@peculiar/asn1-pkcs8': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + '@peculiar/asn1-x509-attr': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 - '@octokit/types@16.0.0': + '@peculiar/asn1-rsa@2.6.1': dependencies: - '@octokit/openapi-types': 27.0.0 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 - '@one-ini/wasm@0.1.1': {} + '@peculiar/asn1-schema@2.6.0': + dependencies: + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 - '@openapi-contrib/openapi-schema-to-json-schema@3.2.0': + '@peculiar/asn1-x509-attr@2.6.1': dependencies: - fast-deep-equal: 3.1.3 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + asn1js: 3.0.7 + tslib: 2.8.1 - '@oxc-project/runtime@0.101.0': {} + '@peculiar/asn1-x509@2.6.1': + dependencies: + '@peculiar/asn1-schema': 2.6.0 + asn1js: 3.0.7 + pvtsutils: 1.3.6 + tslib: 2.8.1 - '@oxc-project/types@0.101.0': {} + '@peculiar/x509@1.14.3': + dependencies: + '@peculiar/asn1-cms': 2.6.1 + '@peculiar/asn1-csr': 2.6.1 + '@peculiar/asn1-ecc': 2.6.1 + '@peculiar/asn1-pkcs9': 2.6.1 + '@peculiar/asn1-rsa': 2.6.1 + '@peculiar/asn1-schema': 2.6.0 + '@peculiar/asn1-x509': 2.6.1 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 '@pinojs/redact@0.4.0': {} @@ -13670,6 +20870,18 @@ snapshots: '@popperjs/core@2.11.8': {} + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.7.0': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.2.0 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + '@puppeteer/browsers@2.3.0': dependencies: debug: 4.4.3(supports-color@5.5.0) @@ -13876,50 +21088,111 @@ snapshots: '@rolldown/binding-android-arm64@1.0.0-beta.53': optional: true + '@rolldown/binding-android-arm64@1.0.0-rc.4': + optional: true + '@rolldown/binding-darwin-arm64@1.0.0-beta.53': optional: true + '@rolldown/binding-darwin-arm64@1.0.0-rc.4': + optional: true + '@rolldown/binding-darwin-x64@1.0.0-beta.53': optional: true + '@rolldown/binding-darwin-x64@1.0.0-rc.4': + optional: true + '@rolldown/binding-freebsd-x64@1.0.0-beta.53': optional: true + '@rolldown/binding-freebsd-x64@1.0.0-rc.4': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.4': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.4': + optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.4': + optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.4': + optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-rc.4': + optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-rc.4': + optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-rc.4': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.4': + optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.4': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.27': {} + '@rolldown/pluginutils@1.0.0-beta.50': {} '@rolldown/pluginutils@1.0.0-beta.53': {} '@rolldown/pluginutils@1.0.0-rc.2': {} + '@rolldown/pluginutils@1.0.0-rc.4': {} + + '@rollup/plugin-alias@6.0.0(rollup@4.57.1)': + optionalDependencies: + rollup: 4.57.1 + + '@rollup/plugin-commonjs@29.0.2(rollup@4.57.1)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.5.0(picomatch@4.0.3) + is-reference: 1.2.1 + magic-string: 0.30.21 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.57.1 + '@rollup/plugin-inject@5.0.5(rollup@4.57.1)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.57.1) @@ -13928,6 +21201,37 @@ snapshots: optionalDependencies: rollup: 4.57.1 + '@rollup/plugin-json@6.1.0(rollup@4.57.1)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + optionalDependencies: + rollup: 4.57.1 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.57.1)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.11 + optionalDependencies: + rollup: 4.57.1 + + '@rollup/plugin-replace@6.0.3(rollup@4.57.1)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.57.1 + + '@rollup/plugin-terser@0.4.4(rollup@4.57.1)': + dependencies: + serialize-javascript: 6.0.2 + smob: 1.6.1 + terser: 5.46.0 + optionalDependencies: + rollup: 4.57.1 + '@rollup/pluginutils@5.3.0(rollup@4.57.1)': dependencies: '@types/estree': 1.0.8 @@ -14011,6 +21315,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.57.1': optional: true + '@rtsao/scc@1.1.0': {} + '@rushstack/node-core-library@5.19.1(@types/node@22.19.2)': dependencies: ajv: 8.13.0 @@ -14084,6 +21390,14 @@ snapshots: transitivePeerDependencies: - '@types/node' + '@schematics/angular@21.2.1(chokidar@5.0.0)': + dependencies: + '@angular-devkit/core': 21.2.1(chokidar@5.0.0) + '@angular-devkit/schematics': 21.2.1(chokidar@5.0.0) + jsonc-parser: 3.3.1 + transitivePeerDependencies: + - chokidar + '@sec-ant/readable-stream@0.4.1': {} '@semantic-release/changelog@6.0.3(semantic-release@24.2.9(typescript@5.9.3))': @@ -14240,10 +21554,44 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@sigstore/bundle@4.0.0': + dependencies: + '@sigstore/protobuf-specs': 0.5.0 + + '@sigstore/core@3.1.0': {} + + '@sigstore/protobuf-specs@0.5.0': {} + + '@sigstore/sign@4.1.0': + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.1.0 + '@sigstore/protobuf-specs': 0.5.0 + make-fetch-happen: 15.0.4 + proc-log: 6.1.0 + promise-retry: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@4.0.1': + dependencies: + '@sigstore/protobuf-specs': 0.5.0 + tuf-js: 4.1.0 + transitivePeerDependencies: + - supports-color + + '@sigstore/verify@3.1.0': + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.1.0 + '@sigstore/protobuf-specs': 0.5.0 + '@sindresorhus/is@4.6.0': {} '@sindresorhus/is@5.6.0': {} + '@sindresorhus/is@7.2.0': {} + '@sindresorhus/merge-streams@4.0.0': {} '@sindresorhus/slugify@2.2.0': @@ -14595,6 +21943,10 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} + '@speed-highlight/core@1.2.14': {} + + '@stablelib/base64@1.0.1': {} + '@stoplight/better-ajv-errors@1.0.3(ajv@8.17.1)': dependencies: ajv: 8.17.1 @@ -14738,6 +22090,63 @@ snapshots: '@stoplight/yaml-ast-parser': 0.0.50 tslib: 2.8.1 + '@superdoc-dev/react@1.0.0-rc.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.5.4)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19)': + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + superdoc: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.5.4)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + transitivePeerDependencies: + - '@hocuspocus/provider' + - '@vue/composition-api' + - bufferutil + - canvas + - pdfjs-dist + - supports-color + - typescript + - utf-8-validate + - y-prosemirror + - yjs + + '@superdoc-dev/react@1.0.0-rc.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19)': + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + superdoc: 1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + transitivePeerDependencies: + - '@hocuspocus/provider' + - '@vue/composition-api' + - bufferutil + - canvas + - pdfjs-dist + - supports-color + - typescript + - utf-8-validate + - y-prosemirror + - yjs + + '@superdoc-dev/sdk-darwin-arm64@1.0.0-alpha.39': + optional: true + + '@superdoc-dev/sdk-darwin-x64@1.0.0-alpha.39': + optional: true + + '@superdoc-dev/sdk-linux-arm64@1.0.0-alpha.39': + optional: true + + '@superdoc-dev/sdk-linux-x64@1.0.0-alpha.39': + optional: true + + '@superdoc-dev/sdk-windows-x64@1.0.0-alpha.39': + optional: true + + '@superdoc-dev/sdk@1.0.0-alpha.39': + optionalDependencies: + '@superdoc-dev/sdk-darwin-arm64': 1.0.0-alpha.39 + '@superdoc-dev/sdk-darwin-x64': 1.0.0-alpha.39 + '@superdoc-dev/sdk-linux-arm64': 1.0.0-alpha.39 + '@superdoc-dev/sdk-linux-x64': 1.0.0-alpha.39 + '@superdoc-dev/sdk-windows-x64': 1.0.0-alpha.39 + '@superdoc-dev/sdk@file:packages/sdk/langs/node': optionalDependencies: '@superdoc-dev/sdk-darwin-arm64': link:packages/sdk/langs/node/platforms/sdk-darwin-arm64 @@ -14746,6 +22155,12 @@ snapshots: '@superdoc-dev/sdk-linux-x64': link:packages/sdk/langs/node/platforms/sdk-linux-x64 '@superdoc-dev/sdk-windows-x64': link:packages/sdk/langs/node/platforms/sdk-windows-x64 + '@superdoc-dev/superdoc-yjs-collaboration@1.0.2': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 @@ -14754,6 +22169,75 @@ snapshots: dependencies: defer-to-connect: 2.0.1 + '@tailwindcss/node@4.2.1': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.0 + jiti: 2.6.1 + lightningcss: 1.31.1 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.1 + + '@tailwindcss/oxide-android-arm64@4.2.1': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.1': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.1': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.1': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.1': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.1': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.1': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.1': + optional: true + + '@tailwindcss/oxide@4.2.1': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-arm64': 4.2.1 + '@tailwindcss/oxide-darwin-x64': 4.2.1 + '@tailwindcss/oxide-freebsd-x64': 4.2.1 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.1 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.1 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.1 + '@tailwindcss/oxide-linux-x64-musl': 4.2.1 + '@tailwindcss/oxide-wasm32-wasi': 4.2.1 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.1 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.1 + + '@tailwindcss/postcss@4.2.1': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.2.1 + '@tailwindcss/oxide': 4.2.1 + postcss: 8.5.6 + tailwindcss: 4.2.1 + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 @@ -14790,6 +22274,13 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} + '@tufjs/canonical-json@2.0.0': {} + + '@tufjs/models@4.1.0': + dependencies: + '@tufjs/canonical-json': 2.0.0 + minimatch: 10.1.2 + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -14824,6 +22315,15 @@ snapshots: dependencies: '@babel/types': 7.29.0 + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 22.19.8 + + '@types/bonjour@3.5.13': + dependencies: + '@types/node': 22.19.8 + '@types/bun@1.3.8': dependencies: bun-types: 1.3.8 @@ -14833,6 +22333,15 @@ snapshots: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + '@types/connect-history-api-fallback@1.5.4': + dependencies: + '@types/express-serve-static-core': 4.19.8 + '@types/node': 22.19.8 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.19.8 + '@types/conventional-commits-parser@5.0.2': dependencies: '@types/node': 22.19.8 @@ -14853,12 +22362,36 @@ snapshots: dependencies: '@types/node': 22.19.8 + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.8 '@types/estree@1.0.8': {} + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 22.19.8 + '@types/qs': 6.15.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.0 + '@types/serve-static': 1.15.10 + '@types/extend@3.0.4': {} '@types/fs-extra@8.1.5': @@ -14880,8 +22413,16 @@ snapshots: '@types/http-cache-semantics@4.2.0': {} + '@types/http-errors@2.0.5': {} + + '@types/http-proxy@1.17.17': + dependencies: + '@types/node': 22.19.8 + '@types/json-schema@7.0.15': {} + '@types/json5@0.0.29': {} + '@types/katex@0.16.8': {} '@types/lodash-es@4.17.12': @@ -14900,6 +22441,8 @@ snapshots: '@types/mdx@2.0.13': {} + '@types/mime@1.3.5': {} + '@types/minimatch@6.0.0': dependencies: minimatch: 10.1.2 @@ -14910,6 +22453,10 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/node@20.19.37': + dependencies: + undici-types: 6.21.0 + '@types/node@22.19.2': dependencies: undici-types: 6.21.0 @@ -14922,18 +22469,60 @@ snapshots: '@types/parse5@6.0.3': {} + '@types/prop-types@15.7.15': {} + + '@types/qs@6.15.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-dom@18.3.7(@types/react@18.3.28)': + dependencies: + '@types/react': 18.3.28 + '@types/react-dom@19.2.3(@types/react@19.2.11)': dependencies: '@types/react': 19.2.11 + '@types/react@18.3.28': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + '@types/react@19.2.11': dependencies: csstype: 3.2.3 + '@types/resolve@1.20.2': {} + '@types/responselike@1.0.0': dependencies: '@types/node': 22.19.8 + '@types/retry@0.12.2': {} + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 22.19.8 + + '@types/send@1.2.1': + dependencies: + '@types/node': 22.19.8 + + '@types/serve-index@1.9.4': + dependencies: + '@types/express': 4.17.25 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 22.19.8 + '@types/send': 0.17.6 + + '@types/sockjs@0.3.36': + dependencies: + '@types/node': 22.19.8 + '@types/supports-color@8.1.3': {} '@types/unist@2.0.11': {} @@ -15063,6 +22652,12 @@ snapshots: '@ungap/structured-clone@1.3.0': {} + '@unhead/vue@2.1.10(vue@3.5.25(typescript@5.9.3))': + dependencies: + hookable: 6.0.1 + unhead: 2.1.10 + vue: 3.5.25(typescript@5.9.3) + '@unrs/resolver-binding-android-arm-eabi@1.11.1': optional: true @@ -15122,6 +22717,25 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true + '@vercel/nft@1.3.2(rollup@4.57.1)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.3 + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 13.0.6 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.4 + picomatch: 4.0.3 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + '@verdaccio/auth@8.0.0-next-8.29': dependencies: '@verdaccio/config': 8.0.0-next-8.29 @@ -15279,7 +22893,23 @@ snapshots: lodash: 4.17.21 minimatch: 7.4.6 - '@vitejs/plugin-react@5.1.3(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-basic-ssl@2.1.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + '@vitejs/plugin-react@4.7.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-react@5.1.3(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -15287,11 +22917,11 @@ snapshots: '@rolldown/pluginutils': 1.0.0-rc.2 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@5.1.3(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -15299,23 +22929,46 @@ snapshots: '@rolldown/pluginutils': 1.0.0-rc.2 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue-jsx@5.1.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.2 + '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.0) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vue: 3.5.25(typescript@5.9.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@6.0.2(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': + '@vitejs/plugin-vue@5.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': + dependencies: + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vue: 3.5.25(typescript@5.9.3) + + '@vitejs/plugin-vue@6.0.2(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.50 - vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vue: 3.5.25(typescript@5.9.3) - '@vitejs/plugin-vue@6.0.2(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': + '@vitejs/plugin-vue@6.0.2(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.50 - vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vue: 3.5.25(typescript@5.9.3) + + '@vitejs/plugin-vue@6.0.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': + dependencies: + '@rolldown/pluginutils': 1.0.0-rc.2 + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vue: 3.5.25(typescript@5.9.3) - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -15330,7 +22983,7 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -15342,21 +22995,29 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + '@vitest/mocker@3.2.4(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@vitest/mocker@3.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@3.2.4': dependencies: @@ -15466,6 +23127,45 @@ snapshots: transitivePeerDependencies: - supports-color + '@vue-macros/common@3.1.2(vue@3.5.25(typescript@5.9.3))': + dependencies: + '@vue/compiler-sfc': 3.5.25 + ast-kit: 2.2.0 + local-pkg: 1.1.2 + magic-string-ast: 1.0.3 + unplugin-utils: 0.3.1 + optionalDependencies: + vue: 3.5.25(typescript@5.9.3) + + '@vue/babel-helper-vue-transform-on@2.0.1': {} + + '@vue/babel-plugin-jsx@2.0.1(@babel/core@7.29.0)': + dependencies: + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@vue/babel-helper-vue-transform-on': 2.0.1 + '@vue/babel-plugin-resolve-type': 2.0.1(@babel/core@7.29.0) + '@vue/shared': 3.5.25 + optionalDependencies: + '@babel/core': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@2.0.1(@babel/core@7.29.0)': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/parser': 7.29.0 + '@vue/compiler-sfc': 3.5.25 + transitivePeerDependencies: + - supports-color + '@vue/compiler-core@3.5.25': dependencies: '@babel/parser': 7.29.0 @@ -15503,6 +23203,21 @@ snapshots: '@vue/devtools-api@6.6.4': {} + '@vue/devtools-core@8.0.7(vue@3.5.25(typescript@5.9.3))': + dependencies: + '@vue/devtools-kit': 8.0.7 + '@vue/devtools-shared': 8.0.7 + vue: 3.5.25(typescript@5.9.3) + + '@vue/devtools-kit@8.0.7': + dependencies: + '@vue/devtools-shared': 8.0.7 + birpc: 2.9.0 + hookable: 5.5.3 + perfect-debounce: 2.1.0 + + '@vue/devtools-shared@8.0.7': {} + '@vue/language-core@2.2.0(typescript@5.9.3)': dependencies: '@volar/language-core': 2.4.28 @@ -15516,6 +23231,16 @@ snapshots: optionalDependencies: typescript: 5.9.3 + '@vue/language-core@3.2.5': + dependencies: + '@volar/language-core': 2.4.28 + '@vue/compiler-dom': 3.5.25 + '@vue/shared': 3.5.25 + alien-signals: 3.1.2 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.3 + '@vue/reactivity@3.5.25': dependencies: '@vue/shared': 3.5.25 @@ -15532,6 +23257,12 @@ snapshots: '@vue/shared': 3.5.25 csstype: 3.2.3 + '@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.5.4))': + dependencies: + '@vue/compiler-ssr': 3.5.25 + '@vue/shared': 3.5.25 + vue: 3.5.25(typescript@5.5.4) + '@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.9.3))': dependencies: '@vue/compiler-ssr': 3.5.25 @@ -15545,6 +23276,88 @@ snapshots: js-beautify: 1.15.4 vue-component-type-helpers: 2.2.12 + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + '@yarnpkg/lockfile@1.1.0': {} + '@zeit/schemas@2.36.0': {} JSONStream@1.3.5: @@ -15554,10 +23367,16 @@ snapshots: abbrev@2.0.0: {} + abbrev@3.0.1: {} + + abbrev@4.0.0: {} + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 + abstract-logging@2.0.1: {} + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -15568,6 +23387,14 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 + acorn-import-attributes@1.9.5(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-import-phases@1.0.4(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx@5.3.2(acorn@8.11.2): dependencies: acorn: 8.11.2 @@ -15580,8 +23407,15 @@ snapshots: acorn@8.15.0: {} + acorn@8.16.0: {} + address@1.2.2: {} + adjust-sourcemap-loader@4.0.0: + dependencies: + loader-utils: 2.0.4 + regex-parser: 2.3.1 + adm-zip@0.5.16: {} agent-base@6.0.2: @@ -15631,6 +23465,15 @@ snapshots: optionalDependencies: ajv: 8.17.1 + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -15659,12 +23502,40 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + algoliasearch@5.48.1: + dependencies: + '@algolia/abtesting': 1.14.1 + '@algolia/client-abtesting': 5.48.1 + '@algolia/client-analytics': 5.48.1 + '@algolia/client-common': 5.48.1 + '@algolia/client-insights': 5.48.1 + '@algolia/client-personalization': 5.48.1 + '@algolia/client-query-suggestions': 5.48.1 + '@algolia/client-search': 5.48.1 + '@algolia/ingestion': 1.48.1 + '@algolia/monitoring': 1.48.1 + '@algolia/recommend': 5.48.1 + '@algolia/requester-browser-xhr': 5.48.1 + '@algolia/requester-fetch': 5.48.1 + '@algolia/requester-node-http': 5.48.1 + alien-signals@0.4.14: {} + alien-signals@3.1.2: {} + ansi-align@3.0.1: dependencies: string-width: 4.2.3 + ansi-colors@4.1.3: {} + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -15673,6 +23544,8 @@ snapshots: dependencies: environment: 1.1.0 + ansi-html-community@0.0.8: {} + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -15689,6 +23562,8 @@ snapshots: ansi-styles@6.2.3: {} + ansis@4.2.0: {} + any-promise@1.3.0: {} anymatch@3.1.3: @@ -15700,6 +23575,29 @@ snapshots: arch@2.2.0: {} + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.23 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.1.7 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + are-docs-informative@0.0.2: {} arg@5.0.2: {} @@ -15775,6 +23673,16 @@ snapshots: es-object-atoms: 1.1.1 es-shim-unscopables: 1.1.0 + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + array.prototype.flat@1.3.3: dependencies: call-bind: 1.0.8 @@ -15817,6 +23725,12 @@ snapshots: dependencies: safer-buffer: 2.1.2 + asn1js@3.0.7: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + assert-plus@1.0.0: {} assert@2.1.0: @@ -15829,6 +23743,13 @@ snapshots: assertion-error@2.0.1: {} + ast-kit@2.2.0: + dependencies: + '@babel/parser': 7.29.0 + pathe: 2.0.3 + + ast-types-flow@0.0.8: {} + ast-types@0.13.4: dependencies: tslib: 2.8.1 @@ -15839,12 +23760,19 @@ snapshots: estree-walker: 3.0.3 js-tokens: 10.0.0 + ast-walker-scope@0.8.3: + dependencies: + '@babel/parser': 7.29.0 + ast-kit: 2.2.0 + astring@1.9.0: {} async-function@1.0.0: {} async-lock@1.4.1: {} + async-sema@3.1.1: {} + async-validator@4.2.5: {} async@3.2.6: {} @@ -15855,43 +23783,101 @@ snapshots: auto-bind@5.0.1: {} + autoprefixer@10.4.27(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001777 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 avsc@5.7.9: {} + avvio@9.2.0: + dependencies: + '@fastify/error': 4.2.0 + fastq: 1.20.1 + aws-sign2@0.7.0: {} aws4@1.13.2: {} - axios@1.10.0: + axe-core@4.11.1: {} + + axios@1.10.0: + dependencies: + follow-redirects: 1.15.11(debug@4.4.3) + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axios@1.13.2: + dependencies: + follow-redirects: 1.15.11(debug@4.4.3) + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axobject-query@4.1.0: {} + + azure-devops-node-api@12.5.0: + dependencies: + tunnel: 0.0.6 + typed-rest-client: 1.8.11 + + b4a@1.7.3: {} + + babel-loader@10.0.0(@babel/core@7.29.0)(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + '@babel/core': 7.29.0 + find-up: 5.0.0 + webpack: 5.105.2(esbuild@0.27.3) + + babel-plugin-polyfill-corejs2@0.4.16(@babel/core@7.29.0): + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.7(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.5 - proxy-from-env: 1.1.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.7(@babel/core@7.29.0) + core-js-compat: 3.48.0 transitivePeerDependencies: - - debug + - supports-color - axios@1.13.2: + babel-plugin-polyfill-corejs3@0.14.1(@babel/core@7.29.0): dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.5 - proxy-from-env: 1.1.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.7(@babel/core@7.29.0) + core-js-compat: 3.48.0 transitivePeerDependencies: - - debug + - supports-color - azure-devops-node-api@12.5.0: + babel-plugin-polyfill-regenerator@0.6.7(@babel/core@7.29.0): dependencies: - tunnel: 0.0.6 - typed-rest-client: 1.8.11 - - b4a@1.7.3: {} + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.7(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color bail@2.0.2: {} balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + bare-events@2.8.2: {} bare-fs@4.5.3: @@ -15937,12 +23923,26 @@ snapshots: basic-ftp@5.1.0: {} + batch@0.6.1: {} + bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 bcryptjs@2.4.3: {} + beasties@0.4.1: + dependencies: + css-select: 6.0.0 + css-what: 7.0.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + htmlparser2: 10.1.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-media-query-parser: 0.2.3 + postcss-safe-parser: 7.0.1(postcss@8.5.6) + before-after-hook@4.0.0: {} better-opn@3.0.2: @@ -15953,8 +23953,18 @@ snapshots: dependencies: require-from-string: 2.0.2 + big.js@5.2.2: {} + binary-extensions@2.3.0: {} + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + birpc@2.9.0: {} + + birpc@4.0.0: {} + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -16013,6 +24023,11 @@ snapshots: transitivePeerDependencies: - supports-color + bonjour-service@1.3.0: + dependencies: + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + boolbase@1.0.0: {} bottleneck@2.19.5: {} @@ -16039,6 +24054,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.4: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -16144,8 +24163,41 @@ snapshots: bytes@3.1.2: {} + bytestreamjs@2.0.1: {} + + c12@3.3.3(magicast@0.5.2): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 17.3.1 + exsolve: 1.0.8 + giget: 2.0.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + optionalDependencies: + magicast: 0.5.2 + cac@6.7.14: {} + cacache@20.0.3: + dependencies: + '@npmcli/fs': 5.0.0 + fs-minipass: 3.0.3 + glob: 13.0.6 + lru-cache: 11.2.5 + minipass: 7.1.2 + minipass-collect: 2.0.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 7.0.4 + ssri: 13.0.1 + unique-filename: 5.0.0 + cacheable-lookup@6.1.0: {} cacheable-lookup@7.0.0: {} @@ -16193,8 +24245,17 @@ snapshots: camelcase@7.0.1: {} + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001767 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + caniuse-lite@1.0.30001767: {} + caniuse-lite@1.0.30001777: {} + canvas@3.2.1: dependencies: node-addon-api: 7.1.1 @@ -16300,10 +24361,18 @@ snapshots: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + chownr@1.1.4: {} chownr@2.0.0: {} + chownr@3.0.0: {} + + chrome-trace-event@1.0.4: {} + chromium-bidi@0.6.2(devtools-protocol@0.0.1312386): dependencies: devtools-protocol: 0.0.1312386 @@ -16317,6 +24386,12 @@ snapshots: safe-buffer: 5.2.1 to-buffer: 1.2.2 + citty@0.1.6: + dependencies: + consola: 3.4.2 + + citty@0.2.1: {} + clean-stack@2.2.0: {} clean-stack@4.2.0: @@ -16333,6 +24408,10 @@ snapshots: dependencies: restore-cursor: 4.0.0 + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + cli-highlight@2.1.11: dependencies: chalk: 4.1.2 @@ -16344,6 +24423,8 @@ snapshots: cli-spinners@2.9.2: {} + cli-spinners@3.4.0: {} + cli-table3@0.6.5: dependencies: string-width: 4.2.3 @@ -16355,8 +24436,15 @@ snapshots: slice-ansi: 5.0.0 string-width: 7.2.0 + cli-truncate@5.2.0: + dependencies: + slice-ansi: 8.0.0 + string-width: 8.2.0 + cli-width@4.1.0: {} + client-only@0.0.1: {} + clipanion@4.0.0-rc.4(typanion@3.14.0): dependencies: typanion: 3.14.0 @@ -16367,6 +24455,12 @@ snapshots: execa: 5.1.1 is-wsl: 2.2.0 + clipboardy@4.0.0: + dependencies: + execa: 8.0.1 + is-wsl: 3.1.0 + is64bit: 2.0.0 + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -16379,10 +24473,24 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + clone-response@1.0.3: dependencies: mimic-response: 1.0.1 + cluster-key-slot@1.1.2: {} + cockatiel@3.2.1: {} code-excerpt@4.0.0: @@ -16417,6 +24525,8 @@ snapshots: color-convert: 2.0.1 color-string: 1.9.1 + colord@2.9.3: {} + colorette@1.4.0: {} colorette@2.0.20: {} @@ -16429,6 +24539,10 @@ snapshots: commander@10.0.1: {} + commander@11.1.0: {} + + commander@2.20.3: {} + commander@4.1.1: {} commander@6.2.1: {} @@ -16439,6 +24553,8 @@ snapshots: comment-parser@1.4.5: {} + commondir@1.0.1: {} + compare-func@2.0.0: dependencies: array-ify: 1.0.0 @@ -16446,6 +24562,16 @@ snapshots: compare-versions@6.1.1: {} + compatx@0.2.0: {} + + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + compressible@2.0.18: dependencies: mime-db: 1.54.0 @@ -16477,11 +24603,15 @@ snapshots: confbox@0.2.2: {} + confbox@0.2.4: {} + config-chain@1.1.13: dependencies: ini: 1.3.8 proto-list: 1.2.4 + connect-history-api-fallback@2.0.0: {} + consola@3.4.2: {} console-browserify@1.2.0: {} @@ -16532,10 +24662,16 @@ snapshots: convert-hrtime@5.0.0: {} + convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} convert-to-spaces@2.0.1: {} + cookie-es@1.2.2: {} + + cookie-es@2.0.0: {} + cookie-signature@1.0.6: {} cookie-signature@1.0.7: {} @@ -16548,6 +24684,29 @@ snapshots: cookie@0.7.2: {} + cookie@1.1.1: {} + + copy-anything@2.0.6: + dependencies: + is-what: 3.14.1 + + copy-paste@2.2.0: + dependencies: + iconv-lite: 0.4.24 + + copy-webpack-plugin@14.0.0(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + glob-parent: 6.0.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 7.0.4 + tinyglobby: 0.2.15 + webpack: 5.105.2(esbuild@0.27.3) + + core-js-compat@3.48.0: + dependencies: + browserslist: 4.28.1 + core-util-is@1.0.2: {} core-util-is@1.0.3: {} @@ -16578,6 +24737,13 @@ snapshots: optionalDependencies: typescript: 5.9.3 + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + create-ecdh@4.0.4: dependencies: bn.js: 4.12.2 @@ -16602,12 +24768,18 @@ snapshots: create-require@1.1.1: {} + croner@9.1.0: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + crypto-browserify@3.12.1: dependencies: browserify-cipher: 1.0.1 @@ -16629,6 +24801,23 @@ snapshots: dependencies: type-fest: 1.4.0 + css-declaration-sorter@7.3.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + css-loader@7.1.3(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) + postcss-modules-scope: 3.2.1(postcss@8.5.6) + postcss-modules-values: 4.0.0(postcss@8.5.6) + postcss-value-parser: 4.2.0 + semver: 7.7.4 + optionalDependencies: + webpack: 5.105.2(esbuild@0.27.3) + css-render@0.15.14: dependencies: '@emotion/hash': 0.8.0 @@ -16642,6 +24831,19 @@ snapshots: domutils: 3.2.2 nth-check: 2.1.1 + css-select@6.0.0: + dependencies: + boolbase: 1.0.0 + css-what: 7.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + css-tree@3.1.0: dependencies: mdn-data: 2.12.2 @@ -16649,10 +24851,60 @@ snapshots: css-what@6.2.2: {} + css-what@7.0.0: {} + css.escape@1.5.1: {} cssesc@3.0.0: {} + cssnano-preset-default@7.0.11(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + css-declaration-sorter: 7.3.1(postcss@8.5.6) + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-calc: 10.1.1(postcss@8.5.6) + postcss-colormin: 7.0.6(postcss@8.5.6) + postcss-convert-values: 7.0.9(postcss@8.5.6) + postcss-discard-comments: 7.0.6(postcss@8.5.6) + postcss-discard-duplicates: 7.0.2(postcss@8.5.6) + postcss-discard-empty: 7.0.1(postcss@8.5.6) + postcss-discard-overridden: 7.0.1(postcss@8.5.6) + postcss-merge-longhand: 7.0.5(postcss@8.5.6) + postcss-merge-rules: 7.0.8(postcss@8.5.6) + postcss-minify-font-values: 7.0.1(postcss@8.5.6) + postcss-minify-gradients: 7.0.1(postcss@8.5.6) + postcss-minify-params: 7.0.6(postcss@8.5.6) + postcss-minify-selectors: 7.0.6(postcss@8.5.6) + postcss-normalize-charset: 7.0.1(postcss@8.5.6) + postcss-normalize-display-values: 7.0.1(postcss@8.5.6) + postcss-normalize-positions: 7.0.1(postcss@8.5.6) + postcss-normalize-repeat-style: 7.0.1(postcss@8.5.6) + postcss-normalize-string: 7.0.1(postcss@8.5.6) + postcss-normalize-timing-functions: 7.0.1(postcss@8.5.6) + postcss-normalize-unicode: 7.0.6(postcss@8.5.6) + postcss-normalize-url: 7.0.1(postcss@8.5.6) + postcss-normalize-whitespace: 7.0.1(postcss@8.5.6) + postcss-ordered-values: 7.0.2(postcss@8.5.6) + postcss-reduce-initial: 7.0.6(postcss@8.5.6) + postcss-reduce-transforms: 7.0.1(postcss@8.5.6) + postcss-svgo: 7.1.1(postcss@8.5.6) + postcss-unique-selectors: 7.0.5(postcss@8.5.6) + + cssnano-utils@5.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + cssnano@7.1.3(postcss@8.5.6): + dependencies: + cssnano-preset-default: 7.0.11(postcss@8.5.6) + lilconfig: 3.1.3 + postcss: 8.5.6 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + cssstyle@5.3.7: dependencies: '@asamuzakjp/css-color': 4.1.1 @@ -16664,6 +24916,8 @@ snapshots: csstype@3.2.3: {} + damerau-levenshtein@1.0.8: {} + dargs@8.1.0: {} dashdash@1.14.1: @@ -16705,12 +24959,18 @@ snapshots: dayjs@1.11.13: {} + db0@0.3.4: {} + de-indent@1.0.2: {} debug@2.6.9: dependencies: ms: 2.0.0 + debug@3.2.7: + dependencies: + ms: 2.1.3 + debug@4.3.7: dependencies: ms: 2.1.3 @@ -16752,6 +25012,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge@4.3.1: {} + default-browser-id@5.0.1: {} default-browser@5.5.0: @@ -16777,6 +25039,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + defu@6.1.4: {} + degenerator@5.0.1: dependencies: ast-types: 0.13.4 @@ -16796,6 +25060,10 @@ snapshots: delayed-stream@1.0.0: {} + denque@2.1.0: {} + + depd@1.1.2: {} + depd@2.0.0: {} dependency-graph@0.11.0: {} @@ -16807,12 +25075,16 @@ snapshots: inherits: 2.0.4 minimalistic-assert: 1.0.1 + destr@2.0.5: {} + destroy@1.2.0: {} detect-libc@2.1.2: {} detect-node-es@1.1.0: {} + detect-node@2.1.0: {} + detect-port@1.5.1: dependencies: address: 1.2.2 @@ -16820,6 +25092,8 @@ snapshots: transitivePeerDependencies: - supports-color + devalue@5.6.3: {} + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -16929,12 +25203,18 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 + dot-prop@10.1.0: + dependencies: + type-fest: 5.4.4 + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 dotenv@16.6.1: {} + dotenv@17.3.1: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -16945,6 +25225,8 @@ snapshots: dependencies: readable-stream: 2.3.8 + duplexer@0.1.2: {} + duplexify@3.7.1: dependencies: end-of-stream: 1.4.5 @@ -16952,6 +25234,13 @@ snapshots: readable-stream: 2.3.8 stream-shift: 1.0.3 + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2(patch_hash=e4aadcbd3e7fffdf34e27d9a810232cda21beee31c3b1f1fda75b4877dfe5e61) + stream-shift: 1.0.3 + eastasianwidth@0.2.0: {} ecc-jsbn@0.1.2: @@ -16992,6 +25281,8 @@ snapshots: emojilib@2.4.0: {} + emojis-list@3.0.0: {} + encodeurl@1.0.2: {} encodeurl@2.0.0: {} @@ -17024,6 +25315,11 @@ snapshots: - supports-color - utf-8-validate + enhanced-resolve@5.20.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + entities@2.1.0: {} entities@4.5.0: {} @@ -17043,10 +25339,21 @@ snapshots: environment@1.1.0: {} + err-code@2.0.3: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + optional: true + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 + error-stack-parser-es@1.0.5: {} + + errx@0.1.0: {} + es-abstract@1.24.1: dependencies: array-buffer-byte-length: 1.0.2 @@ -17140,6 +25447,8 @@ snapshots: es-module-lexer@1.7.0: {} + es-module-lexer@2.0.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -17177,6 +25486,8 @@ snapshots: esast-util-from-estree: 2.0.0 vfile-message: 4.0.3 + esbuild-wasm@0.27.3: {} + esbuild@0.25.12: optionalDependencies: '@esbuild/aix-ppc64': 0.25.12 @@ -17235,6 +25546,35 @@ snapshots: '@esbuild/win32-ia32': 0.27.2 '@esbuild/win32-x64': 0.27.2 + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -17255,6 +25595,26 @@ snapshots: optionalDependencies: source-map: 0.6.1 + eslint-config-next@16.1.6(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 16.1.6 + eslint: 9.39.2(jiti@2.6.1) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@2.6.1)) + globals: 16.4.0 + typescript-eslint: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + eslint-config-prettier@9.1.2(eslint@9.39.2(jiti@2.6.1)): dependencies: eslint: 9.39.2(jiti@2.6.1) @@ -17266,7 +25626,31 @@ snapshots: optionalDependencies: unrs-resolver: 1.11.1 - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3(supports-color@5.5.0) + eslint: 9.39.2(jiti@2.6.1) + get-tsconfig: 4.13.1 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 4.4.3(supports-color@5.5.0) eslint: 9.39.2(jiti@2.6.1) @@ -17277,26 +25661,110 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)))(eslint@9.39.2(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.2(jiti@2.6.1) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) + transitivePeerDependencies: + - supports-color + optional: true + + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)): + dependencies: + '@typescript-eslint/types': 8.54.0 + comment-parser: 1.4.5 + debug: 4.4.3(supports-color@5.5.0) + eslint: 9.39.2(jiti@2.6.1) + eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + is-glob: 4.0.3 + minimatch: 10.1.2 + semver: 7.7.3 + stable-hash-x: 0.2.0 + unrs-resolver: 1.11.1 + optionalDependencies: + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.2(jiti@2.6.1) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack - supports-color - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)): dependencies: - '@typescript-eslint/types': 8.54.0 - comment-parser: 1.4.5 - debug: 4.4.3(supports-color@5.5.0) + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 eslint: 9.39.2(jiti@2.6.1) - eslint-import-context: 0.1.9(unrs-resolver@1.11.1) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.2(jiti@2.6.1)) + hasown: 2.0.2 + is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 10.1.2 - semver: 7.7.3 - stable-hash-x: 0.2.0 - unrs-resolver: 1.11.1 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack - supports-color + optional: true eslint-plugin-jsdoc@54.7.0(eslint@9.39.2(jiti@2.6.1)): dependencies: @@ -17314,6 +25782,25 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.2(jiti@2.6.1)): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.1 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.39.2(jiti@2.6.1) + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + eslint-plugin-react-hooks@7.0.1(eslint@9.39.2(jiti@2.6.1)): dependencies: '@babel/core': 7.29.0 @@ -17347,6 +25834,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 @@ -17413,6 +25905,8 @@ snapshots: dependencies: estraverse: 5.3.0 + estraverse@4.3.0: {} + estraverse@5.3.0: {} estree-util-attach-comments@3.0.0: @@ -17456,6 +25950,8 @@ snapshots: event-target-shim@5.0.1: {} + eventemitter3@4.0.7: {} + eventemitter3@5.0.4: {} events-universal@1.0.1: @@ -17522,6 +26018,8 @@ snapshots: expect-type@1.3.0: {} + exponential-backoff@3.1.3: {} + express-rate-limit@5.5.1: {} express-rate-limit@8.2.1(express@5.2.1): @@ -17652,10 +26150,20 @@ snapshots: fast-content-type-parse@3.0.0: {} + fast-decode-uri-component@1.0.1: {} + fast-deep-equal@3.1.3: {} fast-fifo@1.3.2: {} + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -17666,16 +26174,53 @@ snapshots: fast-json-stable-stringify@2.1.0: {} + fast-json-stringify@6.3.0: + dependencies: + '@fastify/merge-json-schemas': 0.2.1 + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-uri: 3.1.0 + json-schema-ref-resolver: 3.0.0 + rfdc: 1.4.1 + fast-levenshtein@2.0.6: {} fast-memoize@2.5.2: {} + fast-npm-meta@1.4.2: {} + + fast-querystring@1.1.2: + dependencies: + fast-decode-uri-component: 1.0.1 + + fast-sha256@1.3.0: {} + fast-uri@3.1.0: {} fast-xml-parser@5.3.4: dependencies: strnum: 2.1.2 + fastify-plugin@5.1.0: {} + + fastify@5.8.2: + dependencies: + '@fastify/ajv-compiler': 4.0.5 + '@fastify/error': 4.2.0 + '@fastify/fast-json-stringify-compiler': 5.0.3 + '@fastify/proxy-addr': 5.1.0 + abstract-logging: 2.0.1 + avvio: 9.2.0 + fast-json-stringify: 6.3.0 + find-my-way: 9.5.0 + light-my-request: 6.6.0 + pino: 9.14.0 + process-warning: 5.0.0 + rfdc: 1.4.1 + secure-json-parse: 4.1.0 + semver: 7.7.3 + toad-cache: 3.7.0 + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -17690,6 +26235,10 @@ snapshots: sharp: 0.33.5 xml2js: 0.6.2 + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + fd-slicer@1.1.0: dependencies: pend: 1.2.0 @@ -17715,6 +26264,8 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-uri-to-path@1.0.0: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -17754,6 +26305,12 @@ snapshots: transitivePeerDependencies: - supports-color + find-my-way@9.5.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 5.0.0 + find-up-simple@1.0.1: {} find-up@2.1.0: @@ -17792,9 +26349,13 @@ snapshots: flatted: 3.3.3 keyv: 4.5.4 + flat@5.0.2: {} + flatted@3.3.3: {} - follow-redirects@1.15.11: {} + follow-redirects@1.15.11(debug@4.4.3): + optionalDependencies: + debug: 4.4.3(supports-color@5.5.0) for-each@0.3.5: dependencies: @@ -17827,6 +26388,8 @@ snapshots: forwarded@0.2.0: {} + fraction.js@5.3.4: {} + fresh@0.5.2: {} fresh@2.0.0: {} @@ -17882,6 +26445,10 @@ snapshots: dependencies: minipass: 3.3.6 + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + fs.realpath@1.0.0: {} fsevents@2.3.2: @@ -17905,6 +26472,10 @@ snapshots: functions-have-names@1.2.3: {} + fuse.js@7.1.0: {} + + fzf@0.5.2: {} + gcd@0.0.1: {} generator-function@2.0.1: {} @@ -17915,6 +26486,8 @@ snapshots: get-east-asian-width@1.4.0: {} + get-east-asian-width@1.5.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -17930,6 +26503,8 @@ snapshots: get-nonce@1.0.1: {} + get-port-please@3.2.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -17972,6 +26547,17 @@ snapshots: dependencies: assert-plus: 1.0.0 + giget@2.0.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.7 + nypm: 0.6.5 + pathe: 2.0.3 + + giget@3.1.2: {} + git-log-parser@1.2.1: dependencies: argv-formatter: 1.0.0 @@ -18010,6 +26596,12 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regex.js@1.2.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + glob-to-regexp@0.4.1: {} + glob@10.5.0: dependencies: foreground-child: 3.3.1 @@ -18019,6 +26611,12 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@13.0.6: + dependencies: + minimatch: 10.2.4 + minipass: 7.1.3 + path-scurry: 2.0.2 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -18044,6 +26642,8 @@ snapshots: globals@14.0.0: {} + globals@16.4.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -18069,6 +26669,15 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + globby@16.1.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + fast-glob: 3.3.3 + ignore: 7.0.5 + is-path-inside: 4.0.0 + slash: 5.1.0 + unicorn-magic: 0.4.0 + gopd@1.2.0: {} got-cjs@12.5.4: @@ -18127,6 +26736,24 @@ snapshots: pumpify: 1.5.1 through2: 2.0.5 + gzip-size@7.0.0: + dependencies: + duplexer: 0.1.2 + + h3@1.15.6: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.3 + uncrypto: 0.1.3 + + handle-thing@2.0.1: {} + handlebars@4.7.8: dependencies: minimist: 1.2.8 @@ -18474,6 +27101,10 @@ snapshots: hook-std@4.0.0: {} + hookable@5.5.3: {} + + hookable@6.0.1: {} + hosted-git-info@2.8.9: {} hosted-git-info@4.1.0: @@ -18488,6 +27119,17 @@ snapshots: dependencies: lru-cache: 10.4.3 + hosted-git-info@9.0.2: + dependencies: + lru-cache: 11.2.5 + + hpack.js@2.1.6: + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + html-encoding-sniffer@4.0.0: dependencies: whatwg-encoding: 3.1.1 @@ -18507,6 +27149,16 @@ snapshots: http-cache-semantics@4.2.0: {} + http-deceiver@1.2.7: {} + + http-errors@1.8.1: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -18523,6 +27175,8 @@ snapshots: statuses: 2.0.2 toidentifier: 1.0.1 + http-parser-js@0.5.10: {} + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -18530,6 +27184,39 @@ snapshots: transitivePeerDependencies: - supports-color + http-proxy-middleware@2.0.9(@types/express@4.17.25): + dependencies: + '@types/http-proxy': 1.17.17 + http-proxy: 1.18.1(debug@4.4.3) + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.25 + transitivePeerDependencies: + - debug + + http-proxy-middleware@3.0.5: + dependencies: + '@types/http-proxy': 1.17.17 + debug: 4.4.3(supports-color@5.5.0) + http-proxy: 1.18.1(debug@4.4.3) + is-glob: 4.0.3 + is-plain-object: 5.0.0 + micromatch: 4.0.8 + transitivePeerDependencies: + - supports-color + + http-proxy@1.18.1(debug@4.4.3): + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.11(debug@4.4.3) + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + http-shutdown@1.2.2: {} + http-signature@1.4.0: dependencies: assert-plus: 1.0.0 @@ -18559,12 +27246,16 @@ snapshots: transitivePeerDependencies: - supports-color + httpxy@0.1.7: {} + human-signals@2.1.0: {} human-signals@5.0.0: {} human-signals@8.0.1: {} + hyperdyperid@1.2.0: {} + ico-endec@0.1.6: {} iconv-lite@0.4.24: @@ -18579,18 +27270,33 @@ snapshots: dependencies: safer-buffer: 2.1.2 + icss-utils@5.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + ieee754@1.2.1: {} ignore-by-default@1.0.1: {} + ignore-walk@8.0.0: + dependencies: + minimatch: 10.1.2 + ignore@5.3.2: {} ignore@7.0.5: {} + image-meta@0.2.2: {} + + image-size@0.5.5: + optional: true + immediate@3.0.6: {} immer@9.0.21: {} + immutable@5.1.5: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -18607,6 +27313,14 @@ snapshots: import-meta-resolve@4.2.0: {} + impound@1.1.5: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + es-module-lexer: 2.0.0 + pathe: 2.0.3 + unplugin: 3.0.0 + unplugin-utils: 0.3.1 + imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -18628,6 +27342,8 @@ snapshots: ini@4.1.1: {} + ini@6.0.0: {} + ink-spinner@5.0.0(ink@6.3.0(@types/react@19.2.11)(react@19.2.3))(react@19.2.3): dependencies: cli-spinners: 2.9.2 @@ -18690,6 +27406,20 @@ snapshots: from2: 2.3.0 p-is-promise: 3.0.0 + ioredis@5.10.0: + dependencies: + '@ioredis/commands': 1.5.1 + cluster-key-slot: 1.1.2 + debug: 4.4.3(supports-color@5.5.0) + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + ip-address@10.0.1: {} ip-address@10.1.0: {} @@ -18698,6 +27428,10 @@ snapshots: ipaddr.js@1.9.1: {} + ipaddr.js@2.3.0: {} + + iron-webcrypto@1.2.1: {} + is-absolute@1.0.0: dependencies: is-relative: 1.0.0 @@ -18809,16 +27543,27 @@ snapshots: is-in-ci@2.0.0: {} + is-in-ssh@1.0.0: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + + is-interactive@2.0.0: {} + is-ip@3.1.0: dependencies: ip-regex: 4.3.0 is-map@2.0.3: {} + is-module@1.0.0: {} + is-nan@1.3.2: dependencies: call-bind: 1.0.8 @@ -18826,6 +27571,8 @@ snapshots: is-negative-zero@2.0.3: {} + is-network-error@1.3.1: {} + is-number-object@1.1.1: dependencies: call-bound: 1.0.4 @@ -18846,10 +27593,20 @@ snapshots: is-path-inside@3.0.3: {} + is-path-inside@4.0.0: {} + + is-plain-obj@3.0.0: {} + is-plain-obj@4.1.0: {} + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + is-plain-object@3.0.1: {} + is-plain-object@5.0.0: {} + is-port-reachable@4.0.0: {} is-potential-custom-element-name@1.0.1: {} @@ -18858,6 +27615,10 @@ snapshots: is-promise@4.0.0: {} + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.8 + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -18923,6 +27684,8 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 + is-what@3.14.1: {} + is-windows@1.0.2: {} is-wsl@2.2.0: @@ -18933,12 +27696,22 @@ snapshots: dependencies: is-inside-container: 1.0.0 + is64bit@2.0.0: + dependencies: + system-architecture: 0.1.0 + isarray@1.0.0: {} isarray@2.0.5: {} isexe@2.0.0: {} + isexe@3.1.5: {} + + isexe@4.0.0: {} + + isobject@3.0.1: {} + isomorphic-timers-promises@1.0.1: {} isomorphic.js@0.2.5: {} @@ -18955,6 +27728,16 @@ snapshots: istanbul-lib-coverage@3.2.2: {} + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 @@ -18991,6 +27774,12 @@ snapshots: java-properties@1.0.2: {} + jest-worker@27.5.1: + dependencies: + '@types/node': 22.19.8 + merge-stream: 2.0.0 + supports-color: 8.1.1 + jiti@1.21.7: {} jiti@2.6.1: {} @@ -19001,6 +27790,8 @@ snapshots: joycon@3.1.1: {} + js-base64@3.7.8: {} + js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -19073,6 +27864,12 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-parse-even-better-errors@5.0.0: {} + + json-schema-ref-resolver@3.0.0: + dependencies: + dequal: 2.0.3 + json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} @@ -19085,6 +27882,10 @@ snapshots: json-stringify-safe@5.0.1: {} + json5@1.0.2: + dependencies: + minimist: 1.2.8 + json5@2.2.3: {} jsonc-parser@2.2.1: {} @@ -19156,6 +27957,10 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 + karma-source-map-support@1.4.0: + dependencies: + source-map-support: 0.5.21 + katex@0.16.28: dependencies: commander: 8.3.0 @@ -19170,8 +27975,14 @@ snapshots: dependencies: json-buffer: 3.0.1 + kind-of@6.0.3: {} + kleur@4.1.5: {} + klona@2.0.6: {} + + knitwork@1.3.0: {} + kolorist@1.8.0: {} konan@2.1.1: @@ -19183,6 +27994,27 @@ snapshots: konva@10.2.0: {} + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + laravel-vite-plugin@2.1.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + picocolors: 1.1.1 + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-plugin-full-reload: 1.2.0 + + launch-editor@2.13.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + lcm@0.0.3: dependencies: gcd: 0.0.1 @@ -19230,6 +28062,26 @@ snapshots: lefthook-windows-arm64: 1.13.6 lefthook-windows-x64: 1.13.6 + less-loader@12.3.1(less@4.4.2)(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + less: 4.4.2 + optionalDependencies: + webpack: 5.105.2(esbuild@0.27.3) + + less@4.4.2: + dependencies: + copy-anything: 2.0.6 + parse-node-version: 1.0.1 + tslib: 2.8.1 + optionalDependencies: + errno: 0.1.8 + graceful-fs: 4.2.11 + image-size: 0.5.5 + make-dir: 2.1.0 + mime: 1.6.0 + needle: 3.3.1 + source-map: 0.6.1 + leven@3.1.0: {} leven@4.1.0: {} @@ -19243,10 +28095,22 @@ snapshots: dependencies: isomorphic.js: 0.2.5 + license-webpack-plugin@4.0.2(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + webpack-sources: 3.3.4 + optionalDependencies: + webpack: 5.105.2(esbuild@0.27.3) + lie@3.3.0: dependencies: immediate: 3.0.6 + light-my-request@6.6.0: + dependencies: + cookie: 1.1.1 + process-warning: 4.0.1 + set-cookie-parser: 2.7.2 + lightningcss-android-arm64@1.31.1: optional: true @@ -19302,9 +28166,57 @@ snapshots: lines-and-columns@1.2.4: {} - linkify-it@3.0.3: + linkify-it@3.0.3: + dependencies: + uc.micro: 1.0.6 + + listhen@1.9.0: + dependencies: + '@parcel/watcher': 2.5.6 + '@parcel/watcher-wasm': 2.5.6 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.4.2 + crossws: 0.3.5 + defu: 6.1.4 + get-port-please: 3.2.0 + h3: 1.15.6 + http-shutdown: 1.2.2 + jiti: 2.6.1 + mlly: 1.8.0 + node-forge: 1.3.3 + pathe: 1.1.2 + std-env: 3.10.0 + ufo: 1.6.3 + untun: 0.1.3 + uqr: 0.1.2 + + listr2@9.0.5: + dependencies: + cli-truncate: 5.2.0 + colorette: 2.0.20 + eventemitter3: 5.0.4 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.2 + + lmdb@3.5.1: dependencies: - uc.micro: 1.0.6 + '@harperfast/extended-iterable': 1.0.3 + msgpackr: 1.11.8 + node-addon-api: 6.1.0 + node-gyp-build-optional-packages: 5.2.2 + ordered-binary: 1.6.1 + weak-lru-cache: 1.2.2 + optionalDependencies: + '@lmdb/lmdb-darwin-arm64': 3.5.1 + '@lmdb/lmdb-darwin-x64': 3.5.1 + '@lmdb/lmdb-linux-arm': 3.5.1 + '@lmdb/lmdb-linux-arm64': 3.5.1 + '@lmdb/lmdb-linux-x64': 3.5.1 + '@lmdb/lmdb-win32-arm64': 3.5.1 + '@lmdb/lmdb-win32-x64': 3.5.1 + optional: true load-json-file@4.0.0: dependencies: @@ -19315,6 +28227,16 @@ snapshots: load-tsconfig@0.2.5: {} + loader-runner@4.3.1: {} + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + loader-utils@3.3.1: {} + local-pkg@1.1.2: dependencies: mlly: 1.8.0 @@ -19344,10 +28266,16 @@ snapshots: lodash.capitalize@4.2.1: {} + lodash.debounce@4.0.8: {} + + lodash.defaults@4.2.0: {} + lodash.escaperegexp@4.1.2: {} lodash.includes@4.3.0: {} + lodash.isarguments@3.1.0: {} + lodash.isboolean@3.0.3: {} lodash.isinteger@4.0.4: {} @@ -19360,6 +28288,8 @@ snapshots: lodash.kebabcase@4.1.1: {} + lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} lodash.mergewith@4.6.2: {} @@ -19382,6 +28312,19 @@ snapshots: lodash@4.17.23: {} + log-symbols@7.0.1: + dependencies: + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.2 + + log-update@6.1.0: + dependencies: + ansi-escapes: 7.3.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.1.2 + wrap-ansi: 9.0.2 + longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -19418,6 +28361,20 @@ snapshots: lz-string@1.5.0: {} + magic-regexp@0.10.0: + dependencies: + estree-walker: 3.0.3 + magic-string: 0.30.21 + mlly: 1.8.0 + regexp-tree: 0.1.27 + type-level-regexp: 0.1.17 + ufo: 1.6.3 + unplugin: 2.3.11 + + magic-string-ast@1.0.3: + dependencies: + magic-string: 0.30.21 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -19428,16 +28385,44 @@ snapshots: '@babel/types': 7.29.0 source-map-js: 1.2.1 + magicast@0.5.2: + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + source-map-js: 1.2.1 + make-asynchronous@1.0.1: dependencies: p-event: 6.0.1 type-fest: 4.41.0 web-worker: 1.2.0 + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + optional: true + make-dir@4.0.0: dependencies: semver: 7.7.3 + make-fetch-happen@15.0.4: + dependencies: + '@gar/promise-retry': 1.0.2 + '@npmcli/agent': 4.0.0 + cacache: 20.0.3 + http-cache-semantics: 4.2.0 + minipass: 7.1.2 + minipass-fetch: 5.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 1.0.0 + proc-log: 6.1.0 + ssri: 13.0.1 + transitivePeerDependencies: + - supports-color + map-cache@0.2.2: {} markdown-extensions@2.0.0: {} @@ -19809,6 +28794,8 @@ snapshots: unist-util-is: 5.2.1 unist-util-visit: 4.1.2 + mdn-data@2.0.28: {} + mdn-data@2.12.2: {} mdurl@1.0.1: {} @@ -19817,6 +28804,23 @@ snapshots: media-typer@1.1.0: {} + memfs@4.56.11(tslib@2.8.1): + dependencies: + '@jsonjoy.com/fs-core': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.56.11(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + meow@12.1.1: {} meow@13.2.0: {} @@ -20344,6 +29348,8 @@ snapshots: mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -20352,6 +29358,12 @@ snapshots: min-indent@1.0.1: {} + mini-css-extract-plugin@2.10.0(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + schema-utils: 4.3.3 + tapable: 2.3.0 + webpack: 5.105.2(esbuild@0.27.3) + minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} @@ -20364,6 +29376,10 @@ snapshots: dependencies: '@isaacs/brace-expansion': 5.0.1 + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.4 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -20386,6 +29402,30 @@ snapshots: minimist@1.2.8: {} + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.2 + + minipass-fetch@5.0.2: + dependencies: + minipass: 7.1.2 + minipass-sized: 2.0.0 + minizlib: 3.1.0 + optionalDependencies: + iconv-lite: 0.7.2 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@2.0.0: + dependencies: + minipass: 7.1.2 + minipass@3.3.6: dependencies: yallist: 4.0.0 @@ -20394,11 +29434,17 @@ snapshots: minipass@7.1.2: {} + minipass@7.1.3: {} + minizlib@2.1.2: dependencies: minipass: 3.3.6 yallist: 4.0.0 + minizlib@3.1.0: + dependencies: + minipass: 7.1.2 + mintlify@4.2.331(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3): dependencies: '@mintlify/cli': 4.0.935(@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(react@19.2.3))(@types/node@22.19.8)(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.3))(typescript@5.9.3) @@ -20432,6 +29478,8 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.3 + mocked-exports@0.1.1: {} + mri@1.2.0: {} mrmime@2.0.1: {} @@ -20440,8 +29488,30 @@ snapshots: ms@2.1.3: {} + msgpackr-extract@3.0.3: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + optional: true + + msgpackr@1.11.8: + optionalDependencies: + msgpackr-extract: 3.0.3 + optional: true + muggle-string@0.4.1: {} + multicast-dns@7.2.5: + dependencies: + dns-packet: 5.6.1 + thunky: 1.1.0 + mute-stream@0.0.8: {} mute-stream@2.0.0: {} @@ -20452,6 +29522,29 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + naive-ui@2.43.2(vue@3.5.25(typescript@5.5.4)): + dependencies: + '@css-render/plugin-bem': 0.15.14(css-render@0.15.14) + '@css-render/vue3-ssr': 0.15.14(vue@3.5.25(typescript@5.5.4)) + '@types/katex': 0.16.8 + '@types/lodash': 4.17.23 + '@types/lodash-es': 4.17.12 + async-validator: 4.2.5 + css-render: 0.15.14 + csstype: 3.2.3 + date-fns: 4.1.0 + date-fns-tz: 3.2.0(date-fns@4.1.0) + evtd: 0.2.4 + highlight.js: 11.11.1 + lodash: 4.17.23 + lodash-es: 4.17.23 + seemly: 0.3.10 + treemate: 0.3.11 + vdirs: 0.1.8(vue@3.5.25(typescript@5.5.4)) + vooks: 0.2.12(vue@3.5.25(typescript@5.5.4)) + vue: 3.5.25(typescript@5.5.4) + vueuc: 0.4.65(vue@3.5.25(typescript@5.5.4)) + naive-ui@2.43.2(vue@3.5.25(typescript@5.9.3)): dependencies: '@css-render/plugin-bem': 0.15.14(css-render@0.15.14) @@ -20477,12 +29570,20 @@ snapshots: nanoid@3.3.11: {} + nanotar@0.2.1: {} + napi-build-utils@2.0.0: {} napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} + needle@3.3.1: + dependencies: + iconv-lite: 0.6.3 + sax: 1.4.4 + optional: true + negotiator@0.6.3: {} negotiator@0.6.4: {} @@ -20513,6 +29614,32 @@ snapshots: - supports-color - unified + next@16.1.6(@playwright/test@1.58.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.3): + dependencies: + '@next/env': 16.1.6 + '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001767 + postcss: 8.4.31 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + styled-jsx: 5.1.6(react@19.2.4) + optionalDependencies: + '@next/swc-darwin-arm64': 16.1.6 + '@next/swc-darwin-x64': 16.1.6 + '@next/swc-linux-arm64-gnu': 16.1.6 + '@next/swc-linux-arm64-musl': 16.1.6 + '@next/swc-linux-x64-gnu': 16.1.6 + '@next/swc-linux-x64-musl': 16.1.6 + '@next/swc-win32-arm64-msvc': 16.1.6 + '@next/swc-win32-x64-msvc': 16.1.6 + '@playwright/test': 1.58.1 + sass: 1.97.3 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nimma@0.2.3: dependencies: '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) @@ -20523,6 +29650,110 @@ snapshots: jsonpath-plus: 10.3.0 lodash.topath: 4.5.2 + nitropack@2.13.1(@azure/identity@4.13.0)(rolldown@1.0.0-rc.4)(xml2js@0.6.2): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.2 + '@rollup/plugin-alias': 6.0.0(rollup@4.57.1) + '@rollup/plugin-commonjs': 29.0.2(rollup@4.57.1) + '@rollup/plugin-inject': 5.0.5(rollup@4.57.1) + '@rollup/plugin-json': 6.1.0(rollup@4.57.1) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.57.1) + '@rollup/plugin-replace': 6.0.3(rollup@4.57.1) + '@rollup/plugin-terser': 0.4.4(rollup@4.57.1) + '@vercel/nft': 1.3.2(rollup@4.57.1) + archiver: 7.0.1 + c12: 3.3.3(magicast@0.5.2) + chokidar: 5.0.0 + citty: 0.1.6 + compatx: 0.2.0 + confbox: 0.2.2 + consola: 3.4.2 + cookie-es: 2.0.0 + croner: 9.1.0 + crossws: 0.3.5 + db0: 0.3.4 + defu: 6.1.4 + destr: 2.0.5 + dot-prop: 10.1.0 + esbuild: 0.27.2 + escape-string-regexp: 5.0.0 + etag: 1.8.1 + exsolve: 1.0.8 + globby: 16.1.1 + gzip-size: 7.0.0 + h3: 1.15.6 + hookable: 5.5.3 + httpxy: 0.1.7 + ioredis: 5.10.0 + jiti: 2.6.1 + klona: 2.0.6 + knitwork: 1.3.0 + listhen: 1.9.0 + magic-string: 0.30.21 + magicast: 0.5.2 + mime: 4.1.0 + mlly: 1.8.0 + node-fetch-native: 1.6.7 + node-mock-http: 1.0.4 + ofetch: 1.5.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + pretty-bytes: 7.1.0 + radix3: 1.1.2 + rollup: 4.57.1 + rollup-plugin-visualizer: 6.0.11(rolldown@1.0.0-rc.4)(rollup@4.57.1) + scule: 1.3.0 + semver: 7.7.4 + serve-placeholder: 2.0.2 + serve-static: 2.2.1 + source-map: 0.7.6 + std-env: 3.10.0 + ufo: 1.6.3 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.5.0 + unenv: 2.0.0-rc.24 + unimport: 5.7.0 + unplugin-utils: 0.3.1 + unstorage: 1.17.4(@azure/identity@4.13.0)(db0@0.3.4)(ioredis@5.10.0) + untyped: 2.0.0 + unwasm: 0.5.3 + youch: 4.1.0 + youch-core: 0.3.3 + optionalDependencies: + xml2js: 0.6.2 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bare-abort-controller + - better-sqlite3 + - drizzle-orm + - encoding + - idb-keyval + - mysql2 + - react-native-b4a + - rolldown + - sqlite3 + - supports-color + - uploadthing + nlcst-to-string@4.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -20534,6 +29765,9 @@ snapshots: node-addon-api@4.3.0: optional: true + node-addon-api@6.1.0: + optional: true + node-addon-api@7.1.1: {} node-domexception@1.0.0: {} @@ -20545,6 +29779,8 @@ snapshots: emojilib: 2.4.0 skin-tone: 2.0.0 + node-fetch-native@1.6.7: {} + node-fetch@2.6.7: dependencies: whatwg-url: 5.0.0 @@ -20559,6 +29795,32 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-forge@1.3.3: {} + + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.1.2 + optional: true + + node-gyp-build@4.8.4: {} + + node-gyp@12.2.0: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + graceful-fs: 4.2.11 + make-fetch-happen: 15.0.4 + nopt: 9.0.0 + proc-log: 6.1.0 + semver: 7.7.4 + tar: 7.5.11 + tinyglobby: 0.2.15 + which: 6.0.1 + transitivePeerDependencies: + - supports-color + + node-mock-http@1.0.4: {} + node-readable-to-web-readable-stream@0.4.2: optional: true @@ -20611,6 +29873,14 @@ snapshots: dependencies: abbrev: 2.0.0 + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + + nopt@9.0.0: + dependencies: + abbrev: 4.0.0 + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -20637,6 +29907,48 @@ snapshots: normalize-url@8.1.1: {} + npm-bundled@5.0.0: + dependencies: + npm-normalize-package-bin: 5.0.0 + + npm-install-checks@8.0.0: + dependencies: + semver: 7.7.4 + + npm-normalize-package-bin@5.0.0: {} + + npm-package-arg@13.0.2: + dependencies: + hosted-git-info: 9.0.2 + proc-log: 6.1.0 + semver: 7.7.4 + validate-npm-package-name: 7.0.2 + + npm-packlist@10.0.4: + dependencies: + ignore-walk: 8.0.0 + proc-log: 6.1.0 + + npm-pick-manifest@11.0.3: + dependencies: + npm-install-checks: 8.0.0 + npm-normalize-package-bin: 5.0.0 + npm-package-arg: 13.0.2 + semver: 7.7.4 + + npm-registry-fetch@19.1.1: + dependencies: + '@npmcli/redact': 4.0.0 + jsonparse: 1.3.1 + make-fetch-happen: 15.0.4 + minipass: 7.1.2 + minipass-fetch: 5.0.2 + minizlib: 3.1.0 + npm-package-arg: 13.0.2 + proc-log: 6.1.0 + transitivePeerDependencies: + - supports-color + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -20658,6 +29970,134 @@ snapshots: dependencies: boolbase: 1.0.0 + nuxt@4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2): + dependencies: + '@dxup/nuxt': 0.3.2(magicast@0.5.2) + '@nuxt/cli': 3.33.1(@nuxt/schema@4.3.1)(cac@6.7.14)(magicast@0.5.2) + '@nuxt/devtools': 3.2.3(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + '@nuxt/kit': 4.3.1(magicast@0.5.2) + '@nuxt/nitro-server': 4.3.1(@azure/identity@4.13.0)(db0@0.3.4)(ioredis@5.10.0)(magicast@0.5.2)(nuxt@4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2))(rolldown@1.0.0-rc.4)(typescript@5.9.3)(xml2js@0.6.2) + '@nuxt/schema': 4.3.1 + '@nuxt/telemetry': 2.7.0(@nuxt/kit@4.3.1(magicast@0.5.2)) + '@nuxt/vite-builder': 4.3.1(@types/node@22.19.8)(eslint@9.39.2(jiti@2.6.1))(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(nuxt@4.3.1(@azure/identity@4.13.0)(@parcel/watcher@2.5.6)(@types/node@22.19.8)(@vue/compiler-sfc@3.5.25)(cac@6.7.14)(db0@0.3.4)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.10.0)(less@4.4.2)(magicast@0.5.2)(meow@13.2.0)(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(xml2js@0.6.2)(yaml@2.8.2))(optionator@0.9.4)(rolldown@1.0.0-rc.4)(rollup@4.57.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))(yaml@2.8.2) + '@unhead/vue': 2.1.10(vue@3.5.25(typescript@5.9.3)) + '@vue/shared': 3.5.25 + c12: 3.3.3(magicast@0.5.2) + chokidar: 5.0.0 + compatx: 0.2.0 + consola: 3.4.2 + cookie-es: 2.0.0 + defu: 6.1.4 + destr: 2.0.5 + devalue: 5.6.3 + errx: 0.1.0 + escape-string-regexp: 5.0.0 + exsolve: 1.0.8 + h3: 1.15.6 + hookable: 5.5.3 + ignore: 7.0.5 + impound: 1.1.5 + jiti: 2.6.1 + klona: 2.0.6 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.0 + nanotar: 0.2.1 + nypm: 0.6.5 + ofetch: 1.5.1 + ohash: 2.0.11 + on-change: 6.0.2 + oxc-minify: 0.112.0 + oxc-parser: 0.112.0 + oxc-transform: 0.112.0 + oxc-walker: 0.7.0(oxc-parser@0.112.0) + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + rou3: 0.7.12 + scule: 1.3.0 + semver: 7.7.4 + std-env: 3.10.0 + tinyglobby: 0.2.15 + ufo: 1.6.3 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.5.0 + unimport: 5.7.0 + unplugin: 3.0.0 + unplugin-vue-router: 0.19.2(@vue/compiler-sfc@3.5.25)(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) + untyped: 2.0.0 + vue: 3.5.25(typescript@5.9.3) + vue-router: 4.6.4(vue@3.5.25(typescript@5.9.3)) + optionalDependencies: + '@parcel/watcher': 2.5.6 + '@types/node': 22.19.8 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@biomejs/biome' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools' + - '@vue/compiler-sfc' + - aws4fetch + - bare-abort-controller + - better-sqlite3 + - bufferutil + - cac + - commander + - db0 + - drizzle-orm + - encoding + - eslint + - idb-keyval + - ioredis + - less + - magicast + - meow + - mysql2 + - optionator + - oxlint + - react-native-b4a + - rolldown + - rollup + - sass + - sass-embedded + - sqlite3 + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - utf-8-validate + - vite + - vls + - vti + - vue-tsc + - xml2js + - yaml + + nypm@0.6.5: + dependencies: + citty: 0.2.1 + pathe: 2.0.3 + tinyexec: 1.0.2 + object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -20694,6 +30134,12 @@ snapshots: es-abstract: 1.24.1 es-object-atoms: 1.1.1 + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + object.values@1.2.1: dependencies: call-bind: 1.0.8 @@ -20701,6 +30147,22 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + obuf@1.1.2: {} + + obug@2.1.1: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.3 + + ofetch@2.0.0-alpha.3: {} + + ohash@2.0.11: {} + + on-change@6.0.2: {} + on-exit-leak-free@2.1.2: {} on-finished@2.4.1: @@ -20721,6 +30183,10 @@ snapshots: dependencies: mimic-fn: 4.0.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + oniguruma-parser@0.12.1: {} oniguruma-to-es@4.3.4: @@ -20736,6 +30202,15 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 + open@11.0.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 @@ -20753,6 +30228,20 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + ora@9.3.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 3.4.0 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 7.0.1 + stdin-discarder: 0.3.1 + string-width: 8.2.0 + + ordered-binary@1.6.1: + optional: true + orderedmap@2.1.1: {} os-browserify@0.3.0: {} @@ -20763,6 +30252,82 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + oxc-minify@0.112.0: + optionalDependencies: + '@oxc-minify/binding-android-arm-eabi': 0.112.0 + '@oxc-minify/binding-android-arm64': 0.112.0 + '@oxc-minify/binding-darwin-arm64': 0.112.0 + '@oxc-minify/binding-darwin-x64': 0.112.0 + '@oxc-minify/binding-freebsd-x64': 0.112.0 + '@oxc-minify/binding-linux-arm-gnueabihf': 0.112.0 + '@oxc-minify/binding-linux-arm-musleabihf': 0.112.0 + '@oxc-minify/binding-linux-arm64-gnu': 0.112.0 + '@oxc-minify/binding-linux-arm64-musl': 0.112.0 + '@oxc-minify/binding-linux-ppc64-gnu': 0.112.0 + '@oxc-minify/binding-linux-riscv64-gnu': 0.112.0 + '@oxc-minify/binding-linux-riscv64-musl': 0.112.0 + '@oxc-minify/binding-linux-s390x-gnu': 0.112.0 + '@oxc-minify/binding-linux-x64-gnu': 0.112.0 + '@oxc-minify/binding-linux-x64-musl': 0.112.0 + '@oxc-minify/binding-openharmony-arm64': 0.112.0 + '@oxc-minify/binding-wasm32-wasi': 0.112.0 + '@oxc-minify/binding-win32-arm64-msvc': 0.112.0 + '@oxc-minify/binding-win32-ia32-msvc': 0.112.0 + '@oxc-minify/binding-win32-x64-msvc': 0.112.0 + + oxc-parser@0.112.0: + dependencies: + '@oxc-project/types': 0.112.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.112.0 + '@oxc-parser/binding-android-arm64': 0.112.0 + '@oxc-parser/binding-darwin-arm64': 0.112.0 + '@oxc-parser/binding-darwin-x64': 0.112.0 + '@oxc-parser/binding-freebsd-x64': 0.112.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.112.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.112.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.112.0 + '@oxc-parser/binding-linux-arm64-musl': 0.112.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.112.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.112.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.112.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.112.0 + '@oxc-parser/binding-linux-x64-gnu': 0.112.0 + '@oxc-parser/binding-linux-x64-musl': 0.112.0 + '@oxc-parser/binding-openharmony-arm64': 0.112.0 + '@oxc-parser/binding-wasm32-wasi': 0.112.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.112.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.112.0 + '@oxc-parser/binding-win32-x64-msvc': 0.112.0 + + oxc-transform@0.112.0: + optionalDependencies: + '@oxc-transform/binding-android-arm-eabi': 0.112.0 + '@oxc-transform/binding-android-arm64': 0.112.0 + '@oxc-transform/binding-darwin-arm64': 0.112.0 + '@oxc-transform/binding-darwin-x64': 0.112.0 + '@oxc-transform/binding-freebsd-x64': 0.112.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.112.0 + '@oxc-transform/binding-linux-arm-musleabihf': 0.112.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.112.0 + '@oxc-transform/binding-linux-arm64-musl': 0.112.0 + '@oxc-transform/binding-linux-ppc64-gnu': 0.112.0 + '@oxc-transform/binding-linux-riscv64-gnu': 0.112.0 + '@oxc-transform/binding-linux-riscv64-musl': 0.112.0 + '@oxc-transform/binding-linux-s390x-gnu': 0.112.0 + '@oxc-transform/binding-linux-x64-gnu': 0.112.0 + '@oxc-transform/binding-linux-x64-musl': 0.112.0 + '@oxc-transform/binding-openharmony-arm64': 0.112.0 + '@oxc-transform/binding-wasm32-wasi': 0.112.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.112.0 + '@oxc-transform/binding-win32-ia32-msvc': 0.112.0 + '@oxc-transform/binding-win32-x64-msvc': 0.112.0 + + oxc-walker@0.7.0(oxc-parser@0.112.0): + dependencies: + magic-regexp: 0.10.0 + oxc-parser: 0.112.0 + p-any@4.0.0: dependencies: p-cancelable: 3.0.0 @@ -20818,6 +30383,12 @@ snapshots: p-reduce@3.0.0: {} + p-retry@6.2.1: + dependencies: + '@types/retry': 0.12.2 + is-network-error: 1.3.1 + retry: 0.13.1 + p-some@6.0.0: dependencies: aggregate-error: 4.0.1 @@ -20849,6 +30420,28 @@ snapshots: package-json-from-dist@1.0.1: {} + pacote@21.3.1: + dependencies: + '@npmcli/git': 7.0.2 + '@npmcli/installed-package-contents': 4.0.0 + '@npmcli/package-json': 7.0.5 + '@npmcli/promise-spawn': 9.0.1 + '@npmcli/run-script': 10.0.4 + cacache: 20.0.3 + fs-minipass: 3.0.3 + minipass: 7.1.2 + npm-package-arg: 13.0.2 + npm-packlist: 10.0.4 + npm-pick-manifest: 11.0.3 + npm-registry-fetch: 19.1.1 + proc-log: 6.1.0 + promise-retry: 2.0.1 + sigstore: 4.1.0 + ssri: 13.0.1 + tar: 7.5.11 + transitivePeerDependencies: + - supports-color + pako@0.2.9: {} pako@1.0.11: {} @@ -20914,6 +30507,8 @@ snapshots: parse-ms@4.0.0: {} + parse-node-version@1.0.1: {} + parse-path@7.1.0: dependencies: protocols: 2.0.2 @@ -20928,6 +30523,12 @@ snapshots: dependencies: parse-path: 7.1.0 + parse5-html-rewriting-stream@8.0.0: + dependencies: + entities: 6.0.1 + parse5: 8.0.0 + parse5-sax-parser: 8.0.0 + parse5-htmlparser2-tree-adapter@6.0.1: dependencies: parse5: 6.0.1 @@ -20941,6 +30542,10 @@ snapshots: dependencies: parse5: 7.3.0 + parse5-sax-parser@8.0.0: + dependencies: + parse5: 8.0.0 + parse5@5.1.1: {} parse5@6.0.1: {} @@ -20986,6 +30591,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.2: + dependencies: + lru-cache: 11.2.5 + minipass: 7.1.3 + path-to-regexp@0.1.12: {} path-to-regexp@0.1.7: {} @@ -20996,6 +30606,8 @@ snapshots: path-type@4.0.0: {} + pathe@1.1.2: {} + pathe@2.0.3: {} pathval@2.0.1: {} @@ -21022,6 +30634,8 @@ snapshots: pend@1.2.0: {} + perfect-debounce@2.1.0: {} + performance-now@2.1.0: {} picocolors@1.1.1: {} @@ -21034,8 +30648,21 @@ snapshots: pify@3.0.0: {} + pify@4.0.1: + optional: true + pify@6.1.0: {} + pinia@2.3.1(typescript@5.5.4)(vue@3.5.25(typescript@5.5.4)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.25(typescript@5.5.4) + vue-demi: 0.14.10(vue@3.5.25(typescript@5.5.4)) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - '@vue/composition-api' + pinia@2.3.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)): dependencies: '@vue/devtools-api': 6.6.4 @@ -21073,6 +30700,10 @@ snapshots: pirates@4.0.7: {} + piscina@5.1.4: + optionalDependencies: + '@napi-rs/nice': 1.1.1 + pkce-challenge@5.0.1: {} pkg-conf@2.1.0: @@ -21096,6 +30727,15 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 + pkijs@3.3.3: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.7 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + playwright-core@1.58.1: {} playwright@1.58.1: @@ -21108,6 +30748,43 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-calc@10.1.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-colormin@7.0.6(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.9(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.6(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + + postcss-discard-duplicates@7.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-discard-empty@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-discard-overridden@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-import@15.1.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -21136,6 +30813,79 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 + postcss-loader@8.2.0(postcss@8.5.6)(typescript@5.9.3)(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + cosmiconfig: 9.0.0(typescript@5.9.3) + jiti: 2.6.1 + postcss: 8.5.6 + semver: 7.7.4 + optionalDependencies: + webpack: 5.105.2(esbuild@0.27.3) + transitivePeerDependencies: + - typescript + + postcss-media-query-parser@0.2.3: {} + + postcss-merge-longhand@7.0.5(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.8(postcss@8.5.6) + + postcss-merge-rules@7.0.8(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + + postcss-minify-font-values@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.1(postcss@8.5.6): + dependencies: + colord: 2.9.3 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.6(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.0.6(postcss@8.5.6): + dependencies: + cssesc: 3.0.0 + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + + postcss-modules-extract-imports@3.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + + postcss-modules-values@4.0.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-nested-import@1.3.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -21146,23 +30896,113 @@ snapshots: postcss: 8.5.6 postcss-selector-parser: 6.1.2 + postcss-normalize-charset@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-normalize-display-values@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.6(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.2(postcss@8.5.6): + dependencies: + cssnano-utils: 5.0.1(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + postcss-prefixwrap@1.57.2(postcss@8.5.6): dependencies: postcss: 8.5.6 + postcss-reduce-initial@7.0.6(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-api: 3.0.0 + postcss: 8.5.6 + + postcss-reduce-transforms@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-safe-parser@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@7.1.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + svgo: 4.0.1 + + postcss-unique-selectors@7.0.5(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + postcss-value-parser@4.2.0: {} + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + powershell-utils@0.1.0: {} + prebuild-install@7.1.3: dependencies: detect-libc: 2.1.2 @@ -21184,6 +31024,8 @@ snapshots: prettier@3.8.1: {} + pretty-bytes@7.1.0: {} + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -21194,16 +31036,25 @@ snapshots: dependencies: parse-ms: 4.0.0 + proc-log@6.1.0: {} + process-nextick-args@2.0.1: {} process-warning@1.0.0: {} + process-warning@4.0.1: {} + process-warning@5.0.0: {} process@0.11.10: {} progress@2.0.3: {} + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -21318,6 +31169,9 @@ snapshots: proxy-from-env@1.1.0: {} + prr@1.0.1: + optional: true + pstree.remy@1.1.8: {} public-encrypt@4.0.3: @@ -21385,6 +31239,12 @@ snapshots: - typescript - utf-8-validate + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.5: {} + qs@6.11.0: dependencies: side-channel: 1.1.0 @@ -21407,6 +31267,8 @@ snapshots: quick-lru@5.1.1: {} + radix3@1.1.2: {} + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -21441,6 +31303,16 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + + rc9@3.0.0: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -21467,6 +31339,8 @@ snapshots: react: 19.2.3 scheduler: 0.26.0 + react-refresh@0.17.0: {} + react-refresh@0.18.0: {} react-remove-scroll-bar@2.3.8(@types/react@19.2.11)(react@19.2.3): @@ -21566,12 +31440,18 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.6 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 readdirp@4.1.2: {} + readdirp@5.0.0: {} + real-require@0.2.0: {} recma-build-jsx@1.0.0: @@ -21608,6 +31488,14 @@ snapshots: indent-string: 4.0.0 strip-indent: 3.0.0 + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + + reflect-metadata@0.2.2: {} + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -21619,6 +31507,14 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regex-parser@2.3.1: {} + regex-recursion@6.0.2: dependencies: regex-utilities: 2.3.0 @@ -21629,6 +31525,8 @@ snapshots: dependencies: regex-utilities: 2.3.0 + regexp-tree@0.1.27: {} + regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -21638,6 +31536,15 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + regexpu-core@6.4.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.13.0 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + registry-auth-token@3.3.2: dependencies: rc: 1.2.8 @@ -21655,6 +31562,12 @@ snapshots: dependencies: rc: 1.2.8 + regjsgen@0.8.0: {} + + regjsparser@0.13.0: + dependencies: + jsesc: 3.1.0 + rehype-katex@7.0.1: dependencies: '@types/hast': 3.0.4 @@ -21863,6 +31776,8 @@ snapshots: require-from-string@2.0.2: {} + requires-port@1.0.0: {} + resolve-alpn@1.2.1: {} resolve-from@4.0.0: {} @@ -21871,6 +31786,14 @@ snapshots: resolve-pkg-maps@1.0.0: {} + resolve-url-loader@5.0.0: + dependencies: + adjust-sourcemap-loader: 4.0.0 + convert-source-map: 1.9.0 + loader-utils: 2.0.4 + postcss: 8.5.6 + source-map: 0.6.1 + resolve@1.22.11: dependencies: is-core-module: 2.16.1 @@ -21896,6 +31819,13 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + ret@0.5.0: {} + retext-latin@4.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -21921,8 +31851,14 @@ snapshots: retext-stringify: 4.0.0 unified: 11.0.5 + retry@0.12.0: {} + + retry@0.13.1: {} + reusify@1.1.0: {} + rfdc@1.4.1: {} + rimraf@3.0.2: dependencies: glob: 7.2.3 @@ -21932,7 +31868,7 @@ snapshots: hash-base: 3.1.2 inherits: 2.0.4 - rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): + rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@oxc-project/runtime': 0.101.0 fdir: 6.5.0(picomatch@4.0.3) @@ -21946,10 +31882,33 @@ snapshots: esbuild: 0.27.2 fsevents: 2.3.3 jiti: 2.6.1 + less: 4.4.2 + sass: 1.97.3 + terser: 5.46.0 + tsx: 4.21.0 + yaml: 2.8.2 + + rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + '@oxc-project/runtime': 0.101.0 + fdir: 6.5.0(picomatch@4.0.3) + lightningcss: 1.31.1 + picomatch: 4.0.3 + postcss: 8.5.6 + rolldown: 1.0.0-beta.53 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.2 + esbuild: 0.27.3 + fsevents: 2.3.3 + jiti: 2.6.1 + less: 4.4.2 + sass: 1.97.3 + terser: 5.46.0 tsx: 4.21.0 yaml: 2.8.2 - rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): + rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@oxc-project/runtime': 0.101.0 fdir: 6.5.0(picomatch@4.0.3) @@ -21960,9 +31919,12 @@ snapshots: tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.19.8 - esbuild: 0.27.2 + esbuild: 0.27.3 fsevents: 2.3.3 jiti: 2.6.1 + less: 4.4.2 + sass: 1.97.3 + terser: 5.46.0 tsx: 4.21.0 yaml: 2.8.2 @@ -21985,6 +31947,25 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.53 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.53 + rolldown@1.0.0-rc.4: + dependencies: + '@oxc-project/types': 0.113.0 + '@rolldown/pluginutils': 1.0.0-rc.4 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.4 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.4 + '@rolldown/binding-darwin-x64': 1.0.0-rc.4 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.4 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.4 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.4 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.4 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.4 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.4 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.4 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.4 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.4 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.4 + rollup-plugin-copy@3.5.0: dependencies: '@types/fs-extra': 8.1.5 @@ -22002,6 +31983,16 @@ snapshots: optionalDependencies: rollup: 4.57.1 + rollup-plugin-visualizer@6.0.11(rolldown@1.0.0-rc.4)(rollup@4.57.1): + dependencies: + open: 8.4.2 + picomatch: 4.0.3 + source-map: 0.7.6 + yargs: 17.7.2 + optionalDependencies: + rolldown: 1.0.0-rc.4 + rollup: 4.57.1 + rollup@4.57.1: dependencies: '@types/estree': 1.0.8 @@ -22035,6 +32026,8 @@ snapshots: rope-sequence@1.3.4: {} + rou3@0.7.12: {} + router@2.2.0: dependencies: debug: 4.4.3(supports-color@5.5.0) @@ -22084,14 +32077,35 @@ snapshots: es-errors: 1.3.0 is-regex: 1.2.1 + safe-regex2@5.0.0: + dependencies: + ret: 0.5.0 + safe-stable-stringify@1.1.1: {} safe-stable-stringify@2.5.0: {} - safer-buffer@2.1.2: {} + safer-buffer@2.1.2: {} + + sass-loader@16.0.7(sass@1.97.3)(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + neo-async: 2.6.2 + optionalDependencies: + sass: 1.97.3 + webpack: 5.105.2(esbuild@0.27.3) + + sass@1.97.3: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 sax@1.4.4: {} + sax@1.5.0: {} + saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -22100,8 +32114,26 @@ snapshots: scheduler@0.27.0: {} + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + scule@1.3.0: {} + + secure-json-parse@4.1.0: {} + seemly@0.3.10: {} + select-hose@2.0.0: {} + + selfsigned@5.5.0: + dependencies: + '@peculiar/x509': 1.14.3 + pkijs: 3.3.3 + semantic-release-commit-filter@1.0.2: {} semantic-release-linear-app@0.7.1(semantic-release@24.2.9(typescript@5.9.3)): @@ -22180,6 +32212,8 @@ snapshots: semver@7.7.3: {} + semver@7.7.4: {} + send@0.18.0: dependencies: debug: 2.6.9 @@ -22236,6 +32270,14 @@ snapshots: dependencies: type-fest: 4.41.0 + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serialize-javascript@7.0.4: {} + + seroval@1.5.1: {} + serve-handler@6.1.6: dependencies: bytes: 3.0.0 @@ -22246,6 +32288,22 @@ snapshots: path-to-regexp: 3.3.0 range-parser: 1.2.0 + serve-index@1.9.2: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.8.1 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-placeholder@2.0.2: + dependencies: + defu: 6.1.4 + serve-static@1.15.0: dependencies: encodeurl: 1.0.2 @@ -22289,6 +32347,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-cookie-parser@2.7.2: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -22321,6 +32381,10 @@ snapshots: safe-buffer: 5.2.1 to-buffer: 1.2.2 + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + sharp-ico@0.1.5: dependencies: decode-ico: 0.4.1 @@ -22445,6 +32509,17 @@ snapshots: signature_pad@5.1.3: {} + sigstore@4.1.0: + dependencies: + '@sigstore/bundle': 4.0.0 + '@sigstore/core': 3.1.0 + '@sigstore/protobuf-specs': 0.5.0 + '@sigstore/sign': 4.1.0 + '@sigstore/tuf': 4.0.1 + '@sigstore/verify': 3.1.0 + transitivePeerDependencies: + - supports-color + simple-concat@1.0.1: {} simple-eval@1.0.1: @@ -22457,6 +32532,14 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 + simple-git@3.32.3: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.4.3(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + simple-swizzle@0.2.4: dependencies: is-arrayish: 0.3.4 @@ -22479,6 +32562,8 @@ snapshots: slash@3.0.0: {} + slash@5.1.0: {} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.3 @@ -22489,8 +32574,15 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + smart-buffer@4.2.0: {} + smob@1.6.1: {} + socket.io-adapter@2.5.6: dependencies: debug: 4.4.3(supports-color@5.5.0) @@ -22521,6 +32613,12 @@ snapshots: - supports-color - utf-8-validate + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.4 @@ -22544,6 +32642,17 @@ snapshots: source-map-js@1.2.1: {} + source-map-loader@5.0.0(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + iconv-lite: 0.6.3 + source-map-js: 1.2.1 + webpack: 5.105.2(esbuild@0.27.3) + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map@0.6.1: {} source-map@0.7.6: {} @@ -22571,6 +32680,27 @@ snapshots: spdx-license-ids@3.0.22: {} + spdy-transport@3.0.0: + dependencies: + debug: 4.4.3(supports-color@5.5.0) + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2(patch_hash=e4aadcbd3e7fffdf34e27d9a810232cda21beee31c3b1f1fda75b4877dfe5e61) + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2: + dependencies: + debug: 4.4.3(supports-color@5.5.0) + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + split2@1.0.0: dependencies: through2: 2.0.5 @@ -22579,6 +32709,8 @@ snapshots: sprintf-js@1.0.3: {} + srvx@0.11.9: {} + sshpk@1.18.0: dependencies: asn1: 0.2.6 @@ -22591,20 +32723,32 @@ snapshots: safer-buffer: 2.1.2 tweetnacl: 0.14.5 + ssri@13.0.1: + dependencies: + minipass: 7.1.2 + stable-hash-x@0.2.0: {} + stable-hash@0.0.5: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 stackback@0.0.2: {} + standard-as-callback@2.1.0: {} + + statuses@1.5.0: {} + statuses@2.0.1: {} statuses@2.0.2: {} std-env@3.10.0: {} + stdin-discarder@0.3.1: {} + steno@0.4.4: dependencies: graceful-fs: 4.2.11 @@ -22662,6 +32806,17 @@ snapshots: get-east-asian-width: 1.4.0 strip-ansi: 7.1.2 + string-width@8.2.0: + dependencies: + get-east-asian-width: 1.5.0 + strip-ansi: 7.1.2 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + string.prototype.matchall@4.0.12: dependencies: call-bind: 1.0.8 @@ -22751,6 +32906,8 @@ snapshots: strnum@2.1.2: {} + structured-clone-es@1.0.0: {} + style-to-js@1.1.21: dependencies: style-to-object: 1.0.14 @@ -22759,6 +32916,17 @@ snapshots: dependencies: inline-style-parser: 0.2.7 + styled-jsx@5.1.6(react@19.2.4): + dependencies: + client-only: 0.0.1 + react: 19.2.4 + + stylehacks@7.0.8(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + postcss: 8.5.6 + postcss-selector-parser: 7.1.1 + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -22798,6 +32966,56 @@ snapshots: - typescript - utf-8-validate + superdoc@1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.5.4)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19): + dependencies: + '@hocuspocus/provider': 2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + buffer-crc32: 1.0.0 + eventemitter3: 5.0.4 + jsdom: 27.3.0(canvas@3.2.1) + konva: 10.2.0 + naive-ui: 2.43.2(vue@3.5.25(typescript@5.5.4)) + pdfjs-dist: 5.4.624 + pinia: 2.3.1(typescript@5.5.4)(vue@3.5.25(typescript@5.5.4)) + rollup-plugin-copy: 3.5.0 + uuid: 9.0.1 + vue: 3.5.25(typescript@5.5.4) + y-prosemirror: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + y-websocket: 3.0.0(yjs@13.6.19) + yjs: 13.6.19 + transitivePeerDependencies: + - '@vue/composition-api' + - bufferutil + - canvas + - supports-color + - typescript + - utf-8-validate + + superdoc@1.18.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(canvas@3.2.1)(pdfjs-dist@5.4.624)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19): + dependencies: + '@hocuspocus/provider': 2.15.3(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + buffer-crc32: 1.0.0 + eventemitter3: 5.0.4 + jsdom: 27.3.0(canvas@3.2.1) + konva: 10.2.0 + naive-ui: 2.43.2(vue@3.5.25(typescript@5.9.3)) + pdfjs-dist: 5.4.624 + pinia: 2.3.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) + rollup-plugin-copy: 3.5.0 + uuid: 9.0.1 + vue: 3.5.25(typescript@5.9.3) + y-prosemirror: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19) + y-websocket: 3.0.0(yjs@13.6.19) + yjs: 13.6.19 + transitivePeerDependencies: + - '@vue/composition-api' + - bufferutil + - canvas + - supports-color + - typescript + - utf-8-validate + + supports-color@10.2.2: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -22819,8 +33037,22 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svgo@4.0.1: + dependencies: + commander: 11.1.0 + css-select: 5.2.2 + css-tree: 3.1.0 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.5.0 + symbol-tree@3.2.4: {} + system-architecture@0.1.0: {} + + tagged-tag@1.0.0: {} + tailwindcss@3.4.4: dependencies: '@alloc/quick-lru': 5.2.0 @@ -22848,6 +33080,10 @@ snapshots: transitivePeerDependencies: - ts-node + tailwindcss@4.2.1: {} + + tapable@2.3.0: {} + tar-fs@2.1.4: dependencies: chownr: 1.1.4 @@ -22893,6 +33129,14 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + tar@7.5.11: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 + temp-dir@2.0.0: {} temp-dir@3.0.0: {} @@ -22912,6 +33156,23 @@ snapshots: type-fest: 2.19.0 unique-string: 3.0.0 + terser-webpack-plugin@5.3.17(esbuild@0.27.3)(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.46.0 + webpack: 5.105.2(esbuild@0.27.3) + optionalDependencies: + esbuild: 0.27.3 + + terser@5.46.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 @@ -22934,6 +33195,10 @@ snapshots: dependencies: any-promise: 1.3.0 + thingies@2.5.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + thread-stream@3.1.0: dependencies: real-require: 0.2.0 @@ -22945,6 +33210,8 @@ snapshots: through@2.3.8: {} + thunky@1.1.0: {} + time-span@5.1.0: dependencies: convert-hrtime: 5.0.0 @@ -22953,6 +33220,8 @@ snapshots: dependencies: setimmediate: 1.0.5 + tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -23000,6 +33269,8 @@ snapshots: dependencies: is-number: 7.0.0 + toad-cache@3.7.0: {} + toidentifier@1.0.1: {} totalist@3.0.1: {} @@ -23022,6 +33293,10 @@ snapshots: traverse@0.6.8: {} + tree-dump@1.1.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + tree-kill@1.2.2: {} treemate@0.3.11: {} @@ -23038,6 +33313,13 @@ snapshots: ts-interface-checker@0.1.13: {} + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + tslib@1.14.1: {} tslib@2.8.1: {} @@ -23078,8 +33360,20 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + tty-browserify@0.0.1: {} + tuf-js@4.1.0: + dependencies: + '@tufjs/models': 4.1.0 + debug: 4.4.3(supports-color@5.5.0) + make-fetch-happen: 15.0.4 + transitivePeerDependencies: + - supports-color + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -23116,6 +33410,10 @@ snapshots: type-fest@4.41.0: {} + type-fest@5.4.4: + dependencies: + tagged-tag: 1.0.0 + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -23127,6 +33425,8 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.2 + type-level-regexp@0.1.17: {} + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -23160,6 +33460,8 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 + typed-assert@1.0.9: {} + typed-rest-client@1.8.11: dependencies: qs: 6.14.1 @@ -23177,6 +33479,8 @@ snapshots: transitivePeerDependencies: - supports-color + typescript@5.5.4: {} + typescript@5.8.2: {} typescript@5.9.3: {} @@ -23188,6 +33492,8 @@ snapshots: uglify-js@3.19.3: optional: true + ultrahtml@1.6.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -23202,6 +33508,15 @@ snapshots: unc-path-regex@0.1.2: {} + uncrypto@0.1.3: {} + + unctx@2.5.0: + dependencies: + acorn: 8.15.0 + estree-walker: 3.0.3 + magic-string: 0.30.21 + unplugin: 2.3.11 + undefsafe@2.0.5: {} underscore@1.13.7: {} @@ -23210,12 +33525,35 @@ snapshots: undici@7.20.0: {} + undici@7.22.0: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + + unhead@2.1.10: + dependencies: + hookable: 6.0.1 + + unicode-canonical-property-names-ecmascript@2.0.1: {} + unicode-emoji-modifier-base@1.0.0: {} + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + unicorn-magic@0.1.0: {} unicorn-magic@0.3.0: {} + unicorn-magic@0.4.0: {} + unified@10.1.2: dependencies: '@types/unist': 2.0.11 @@ -23236,6 +33574,31 @@ snapshots: trough: 2.2.0 vfile: 6.0.3 + unimport@5.7.0: + dependencies: + acorn: 8.16.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.1.2 + magic-string: 0.30.21 + mlly: 1.8.0 + pathe: 2.0.3 + picomatch: 4.0.3 + pkg-types: 2.3.0 + scule: 1.3.0 + strip-literal: 3.1.0 + tinyglobby: 0.2.15 + unplugin: 2.3.11 + unplugin-utils: 0.3.1 + + unique-filename@5.0.0: + dependencies: + unique-slug: 6.0.0 + + unique-slug@6.0.0: + dependencies: + imurmurhash: 0.1.4 + unique-string@2.0.0: dependencies: crypto-random-string: 2.0.0 @@ -23354,6 +33717,49 @@ snapshots: unpipe@1.0.0: {} + unplugin-utils@0.3.1: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.3 + + unplugin-vue-router@0.19.2(@vue/compiler-sfc@3.5.25)(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)): + dependencies: + '@babel/generator': 7.29.1 + '@vue-macros/common': 3.1.2(vue@3.5.25(typescript@5.9.3)) + '@vue/compiler-sfc': 3.5.25 + '@vue/language-core': 3.2.5 + ast-walker-scope: 0.8.3 + chokidar: 5.0.0 + json5: 2.2.3 + local-pkg: 1.1.2 + magic-string: 0.30.21 + mlly: 1.8.0 + muggle-string: 0.4.1 + pathe: 2.0.3 + picomatch: 4.0.3 + scule: 1.3.0 + tinyglobby: 0.2.15 + unplugin: 2.3.11 + unplugin-utils: 0.3.1 + yaml: 2.8.2 + optionalDependencies: + vue-router: 4.6.4(vue@3.5.25(typescript@5.9.3)) + transitivePeerDependencies: + - vue + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + + unplugin@3.0.0: + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + unrs-resolver@1.11.1: dependencies: napi-postinstall: 0.3.4 @@ -23378,6 +33784,44 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + unstorage@1.17.4(@azure/identity@4.13.0)(db0@0.3.4)(ioredis@5.10.0): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.6 + lru-cache: 11.2.5 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.3 + optionalDependencies: + '@azure/identity': 4.13.0 + db0: 0.3.4 + ioredis: 5.10.0 + + untun@0.1.3: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 1.1.2 + + untyped@2.0.0: + dependencies: + citty: 0.1.6 + defu: 6.1.4 + jiti: 2.6.1 + knitwork: 1.3.0 + scule: 1.3.0 + + unwasm@0.5.3: + dependencies: + exsolve: 1.0.8 + knitwork: 1.3.0 + magic-string: 0.30.21 + mlly: 1.8.0 + pathe: 2.0.3 + pkg-types: 2.3.0 + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 @@ -23389,6 +33833,8 @@ snapshots: registry-auth-token: 3.3.2 registry-url: 3.1.0 + uqr@0.1.2: {} + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -23457,10 +33903,17 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + validate-npm-package-name@7.0.2: {} + validator@13.15.26: {} vary@1.1.2: {} + vdirs@0.1.8(vue@3.5.25(typescript@5.5.4)): + dependencies: + evtd: 0.2.4 + vue: 3.5.25(typescript@5.5.4) + vdirs@0.1.8(vue@3.5.25(typescript@5.9.3)): dependencies: evtd: 0.2.4 @@ -23592,13 +34045,44 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): + vite-dev-rpc@1.1.0(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + birpc: 2.9.0 + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-hot-client: 2.1.0(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + + vite-hot-client@2.1.0(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + vite-node@3.2.4(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + cac: 6.7.14 + debug: 4.4.3(supports-color@5.5.0) + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - esbuild + - jiti + - less + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-node@3.2.4(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: cac: 6.7.14 debug: 4.4.3(supports-color@5.5.0) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - esbuild @@ -23613,13 +34097,13 @@ snapshots: - tsx - yaml - vite-node@3.2.4(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): + vite-node@3.2.4(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: cac: 6.7.14 debug: 4.4.3(supports-color@5.5.0) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - esbuild @@ -23634,7 +34118,44 @@ snapshots: - tsx - yaml - vite-plugin-dts@4.5.4(@types/node@22.19.2)(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3): + vite-node@5.3.0(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + cac: 6.7.14 + es-module-lexer: 2.0.0 + obug: 2.1.1 + pathe: 2.0.3 + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/node' + - esbuild + - jiti + - less + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vite-plugin-checker@0.12.0(eslint@9.39.2(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(typescript@5.9.3): + dependencies: + '@babel/code-frame': 7.29.0 + chokidar: 4.0.3 + npm-run-path: 6.0.0 + picocolors: 1.1.1 + picomatch: 4.0.3 + tiny-invariant: 1.3.3 + tinyglobby: 0.2.15 + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vscode-uri: 3.1.0 + optionalDependencies: + eslint: 9.39.2(jiti@2.6.1) + meow: 13.2.0 + optionator: 0.9.4 + typescript: 5.9.3 + + vite-plugin-dts@4.5.4(@types/node@22.19.2)(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3): dependencies: '@microsoft/api-extractor': 7.56.1(@types/node@22.19.2) '@rollup/pluginutils': 5.3.0(rollup@4.57.1) @@ -23647,13 +34168,13 @@ snapshots: magic-string: 0.30.21 typescript: 5.9.3 optionalDependencies: - vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-dts@4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3): + vite-plugin-dts@4.5.4(@types/node@22.19.8)(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1)(typescript@5.9.3): dependencies: '@microsoft/api-extractor': 7.56.1(@types/node@22.19.8) '@rollup/pluginutils': 5.3.0(rollup@4.57.1) @@ -23666,31 +34187,63 @@ snapshots: magic-string: 0.30.21 typescript: 5.9.3 optionalDependencies: - vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-node-polyfills@0.25.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1): + vite-plugin-full-reload@1.2.0: + dependencies: + picocolors: 1.1.1 + picomatch: 2.3.1 + + vite-plugin-inspect@11.3.3(@nuxt/kit@4.3.1(magicast@0.5.2))(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + ansis: 4.2.0 + debug: 4.4.3(supports-color@5.5.0) + error-stack-parser-es: 1.0.5 + ohash: 2.0.11 + open: 10.2.0 + perfect-debounce: 2.1.0 + sirv: 3.0.2 + unplugin-utils: 0.3.1 + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-dev-rpc: 1.1.0(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + optionalDependencies: + '@nuxt/kit': 4.3.1(magicast@0.5.2) + transitivePeerDependencies: + - supports-color + + vite-plugin-node-polyfills@0.25.0(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.57.1): dependencies: '@rollup/plugin-inject': 5.0.5(rollup@4.57.1) node-stdlib-browser: 1.3.1 - vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - rollup - vite-plugin-node-polyfills@0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2)): + vite-plugin-node-polyfills@0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@rollup/plugin-inject': 5.0.5(rollup@4.57.1) node-stdlib-browser: 1.3.1 - vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - rollup - vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(lightningcss@1.31.1)(tsx@4.21.0)(yaml@2.8.2): + vite-plugin-vue-tracer@1.2.0(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)): dependencies: - esbuild: 0.27.2 + estree-walker: 3.0.3 + exsolve: 1.0.8 + magic-string: 0.30.21 + pathe: 2.0.3 + source-map-js: 1.2.1 + vite: 7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vue: 3.5.25(typescript@5.9.3) + + vite@7.3.1(@types/node@22.19.2)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -23700,15 +34253,81 @@ snapshots: '@types/node': 22.19.2 fsevents: 2.3.3 jiti: 2.6.1 + less: 4.4.2 + lightningcss: 1.31.1 + sass: 1.97.3 + terser: 5.46.0 + tsx: 4.21.0 + yaml: 2.8.2 + + vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.8 + fsevents: 2.3.3 + jiti: 2.6.1 + less: 4.4.2 lightningcss: 1.31.1 + sass: 1.97.3 + terser: 5.46.0 tsx: 4.21.0 yaml: 2.8.2 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + debug: 4.4.3(supports-color@5.5.0) + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 22.19.2 + happy-dom: 20.4.0 + jsdom: 27.3.0(canvas@3.2.1) + transitivePeerDependencies: + - esbuild + - jiti + - less + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.2)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 3.2.4(rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -23726,8 +34345,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@22.19.2)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@22.19.2)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -23748,11 +34367,11 @@ snapshots: - tsx - yaml - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.2)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(tsx@4.21.0)(yaml@2.8.2): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.8)(esbuild@0.27.3)(happy-dom@20.4.0)(jiti@2.6.1)(jsdom@27.3.0(canvas@3.2.1))(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 3.2.4(rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -23770,8 +34389,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@22.19.8)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite-node: 3.2.4(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -23794,6 +34413,11 @@ snapshots: vm-browserify@1.1.2: {} + vooks@0.2.12(vue@3.5.25(typescript@5.5.4)): + dependencies: + evtd: 0.2.4 + vue: 3.5.25(typescript@5.5.4) + vooks@0.2.12(vue@3.5.25(typescript@5.9.3)): dependencies: evtd: 0.2.4 @@ -23801,18 +34425,43 @@ snapshots: vscode-uri@3.1.0: {} + vue-bundle-renderer@2.2.0: + dependencies: + ufo: 1.6.3 + vue-component-type-helpers@2.2.12: {} + vue-demi@0.14.10(vue@3.5.25(typescript@5.5.4)): + dependencies: + vue: 3.5.25(typescript@5.5.4) + vue-demi@0.14.10(vue@3.5.25(typescript@5.9.3)): dependencies: vue: 3.5.25(typescript@5.9.3) + vue-devtools-stub@0.1.0: {} + + vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.25(typescript@5.9.3) + vue-template-compiler@2.7.16: dependencies: de-indent: 1.0.2 he: 1.2.0 optional: true + vue@3.5.25(typescript@5.5.4): + dependencies: + '@vue/compiler-dom': 3.5.25 + '@vue/compiler-sfc': 3.5.25 + '@vue/runtime-dom': 3.5.25 + '@vue/server-renderer': 3.5.25(vue@3.5.25(typescript@5.5.4)) + '@vue/shared': 3.5.25 + optionalDependencies: + typescript: 5.5.4 + vue@3.5.25(typescript@5.9.3): dependencies: '@vue/compiler-dom': 3.5.25 @@ -23823,6 +34472,17 @@ snapshots: optionalDependencies: typescript: 5.9.3 + vueuc@0.4.65(vue@3.5.25(typescript@5.5.4)): + dependencies: + '@css-render/vue3-ssr': 0.15.14(vue@3.5.25(typescript@5.5.4)) + '@juggle/resize-observer': 3.4.0 + css-render: 0.15.14 + evtd: 0.2.4 + seemly: 0.3.10 + vdirs: 0.1.8(vue@3.5.25(typescript@5.5.4)) + vooks: 0.2.12(vue@3.5.25(typescript@5.5.4)) + vue: 3.5.25(typescript@5.5.4) + vueuc@0.4.65(vue@3.5.25(typescript@5.9.3)): dependencies: '@css-render/vue3-ssr': 0.15.14(vue@3.5.25(typescript@5.9.3)) @@ -23840,6 +34500,18 @@ snapshots: dependencies: xml-name-validator: 5.0.0 + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + weak-lru-cache@1.2.2: + optional: true + web-namespaces@2.0.1: {} web-streams-polyfill@3.3.3: {} @@ -23850,6 +34522,113 @@ snapshots: webidl-conversions@8.0.1: {} + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + colorette: 2.0.20 + memfs: 4.56.11(tslib@2.8.1) + mime-types: 3.0.2 + on-finished: 2.4.1 + range-parser: 1.2.1 + schema-utils: 4.3.3 + optionalDependencies: + webpack: 5.105.2(esbuild@0.27.3) + transitivePeerDependencies: + - tslib + + webpack-dev-server@5.2.3(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/express-serve-static-core': 4.19.8 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + express: 4.22.1 + graceful-fs: 4.2.11 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.3.0 + launch-editor: 2.13.1 + open: 10.2.0 + p-retry: 6.2.1 + schema-utils: 4.3.3 + selfsigned: 5.5.0 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)) + ws: 8.19.0 + optionalDependencies: + webpack: 5.105.2(esbuild@0.27.3) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - tslib + - utf-8-validate + + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@3.3.4: {} + + webpack-subresource-integrity@5.1.0(webpack@5.105.2(esbuild@0.27.3)): + dependencies: + typed-assert: 1.0.9 + webpack: 5.105.2(esbuild@0.27.3) + + webpack-virtual-modules@0.6.2: {} + + webpack@5.105.2(esbuild@0.27.3): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.28.1 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.20.0 + es-module-lexer: 2.0.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.17(esbuild@0.27.3)(webpack@5.105.2(esbuild@0.27.3)) + watchpack: 2.5.1 + webpack-sources: 3.3.4 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + whatwg-encoding@3.1.1: dependencies: iconv-lite: 0.6.3 @@ -23915,6 +34694,14 @@ snapshots: dependencies: isexe: 2.0.0 + which@5.0.0: + dependencies: + isexe: 3.1.5 + + which@6.0.1: + dependencies: + isexe: 4.0.0 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -23928,6 +34715,8 @@ snapshots: dependencies: string-width: 7.2.0 + wildcard@2.0.1: {} + word-wrap@1.2.5: {} wordwrap@1.0.0: {} @@ -23968,6 +34757,11 @@ snapshots: dependencies: is-wsl: 3.1.0 + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.0 + powershell-utils: 0.1.0 + xml-js@1.6.11: dependencies: sax: 1.4.4 @@ -23990,6 +34784,11 @@ snapshots: xtend@4.0.2: {} + y-indexeddb@9.0.12(yjs@13.6.19): + dependencies: + lib0: 0.2.117 + yjs: 13.6.19 + y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.5)(y-protocols@1.0.7(yjs@13.6.19))(yjs@13.6.19): dependencies: lib0: 0.2.117 @@ -24016,12 +34815,16 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yaml@2.8.2: {} yargs-parser@20.2.9: {} yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@16.2.0: dependencies: cliui: 7.0.4 @@ -24052,6 +34855,15 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + yauzl@2.10.0: dependencies: buffer-crc32: 0.2.13 @@ -24075,6 +34887,25 @@ snapshots: yoga-layout@3.2.1: {} + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.0: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.7.0 + '@speed-highlight/core': 1.2.14 + cookie-es: 2.0.0 + youch-core: 0.3.3 + + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + zod-to-json-schema@3.20.4(zod@3.21.4): dependencies: zod: 3.21.4 @@ -24099,4 +34930,6 @@ snapshots: zod@4.3.6: {} + zone.js@0.16.1: {} + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 95ff71f8d8..b382b62513 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -9,6 +9,7 @@ packages: - packages/**/* - shared/* - examples/* + - examples/*/* catalog: '@commitlint/cli': ^19.8.1 From 68755e5bcb28799fbcc249c3159000bc60039453 Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 12 Mar 2026 10:38:53 -0300 Subject: [PATCH 123/125] fix(numbering): missing imports --- .../super-editor/src/core/helpers/list-numbering-helpers.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/super-editor/src/core/helpers/list-numbering-helpers.js b/packages/super-editor/src/core/helpers/list-numbering-helpers.js index 243adf3092..f59acf5fff 100644 --- a/packages/super-editor/src/core/helpers/list-numbering-helpers.js +++ b/packages/super-editor/src/core/helpers/list-numbering-helpers.js @@ -1,5 +1,7 @@ // @ts-check import { getStyleTagFromStyleId } from '@core/super-converter/v2/importer/listImporter.js'; +import { translator as wAbstractNumTranslator } from '@core/super-converter/v3/handlers/w/abstractNum'; +import { translator as wNumTranslator } from '@core/super-converter/v3/handlers/w/num'; import { baseBulletList, baseOrderedListDef } from './baseListDefinitions'; import { updateNumberingProperties } from '@core/commands/changeListLevel'; import { findParentNode } from './findParentNode.js'; From 25a2ae42d8d88d8d6eb026bb48ab3c0241818a5d Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 12 Mar 2026 10:57:05 -0300 Subject: [PATCH 124/125] chore: update lock file --- pnpm-lock.yaml | 1026 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1024 insertions(+), 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8985e1050b..e0acae7369 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -588,6 +588,19 @@ importers: specifier: npm:rolldown-vite@7.3.1 version: rolldown-vite@7.3.1(@types/node@22.19.8)(esbuild@0.27.3)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + examples/ai/bedrock: + dependencies: + '@aws-sdk/client-bedrock-runtime': + specifier: ^3.750.0 + version: 3.1007.0 + '@superdoc-dev/sdk': + specifier: latest + version: 1.0.0-alpha.44 + devDependencies: + tsx: + specifier: ^4.21.0 + version: 4.21.0 + examples/collaboration/hocuspocus: dependencies: '@hocuspocus/provider': @@ -2278,6 +2291,10 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + '@aws-sdk/client-bedrock-runtime@3.1007.0': + resolution: {integrity: sha512-X7iWTQAZrCvQH2lfrZktVPfR3jdLPNtI4zkk4NA/vXzW5k8VNgdVuWUSm8cAzIXnhV3YThvDpLhEk87igNyGWQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/client-s3@3.988.0': resolution: {integrity: sha512-mt7AdkieJJ5hEKeCxH4sdTTd679shUjo/cUvNY0fUHgQIPZa1jRuekTXnRytRrEwdrZWJDx56n1S8ism2uX7jg==} engines: {node: '>=20.0.0'} @@ -2286,6 +2303,10 @@ packages: resolution: {integrity: sha512-ThqQ7aF1k0Zz4yJRwegHw+T1rM3a7ZPvvEUSEdvn5Z8zTeWgJAbtqW/6ejPsMLmFOlHgNcwDQN/e69OvtEOoIQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/core@3.973.19': + resolution: {integrity: sha512-56KePyOcZnKTWCd89oJS1G6j3HZ9Kc+bh/8+EbvtaCCXdP6T7O7NzCiPuHRhFLWnzXIaXX3CxAz0nI5My9spHQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/core@3.973.8': resolution: {integrity: sha512-WeYJ2sfvRLbbUIrjGMUXcEHGu5SJk53jz3K9F8vFP42zWyROzPJ2NB6lMu9vWl5hnMwzwabX7pJc9Euh3JyMGw==} engines: {node: '>=20.0.0'} @@ -2294,42 +2315,82 @@ packages: resolution: {integrity: sha512-ThlLhTqX68jvoIVv+pryOdb5coP1cX1/MaTbB9xkGDCbWbsqQcLqzPxuSoW1DCnAAIacmXCWpzUNOB9pv+xXQw==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-env@3.972.17': + resolution: {integrity: sha512-MBAMW6YELzE1SdkOniqr51mrjapQUv8JXSGxtwRjQV0mwVDutVsn22OPAUt4RcLRvdiHQmNBDEFP9iTeSVCOlA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-env@3.972.6': resolution: {integrity: sha512-+dYEBWgTqkQQHFUllvBL8SLyXyLKWdxLMD1LmKJRvmb0NMJuaJFG/qg78C+LE67eeGbipYcE+gJ48VlLBGHlMw==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-http@3.972.19': + resolution: {integrity: sha512-9EJROO8LXll5a7eUFqu48k6BChrtokbmgeMWmsH7lBb6lVbtjslUYz/ShLi+SHkYzTomiGBhmzTW7y+H4BxsnA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-http@3.972.8': resolution: {integrity: sha512-z3QkozMV8kOFisN2pgRag/f0zPDrw96mY+ejAM0xssV/+YQ2kklbylRNI/TcTQUDnGg0yPxNjyV6F2EM2zPTwg==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-ini@3.972.18': + resolution: {integrity: sha512-vthIAXJISZnj2576HeyLBj4WTeX+I7PwWeRkbOa0mVX39K13SCGxCgOFuKj2ytm9qTlLOmXe4cdEnroteFtJfw==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-ini@3.972.6': resolution: {integrity: sha512-6tkIYFv3sZH1XsjQq+veOmx8XWRnyqTZ5zx/sMtdu/xFRIzrJM1Y2wAXeCJL1rhYSB7uJSZ1PgALI2WVTj78ow==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-login@3.972.18': + resolution: {integrity: sha512-kINzc5BBxdYBkPZ0/i1AMPMOk5b5QaFNbYMElVw5QTX13AKj6jcxnv/YNl9oW9mg+Y08ti19hh01HhyEAxsSJQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-login@3.972.6': resolution: {integrity: sha512-LXsoBoaTSGHdRCQXlWSA0CHHh05KWncb592h9ElklnPus++8kYn1Ic6acBR4LKFQ0RjjMVgwe5ypUpmTSUOjPA==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-node@3.972.19': + resolution: {integrity: sha512-yDWQ9dFTr+IMxwanFe7+tbN5++q8psZBjlUwOiCXn1EzANoBgtqBwcpYcHaMGtn0Wlfj4NuXdf2JaEx1lz5RaQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-node@3.972.7': resolution: {integrity: sha512-PuJ1IkISG7ZDpBFYpGotaay6dYtmriBYuHJ/Oko4VHxh8YN5vfoWnMNYFEWuzOfyLmP7o9kDVW0BlYIpb3skvw==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-process@3.972.17': + resolution: {integrity: sha512-c8G8wT1axpJDgaP3xzcy+q8Y1fTi9A2eIQJvyhQ9xuXrUZhlCfXbC0vM9bM1CUXiZppFQ1p7g0tuUMvil/gCPg==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-process@3.972.6': resolution: {integrity: sha512-Yf34cjIZJHVnD92jnVYy3tNjM+Q4WJtffLK2Ehn0nKpZfqd1m7SI0ra22Lym4C53ED76oZENVSS2wimoXJtChQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-sso@3.972.18': + resolution: {integrity: sha512-YHYEfj5S2aqInRt5ub8nDOX8vAxgMvd84wm2Y3WVNfFa/53vOv9T7WOAqXI25qjj3uEcV46xxfqdDQk04h5XQA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-sso@3.972.6': resolution: {integrity: sha512-2+5UVwUYdD4BBOkLpKJ11MQ8wQeyJGDVMDRH5eWOULAh9d6HJq07R69M/mNNMC9NTjr3mB1T0KGDn4qyQh5jzg==} engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-web-identity@3.972.18': + resolution: {integrity: sha512-OqlEQpJ+J3T5B96qtC1zLLwkBloechP+fezKbCH0sbd2cCc0Ra55XpxWpk/hRj69xAOYtHvoC4orx6eTa4zU7g==} + engines: {node: '>=20.0.0'} + '@aws-sdk/credential-provider-web-identity@3.972.6': resolution: {integrity: sha512-pdJzwKtlDxBnvZ04pWMqttijmkUIlwOsS0GcxCjzEVyUMpARysl0S0ks74+gs2Pdev3Ujz+BTAjOc1tQgAxGqA==} engines: {node: '>=20.0.0'} + '@aws-sdk/eventstream-handler-node@3.972.10': + resolution: {integrity: sha512-g2Z9s6Y4iNh0wICaEqutgYgt/Pmhv5Ev9G3eKGFe2w9VuZDhc76vYdop6I5OocmpHV79d4TuLG+JWg5rQIVDVA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-bucket-endpoint@3.972.3': resolution: {integrity: sha512-fmbgWYirF67YF1GfD7cg5N6HHQ96EyRNx/rDIrTF277/zTWVuPI2qS/ZHgofwR1NZPe/NWvoppflQY01LrbVLg==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-eventstream@3.972.7': + resolution: {integrity: sha512-VWndapHYCfwLgPpCb/xwlMKG4imhFzKJzZcKOEioGn7OHY+6gdr0K7oqy1HZgbLa3ACznZ9fku+DzmAi8fUC0g==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-expect-continue@3.972.3': resolution: {integrity: sha512-4msC33RZsXQpUKR5QR4HnvBSNCPLGHmB55oDiROqqgyOc+TOfVu2xgi5goA7ms6MdZLeEh2905UfWMnMMF4mRg==} engines: {node: '>=20.0.0'} @@ -2342,6 +2403,10 @@ packages: resolution: {integrity: sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-host-header@3.972.7': + resolution: {integrity: sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-location-constraint@3.972.3': resolution: {integrity: sha512-nIg64CVrsXp67vbK0U1/Is8rik3huS3QkRHn2DRDx4NldrEFMgdkZGI/+cZMKD9k4YOS110Dfu21KZLHrFA/1g==} engines: {node: '>=20.0.0'} @@ -2350,10 +2415,18 @@ packages: resolution: {integrity: sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-logger@3.972.7': + resolution: {integrity: sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-recursion-detection@3.972.3': resolution: {integrity: sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-recursion-detection@3.972.7': + resolution: {integrity: sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-sdk-s3@3.972.8': resolution: {integrity: sha512-/yJdahpN/q3Dc88qXBTQVZfnXryLnxfCoP4hGClbKjuF0VCMxrz3il7sj0GhIkEQt5OM5+lA88XrvbjjuwSxIg==} engines: {node: '>=20.0.0'} @@ -2362,22 +2435,46 @@ packages: resolution: {integrity: sha512-dU6kDuULN3o3jEHcjm0c4zWJlY1zWVkjG9NPe9qxYLLpcbdj5kRYBS2DdWYD+1B9f910DezRuws7xDEqKkHQIg==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-user-agent@3.972.20': + resolution: {integrity: sha512-3kNTLtpUdeahxtnJRnj/oIdLAUdzTfr9N40KtxNhtdrq+Q1RPMdCJINRXq37m4t5+r3H70wgC3opW46OzFcZYA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-user-agent@3.972.8': resolution: {integrity: sha512-3PGL+Kvh1PhB0EeJeqNqOWQgipdqFheO4OUKc6aYiFwEpM5t9AyE5hjjxZ5X6iSj8JiduWFZLPwASzF6wQRgFg==} engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-websocket@3.972.12': + resolution: {integrity: sha512-iyPP6FVDKe/5wy5ojC0akpDFG1vX3FeCUU47JuwN8xfvT66xlEI8qUJZPtN55TJVFzzWZJpWL78eqUE31md08Q==} + engines: {node: '>= 14.0.0'} + '@aws-sdk/nested-clients@3.988.0': resolution: {integrity: sha512-OgYV9k1oBCQ6dOM+wWAMNNehXA8L4iwr7ydFV+JDHyuuu0Ko7tDXnLEtEmeQGYRcAFU3MGasmlBkMB8vf4POrg==} engines: {node: '>=20.0.0'} + '@aws-sdk/nested-clients@3.996.8': + resolution: {integrity: sha512-6HlLm8ciMW8VzfB80kfIx16PBA9lOa9Dl+dmCBi78JDhvGlx3I7Rorwi5PpVRkL31RprXnYna3yBf6UKkD/PqA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/region-config-resolver@3.972.3': resolution: {integrity: sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==} engines: {node: '>=20.0.0'} + '@aws-sdk/region-config-resolver@3.972.7': + resolution: {integrity: sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/signature-v4-multi-region@3.988.0': resolution: {integrity: sha512-SXwhbe2v0Jno7QLIBmZWAL2eVzGmXkfLLy0WkM6ZJVhE0SFUcnymDwMUA1oMDUvyArzvKBiU8khQ2ImheCKOHQ==} engines: {node: '>=20.0.0'} + '@aws-sdk/token-providers@3.1005.0': + resolution: {integrity: sha512-vMxd+ivKqSxU9bHx5vmAlFKDAkjGotFU56IOkDa5DaTu1WWwbcse0yFHEm9I537oVvodaiwMl3VBwgHfzQ2rvw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1007.0': + resolution: {integrity: sha512-kKvVyr53vvVc5k6RbvI6jhafxufxO2SkEw8QeEzJqwOXH/IMY7Cm0IyhnBGdqj80iiIIiIM2jGe7Fn3TIdwdrw==} + engines: {node: '>=20.0.0'} + '@aws-sdk/token-providers@3.988.0': resolution: {integrity: sha512-xvXVlRVKHnF2h6fgWBm64aPP5J+58aJyGfRrQa/uFh8a9mcK68mLfJOYq+ZSxQy/UN3McafJ2ILAy7IWzT9kRw==} engines: {node: '>=20.0.0'} @@ -2386,6 +2483,10 @@ packages: resolution: {integrity: sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==} engines: {node: '>=20.0.0'} + '@aws-sdk/types@3.973.5': + resolution: {integrity: sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/util-arn-parser@3.972.2': resolution: {integrity: sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==} engines: {node: '>=20.0.0'} @@ -2394,6 +2495,14 @@ packages: resolution: {integrity: sha512-HuXu4boeUWU0DQiLslbgdvuQ4ZMCo4Lsk97w8BIUokql2o9MvjE5dwqI5pzGt0K7afO1FybjidUQVTMLuZNTOA==} engines: {node: '>=20.0.0'} + '@aws-sdk/util-endpoints@3.996.4': + resolution: {integrity: sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-format-url@3.972.7': + resolution: {integrity: sha512-V+PbnWfUl93GuFwsOHsAq7hY/fnm9kElRqR8IexIJr5Rvif9e614X5sGSyz3mVSf1YAZ+VTy63W1/pGdA55zyA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/util-locate-window@3.965.4': resolution: {integrity: sha512-H1onv5SkgPBK2P6JR2MjGgbOnttoNzSPIRoeZTNPZYyaplwGg50zS3amXvXqF0/qfXpWEC9rLWU564QTB9bSog==} engines: {node: '>=20.0.0'} @@ -2401,6 +2510,9 @@ packages: '@aws-sdk/util-user-agent-browser@3.972.3': resolution: {integrity: sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==} + '@aws-sdk/util-user-agent-browser@3.972.7': + resolution: {integrity: sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw==} + '@aws-sdk/util-user-agent-node@3.972.6': resolution: {integrity: sha512-966xH8TPqkqOXP7EwnEThcKKz0SNP9kVJBKd9M8bNXE4GSqVouMKKnFBwYnzbWVKuLXubzX5seokcX4a0JLJIA==} engines: {node: '>=20.0.0'} @@ -2410,6 +2522,19 @@ packages: aws-crt: optional: true + '@aws-sdk/util-user-agent-node@3.973.5': + resolution: {integrity: sha512-Dyy38O4GeMk7UQ48RupfHif//gqnOPbq/zlvRssc11E2mClT+aUfc3VS2yD8oLtzqO3RsqQ9I3gOBB4/+HjPOw==} + engines: {node: '>=20.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + + '@aws-sdk/xml-builder@3.972.10': + resolution: {integrity: sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA==} + engines: {node: '>=20.0.0'} + '@aws-sdk/xml-builder@3.972.4': resolution: {integrity: sha512-0zJ05ANfYqI6+rGqj8samZBFod0dPPousBjLEqg8WdxSgbMAkRgLyn81lP215Do0rFJ/17LIXwr7q0yK24mP6Q==} engines: {node: '>=20.0.0'} @@ -6243,6 +6368,10 @@ packages: resolution: {integrity: sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==} engines: {node: '>=12'} + '@smithy/abort-controller@4.2.11': + resolution: {integrity: sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ==} + engines: {node: '>=18.0.0'} + '@smithy/abort-controller@4.2.8': resolution: {integrity: sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==} engines: {node: '>=18.0.0'} @@ -6255,6 +6384,10 @@ packages: resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==} engines: {node: '>=18.0.0'} + '@smithy/config-resolver@4.4.10': + resolution: {integrity: sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg==} + engines: {node: '>=18.0.0'} + '@smithy/config-resolver@4.4.6': resolution: {integrity: sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==} engines: {node: '>=18.0.0'} @@ -6263,30 +6396,62 @@ packages: resolution: {integrity: sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg==} engines: {node: '>=18.0.0'} + '@smithy/core@3.23.9': + resolution: {integrity: sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.2.11': + resolution: {integrity: sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g==} + engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.2.8': resolution: {integrity: sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==} engines: {node: '>=18.0.0'} + '@smithy/eventstream-codec@4.2.11': + resolution: {integrity: sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-codec@4.2.8': resolution: {integrity: sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==} engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-browser@4.2.11': + resolution: {integrity: sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-browser@4.2.8': resolution: {integrity: sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw==} engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-config-resolver@4.3.11': + resolution: {integrity: sha512-XeNIA8tcP/GDWnnKkO7qEm/bg0B/bP9lvIXZBXcGZwZ+VYM8h8k9wuDvUODtdQ2Wcp2RcBkPTCSMmaniVHrMlA==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-config-resolver@4.3.8': resolution: {integrity: sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ==} engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-node@4.2.11': + resolution: {integrity: sha512-fzbCh18rscBDTQSCrsp1fGcclLNF//nJyhjldsEl/5wCYmgpHblv5JSppQAyQI24lClsFT0wV06N1Porn0IsEw==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-node@4.2.8': resolution: {integrity: sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A==} engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-universal@4.2.11': + resolution: {integrity: sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-serde-universal@4.2.8': resolution: {integrity: sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ==} engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@5.3.13': + resolution: {integrity: sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ==} + engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@5.3.9': resolution: {integrity: sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==} engines: {node: '>=18.0.0'} @@ -6295,6 +6460,10 @@ packages: resolution: {integrity: sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg==} engines: {node: '>=18.0.0'} + '@smithy/hash-node@4.2.11': + resolution: {integrity: sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A==} + engines: {node: '>=18.0.0'} + '@smithy/hash-node@4.2.8': resolution: {integrity: sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==} engines: {node: '>=18.0.0'} @@ -6303,6 +6472,10 @@ packages: resolution: {integrity: sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w==} engines: {node: '>=18.0.0'} + '@smithy/invalid-dependency@4.2.11': + resolution: {integrity: sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g==} + engines: {node: '>=18.0.0'} + '@smithy/invalid-dependency@4.2.8': resolution: {integrity: sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==} engines: {node: '>=18.0.0'} @@ -6315,10 +6488,18 @@ packages: resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} + '@smithy/is-array-buffer@4.2.2': + resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} + engines: {node: '>=18.0.0'} + '@smithy/md5-js@4.2.8': resolution: {integrity: sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==} engines: {node: '>=18.0.0'} + '@smithy/middleware-content-length@4.2.11': + resolution: {integrity: sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-content-length@4.2.8': resolution: {integrity: sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==} engines: {node: '>=18.0.0'} @@ -6327,18 +6508,38 @@ packages: resolution: {integrity: sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag==} engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@4.4.23': + resolution: {integrity: sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.31': resolution: {integrity: sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg==} engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.40': + resolution: {integrity: sha512-YhEMakG1Ae57FajERdHNZ4ShOPIY7DsgV+ZoAxo/5BT0KIe+f6DDU2rtIymNNFIj22NJfeeI6LWIifrwM0f+rA==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-serde@4.2.12': + resolution: {integrity: sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@4.2.9': resolution: {integrity: sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==} engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.2.11': + resolution: {integrity: sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.2.8': resolution: {integrity: sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==} engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.3.11': + resolution: {integrity: sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg==} + engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.3.8': resolution: {integrity: sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==} engines: {node: '>=18.0.0'} @@ -6347,22 +6548,46 @@ packages: resolution: {integrity: sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA==} engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.4.14': + resolution: {integrity: sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A==} + engines: {node: '>=18.0.0'} + + '@smithy/property-provider@4.2.11': + resolution: {integrity: sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg==} + engines: {node: '>=18.0.0'} + '@smithy/property-provider@4.2.8': resolution: {integrity: sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==} engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.3.11': + resolution: {integrity: sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ==} + engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.3.8': resolution: {integrity: sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==} engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.2.11': + resolution: {integrity: sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.2.8': resolution: {integrity: sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==} engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.2.11': + resolution: {integrity: sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.2.8': resolution: {integrity: sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==} engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@4.2.11': + resolution: {integrity: sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw==} + engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@4.2.8': resolution: {integrity: sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==} engines: {node: '>=18.0.0'} @@ -6371,6 +6596,14 @@ packages: resolution: {integrity: sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==} engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.4.6': + resolution: {integrity: sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.3.11': + resolution: {integrity: sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ==} + engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.3.8': resolution: {integrity: sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==} engines: {node: '>=18.0.0'} @@ -6379,10 +6612,22 @@ packages: resolution: {integrity: sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg==} engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.12.3': + resolution: {integrity: sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw==} + engines: {node: '>=18.0.0'} + '@smithy/types@4.12.0': resolution: {integrity: sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==} engines: {node: '>=18.0.0'} + '@smithy/types@4.13.0': + resolution: {integrity: sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==} + engines: {node: '>=18.0.0'} + + '@smithy/url-parser@4.2.11': + resolution: {integrity: sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing==} + engines: {node: '>=18.0.0'} + '@smithy/url-parser@4.2.8': resolution: {integrity: sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==} engines: {node: '>=18.0.0'} @@ -6391,14 +6636,26 @@ packages: resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} engines: {node: '>=18.0.0'} + '@smithy/util-base64@4.3.2': + resolution: {integrity: sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.2.0': resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.2.2': + resolution: {integrity: sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.2.1': resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.2.3': + resolution: {integrity: sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==} + engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} @@ -6407,30 +6664,62 @@ packages: resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@4.2.2': + resolution: {integrity: sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==} + engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.2.0': resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.2.2': + resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.30': resolution: {integrity: sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.39': + resolution: {integrity: sha512-ui7/Ho/+VHqS7Km2wBw4/Ab4RktoiSshgcgpJzC4keFPs6tLJS4IQwbeahxQS3E/w98uq6E1mirCH/id9xIXeQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.33': resolution: {integrity: sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.42': + resolution: {integrity: sha512-QDA84CWNe8Akpj15ofLO+1N3Rfg8qa2K5uX0y6HnOp4AnRYRgWrKx/xzbYNbVF9ZsyJUYOfcoaN3y93wA/QJ2A==} + engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.2.8': resolution: {integrity: sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==} engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.3.2': + resolution: {integrity: sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA==} + engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.2.0': resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.2.2': + resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} + engines: {node: '>=18.0.0'} + + '@smithy/util-middleware@4.2.11': + resolution: {integrity: sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw==} + engines: {node: '>=18.0.0'} + '@smithy/util-middleware@4.2.8': resolution: {integrity: sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==} engines: {node: '>=18.0.0'} + '@smithy/util-retry@4.2.11': + resolution: {integrity: sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw==} + engines: {node: '>=18.0.0'} + '@smithy/util-retry@4.2.8': resolution: {integrity: sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==} engines: {node: '>=18.0.0'} @@ -6439,10 +6728,18 @@ packages: resolution: {integrity: sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg==} engines: {node: '>=18.0.0'} + '@smithy/util-stream@4.5.17': + resolution: {integrity: sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@4.2.0': resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@4.2.2': + resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} + engines: {node: '>=18.0.0'} + '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} @@ -6451,6 +6748,10 @@ packages: resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} engines: {node: '>=18.0.0'} + '@smithy/util-utf8@4.2.2': + resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} + engines: {node: '>=18.0.0'} + '@smithy/util-waiter@4.2.8': resolution: {integrity: sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==} engines: {node: '>=18.0.0'} @@ -6459,6 +6760,10 @@ packages: resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} engines: {node: '>=18.0.0'} + '@smithy/uuid@1.1.2': + resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} + engines: {node: '>=18.0.0'} + '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} @@ -6549,33 +6854,66 @@ packages: os: [darwin] hasBin: true + '@superdoc-dev/sdk-darwin-arm64@1.0.0-alpha.44': + resolution: {integrity: sha512-huXcCxZN9e7cx5rlzAaImMOprywt1xhvtUNugUuqis58+VGPlp0b7OTwAsQuAAq1idvjrXj1C0uUOu5VB4HNmQ==} + cpu: [arm64] + os: [darwin] + hasBin: true + '@superdoc-dev/sdk-darwin-x64@1.0.0-alpha.39': resolution: {integrity: sha512-denq7/8dMyakOKr1hbAz77D1K/itlNV1xBya5IYBLhsAwgvj2IC4WGma+bVGkwsvLEIjViYqUxPhQARv2gUjFA==} cpu: [x64] os: [darwin] hasBin: true + '@superdoc-dev/sdk-darwin-x64@1.0.0-alpha.44': + resolution: {integrity: sha512-X1UEFFwx0EsPkgSV0X1Oyol6aCMwfgvLanyNXU6zL6hfd9HM62+zTQXtMo3z5jTRpqRfW0egDWnIz3wxbta/AA==} + cpu: [x64] + os: [darwin] + hasBin: true + '@superdoc-dev/sdk-linux-arm64@1.0.0-alpha.39': resolution: {integrity: sha512-Lq0qtcR1HXmuhr+/jTu09R2VMflUCvKep4veRtbBxQJXOYCE1M6YDHkHze4Y+6vRyzMI9G2duUuEFjKUoDs1Dg==} cpu: [arm64] os: [linux] hasBin: true + '@superdoc-dev/sdk-linux-arm64@1.0.0-alpha.44': + resolution: {integrity: sha512-R0r6AzR32wBGaGOdI7BQa3Zv+f/cE36CV9Himz+u98XlxAjU/O//MYOiYBbosauLPcZAEJ0LfeZAL2k7QweYSQ==} + cpu: [arm64] + os: [linux] + hasBin: true + '@superdoc-dev/sdk-linux-x64@1.0.0-alpha.39': resolution: {integrity: sha512-HTTiFrEM950JcR3KAM2tmuOAEnhStWLnwI2J3a3NeJquiZKkiwOSvb9dHG8ZD72dSnMKX2h/HCBulJJy7zF0bg==} cpu: [x64] os: [linux] hasBin: true + '@superdoc-dev/sdk-linux-x64@1.0.0-alpha.44': + resolution: {integrity: sha512-MSksa8M4Kmaum4YatdMVOAFNT/0YGwiy9R64O6t5w0p1WoJYyt9YOjBqrdab7nwNmJI6bTYq+BxC89IMtEic9A==} + cpu: [x64] + os: [linux] + hasBin: true + '@superdoc-dev/sdk-windows-x64@1.0.0-alpha.39': resolution: {integrity: sha512-CHlFWa/bPRnZN+JDe3i0As2tszsMX+QSk5eorISEJJ2JyxqCLnFjVDgHkQoS6Zq65EaO1q1jg+gqqyEucIU1jA==} cpu: [x64] os: [win32] hasBin: true + '@superdoc-dev/sdk-windows-x64@1.0.0-alpha.44': + resolution: {integrity: sha512-b1yD0uy4FxI61XTU1eIdQX53nFcAidLmlGI61qO1SQb9Y7g5Lez5rU5VWiu/Q7IRErT2YssVifR3dr+T2yC3KA==} + cpu: [x64] + os: [win32] + hasBin: true + '@superdoc-dev/sdk@1.0.0-alpha.39': resolution: {integrity: sha512-jkrEWx+qIntA8WtXu7a4Ht+S+ueJzQAOhSC+ybGoaaBAt2Lnip4yGmTG4Nqww6dvdqykIX4x665fV8vfJHMtHA==} + '@superdoc-dev/sdk@1.0.0-alpha.44': + resolution: {integrity: sha512-Ahb2mwucrRRdU+3gFfHZQZNnPPseiVTiJs7YIsE8yo1/a3u7Pb2lXDOhMfOhVGfG3ZXuwPsOcx6g38qXwog2eA==} + '@superdoc-dev/sdk@file:packages/sdk/langs/node': resolution: {directory: packages/sdk/langs/node, type: directory} @@ -9756,10 +10094,17 @@ packages: fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-xml-builder@1.1.2: + resolution: {integrity: sha512-NJAmiuVaJEjVa7TjLZKlYd7RqmzOC91EtPFXHvlTcqBVo50Qh7XV5IwvXi1c7NRz2Q/majGX9YLcwJtWgHjtkA==} + fast-xml-parser@5.3.4: resolution: {integrity: sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==} hasBin: true + fast-xml-parser@5.4.1: + resolution: {integrity: sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==} + hasBin: true + fastify-plugin@5.1.0: resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} @@ -13092,6 +13437,10 @@ packages: resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-expression-matcher@1.1.3: + resolution: {integrity: sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==} + engines: {node: '>=14.0.0'} + path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -16907,7 +17256,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 + '@aws-sdk/types': 3.973.5 '@aws-sdk/util-locate-window': 3.965.4 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -16915,7 +17264,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 + '@aws-sdk/types': 3.973.5 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -16928,6 +17277,58 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 + '@aws-sdk/client-bedrock-runtime@3.1007.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.19 + '@aws-sdk/credential-provider-node': 3.972.19 + '@aws-sdk/eventstream-handler-node': 3.972.10 + '@aws-sdk/middleware-eventstream': 3.972.7 + '@aws-sdk/middleware-host-header': 3.972.7 + '@aws-sdk/middleware-logger': 3.972.7 + '@aws-sdk/middleware-recursion-detection': 3.972.7 + '@aws-sdk/middleware-user-agent': 3.972.20 + '@aws-sdk/middleware-websocket': 3.972.12 + '@aws-sdk/region-config-resolver': 3.972.7 + '@aws-sdk/token-providers': 3.1007.0 + '@aws-sdk/types': 3.973.5 + '@aws-sdk/util-endpoints': 3.996.4 + '@aws-sdk/util-user-agent-browser': 3.972.7 + '@aws-sdk/util-user-agent-node': 3.973.5 + '@smithy/config-resolver': 4.4.10 + '@smithy/core': 3.23.9 + '@smithy/eventstream-serde-browser': 4.2.11 + '@smithy/eventstream-serde-config-resolver': 4.3.11 + '@smithy/eventstream-serde-node': 4.2.11 + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/hash-node': 4.2.11 + '@smithy/invalid-dependency': 4.2.11 + '@smithy/middleware-content-length': 4.2.11 + '@smithy/middleware-endpoint': 4.4.23 + '@smithy/middleware-retry': 4.4.40 + '@smithy/middleware-serde': 4.2.12 + '@smithy/middleware-stack': 4.2.11 + '@smithy/node-config-provider': 4.3.11 + '@smithy/node-http-handler': 4.4.14 + '@smithy/protocol-http': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.39 + '@smithy/util-defaults-mode-node': 4.2.42 + '@smithy/util-endpoints': 3.3.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-retry': 4.2.11 + '@smithy/util-stream': 4.5.17 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/client-s3@3.988.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 @@ -17031,6 +17432,22 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/core@3.973.19': + dependencies: + '@aws-sdk/types': 3.973.5 + '@aws-sdk/xml-builder': 3.972.10 + '@smithy/core': 3.23.9 + '@smithy/node-config-provider': 4.3.11 + '@smithy/property-provider': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/signature-v4': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@aws-sdk/core@3.973.8': dependencies: '@aws-sdk/types': 3.973.1 @@ -17052,6 +17469,14 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-env@3.972.17': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/credential-provider-env@3.972.6': dependencies: '@aws-sdk/core': 3.973.8 @@ -17060,6 +17485,19 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-http@3.972.19': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/types': 3.973.5 + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/node-http-handler': 4.4.14 + '@smithy/property-provider': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/util-stream': 4.5.17 + tslib: 2.8.1 + '@aws-sdk/credential-provider-http@3.972.8': dependencies: '@aws-sdk/core': 3.973.8 @@ -17073,6 +17511,25 @@ snapshots: '@smithy/util-stream': 4.5.12 tslib: 2.8.1 + '@aws-sdk/credential-provider-ini@3.972.18': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/credential-provider-env': 3.972.17 + '@aws-sdk/credential-provider-http': 3.972.19 + '@aws-sdk/credential-provider-login': 3.972.18 + '@aws-sdk/credential-provider-process': 3.972.17 + '@aws-sdk/credential-provider-sso': 3.972.18 + '@aws-sdk/credential-provider-web-identity': 3.972.18 + '@aws-sdk/nested-clients': 3.996.8 + '@aws-sdk/types': 3.973.5 + '@smithy/credential-provider-imds': 4.2.11 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-ini@3.972.6': dependencies: '@aws-sdk/core': 3.973.8 @@ -17092,6 +17549,19 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-login@3.972.18': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/nested-clients': 3.996.8 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-login@3.972.6': dependencies: '@aws-sdk/core': 3.973.8 @@ -17105,6 +17575,23 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-node@3.972.19': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.17 + '@aws-sdk/credential-provider-http': 3.972.19 + '@aws-sdk/credential-provider-ini': 3.972.18 + '@aws-sdk/credential-provider-process': 3.972.17 + '@aws-sdk/credential-provider-sso': 3.972.18 + '@aws-sdk/credential-provider-web-identity': 3.972.18 + '@aws-sdk/types': 3.973.5 + '@smithy/credential-provider-imds': 4.2.11 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-node@3.972.7': dependencies: '@aws-sdk/credential-provider-env': 3.972.6 @@ -17122,6 +17609,15 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-process@3.972.17': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/credential-provider-process@3.972.6': dependencies: '@aws-sdk/core': 3.973.8 @@ -17131,6 +17627,19 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/credential-provider-sso@3.972.18': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/nested-clients': 3.996.8 + '@aws-sdk/token-providers': 3.1005.0 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-sso@3.972.6': dependencies: '@aws-sdk/client-sso': 3.988.0 @@ -17144,6 +17653,18 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/credential-provider-web-identity@3.972.18': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/nested-clients': 3.996.8 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/credential-provider-web-identity@3.972.6': dependencies: '@aws-sdk/core': 3.973.8 @@ -17156,6 +17677,13 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/eventstream-handler-node@3.972.10': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/eventstream-codec': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-bucket-endpoint@3.972.3': dependencies: '@aws-sdk/types': 3.973.1 @@ -17166,6 +17694,13 @@ snapshots: '@smithy/util-config-provider': 4.2.0 tslib: 2.8.1 + '@aws-sdk/middleware-eventstream@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-expect-continue@3.972.3': dependencies: '@aws-sdk/types': 3.973.1 @@ -17197,6 +17732,13 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/middleware-host-header@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-location-constraint@3.972.3': dependencies: '@aws-sdk/types': 3.973.1 @@ -17209,6 +17751,12 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/middleware-logger@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.972.3': dependencies: '@aws-sdk/types': 3.973.1 @@ -17217,6 +17765,14 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@aws/lambda-invoke-store': 0.2.3 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/middleware-sdk-s3@3.972.8': dependencies: '@aws-sdk/core': 3.973.8 @@ -17240,6 +17796,17 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/middleware-user-agent@3.972.20': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/types': 3.973.5 + '@aws-sdk/util-endpoints': 3.996.4 + '@smithy/core': 3.23.9 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-retry': 4.2.11 + tslib: 2.8.1 + '@aws-sdk/middleware-user-agent@3.972.8': dependencies: '@aws-sdk/core': 3.973.8 @@ -17250,6 +17817,21 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/middleware-websocket@3.972.12': + dependencies: + '@aws-sdk/types': 3.973.5 + '@aws-sdk/util-format-url': 3.972.7 + '@smithy/eventstream-codec': 4.2.11 + '@smithy/eventstream-serde-browser': 4.2.11 + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/protocol-http': 5.3.11 + '@smithy/signature-v4': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@aws-sdk/nested-clients@3.988.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 @@ -17293,6 +17875,49 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/nested-clients@3.996.8': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.19 + '@aws-sdk/middleware-host-header': 3.972.7 + '@aws-sdk/middleware-logger': 3.972.7 + '@aws-sdk/middleware-recursion-detection': 3.972.7 + '@aws-sdk/middleware-user-agent': 3.972.20 + '@aws-sdk/region-config-resolver': 3.972.7 + '@aws-sdk/types': 3.973.5 + '@aws-sdk/util-endpoints': 3.996.4 + '@aws-sdk/util-user-agent-browser': 3.972.7 + '@aws-sdk/util-user-agent-node': 3.973.5 + '@smithy/config-resolver': 4.4.10 + '@smithy/core': 3.23.9 + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/hash-node': 4.2.11 + '@smithy/invalid-dependency': 4.2.11 + '@smithy/middleware-content-length': 4.2.11 + '@smithy/middleware-endpoint': 4.4.23 + '@smithy/middleware-retry': 4.4.40 + '@smithy/middleware-serde': 4.2.12 + '@smithy/middleware-stack': 4.2.11 + '@smithy/node-config-provider': 4.3.11 + '@smithy/node-http-handler': 4.4.14 + '@smithy/protocol-http': 5.3.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.39 + '@smithy/util-defaults-mode-node': 4.2.42 + '@smithy/util-endpoints': 3.3.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-retry': 4.2.11 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/region-config-resolver@3.972.3': dependencies: '@aws-sdk/types': 3.973.1 @@ -17301,6 +17926,14 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/region-config-resolver@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/config-resolver': 4.4.10 + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/signature-v4-multi-region@3.988.0': dependencies: '@aws-sdk/middleware-sdk-s3': 3.972.8 @@ -17310,6 +17943,30 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/token-providers@3.1005.0': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/nested-clients': 3.996.8 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/token-providers@3.1007.0': + dependencies: + '@aws-sdk/core': 3.973.19 + '@aws-sdk/nested-clients': 3.996.8 + '@aws-sdk/types': 3.973.5 + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/token-providers@3.988.0': dependencies: '@aws-sdk/core': 3.973.8 @@ -17327,6 +17984,11 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/types@3.973.5': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/util-arn-parser@3.972.2': dependencies: tslib: 2.8.1 @@ -17339,6 +18001,21 @@ snapshots: '@smithy/util-endpoints': 3.2.8 tslib: 2.8.1 + '@aws-sdk/util-endpoints@3.996.4': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-endpoints': 3.3.2 + tslib: 2.8.1 + + '@aws-sdk/util-format-url@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/querystring-builder': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@aws-sdk/util-locate-window@3.965.4': dependencies: tslib: 2.8.1 @@ -17350,6 +18027,13 @@ snapshots: bowser: 2.14.1 tslib: 2.8.1 + '@aws-sdk/util-user-agent-browser@3.972.7': + dependencies: + '@aws-sdk/types': 3.973.5 + '@smithy/types': 4.13.0 + bowser: 2.14.1 + tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.972.6': dependencies: '@aws-sdk/middleware-user-agent': 3.972.8 @@ -17358,6 +18042,20 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.973.5': + dependencies: + '@aws-sdk/middleware-user-agent': 3.972.20 + '@aws-sdk/types': 3.973.5 + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.10': + dependencies: + '@smithy/types': 4.13.0 + fast-xml-parser: 5.4.1 + tslib: 2.8.1 + '@aws-sdk/xml-builder@3.972.4': dependencies: '@smithy/types': 4.12.0 @@ -21603,6 +22301,11 @@ snapshots: dependencies: escape-string-regexp: 5.0.0 + '@smithy/abort-controller@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/abort-controller@4.2.8': dependencies: '@smithy/types': 4.12.0 @@ -21617,6 +22320,15 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/config-resolver@4.4.10': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-endpoints': 3.3.2 + '@smithy/util-middleware': 4.2.11 + tslib: 2.8.1 + '@smithy/config-resolver@4.4.6': dependencies: '@smithy/node-config-provider': 4.3.8 @@ -21639,6 +22351,27 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 + '@smithy/core@3.23.9': + dependencies: + '@smithy/middleware-serde': 4.2.12 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-stream': 4.5.17 + '@smithy/util-utf8': 4.2.2 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.2.11': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/property-provider': 4.2.11 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + tslib: 2.8.1 + '@smithy/credential-provider-imds@4.2.8': dependencies: '@smithy/node-config-provider': 4.3.8 @@ -21647,6 +22380,13 @@ snapshots: '@smithy/url-parser': 4.2.8 tslib: 2.8.1 + '@smithy/eventstream-codec@4.2.11': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.13.0 + '@smithy/util-hex-encoding': 4.2.2 + tslib: 2.8.1 + '@smithy/eventstream-codec@4.2.8': dependencies: '@aws-crypto/crc32': 5.2.0 @@ -21654,29 +22394,60 @@ snapshots: '@smithy/util-hex-encoding': 4.2.0 tslib: 2.8.1 + '@smithy/eventstream-serde-browser@4.2.11': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-browser@4.2.8': dependencies: '@smithy/eventstream-serde-universal': 4.2.8 '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/eventstream-serde-config-resolver@4.3.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-config-resolver@4.3.8': dependencies: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/eventstream-serde-node@4.2.11': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-node@4.2.8': dependencies: '@smithy/eventstream-serde-universal': 4.2.8 '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/eventstream-serde-universal@4.2.11': + dependencies: + '@smithy/eventstream-codec': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/eventstream-serde-universal@4.2.8': dependencies: '@smithy/eventstream-codec': 4.2.8 '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/fetch-http-handler@5.3.13': + dependencies: + '@smithy/protocol-http': 5.3.11 + '@smithy/querystring-builder': 4.2.11 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + tslib: 2.8.1 + '@smithy/fetch-http-handler@5.3.9': dependencies: '@smithy/protocol-http': 5.3.8 @@ -21692,6 +22463,13 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/hash-node@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/hash-node@4.2.8': dependencies: '@smithy/types': 4.12.0 @@ -21705,6 +22483,11 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@smithy/invalid-dependency@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/invalid-dependency@4.2.8': dependencies: '@smithy/types': 4.12.0 @@ -21718,12 +22501,22 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/is-array-buffer@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/md5-js@4.2.8': dependencies: '@smithy/types': 4.12.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@smithy/middleware-content-length@4.2.11': + dependencies: + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/middleware-content-length@4.2.8': dependencies: '@smithy/protocol-http': 5.3.8 @@ -21741,6 +22534,17 @@ snapshots: '@smithy/util-middleware': 4.2.8 tslib: 2.8.1 + '@smithy/middleware-endpoint@4.4.23': + dependencies: + '@smithy/core': 3.23.9 + '@smithy/middleware-serde': 4.2.12 + '@smithy/node-config-provider': 4.3.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + '@smithy/url-parser': 4.2.11 + '@smithy/util-middleware': 4.2.11 + tslib: 2.8.1 + '@smithy/middleware-retry@4.4.31': dependencies: '@smithy/node-config-provider': 4.3.8 @@ -21753,17 +22557,47 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 + '@smithy/middleware-retry@4.4.40': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/service-error-classification': 4.2.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-retry': 4.2.11 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.2.12': + dependencies: + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/middleware-serde@4.2.9': dependencies: '@smithy/protocol-http': 5.3.8 '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/middleware-stack@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/middleware-stack@4.2.8': dependencies: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/node-config-provider@4.3.11': + dependencies: + '@smithy/property-provider': 4.2.11 + '@smithy/shared-ini-file-loader': 4.4.6 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/node-config-provider@4.3.8': dependencies: '@smithy/property-provider': 4.2.8 @@ -21779,27 +22613,60 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/node-http-handler@4.4.14': + dependencies: + '@smithy/abort-controller': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/querystring-builder': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + + '@smithy/property-provider@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/property-provider@4.2.8': dependencies: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/protocol-http@5.3.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/protocol-http@5.3.8': dependencies: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/querystring-builder@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + '@smithy/util-uri-escape': 4.2.2 + tslib: 2.8.1 + '@smithy/querystring-builder@4.2.8': dependencies: '@smithy/types': 4.12.0 '@smithy/util-uri-escape': 4.2.0 tslib: 2.8.1 + '@smithy/querystring-parser@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/querystring-parser@4.2.8': dependencies: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/service-error-classification@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + '@smithy/service-error-classification@4.2.8': dependencies: '@smithy/types': 4.12.0 @@ -21809,6 +22676,22 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/shared-ini-file-loader@4.4.6': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + + '@smithy/signature-v4@5.3.11': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-middleware': 4.2.11 + '@smithy/util-uri-escape': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/signature-v4@5.3.8': dependencies: '@smithy/is-array-buffer': 4.2.0 @@ -21830,10 +22713,30 @@ snapshots: '@smithy/util-stream': 4.5.12 tslib: 2.8.1 + '@smithy/smithy-client@4.12.3': + dependencies: + '@smithy/core': 3.23.9 + '@smithy/middleware-endpoint': 4.4.23 + '@smithy/middleware-stack': 4.2.11 + '@smithy/protocol-http': 5.3.11 + '@smithy/types': 4.13.0 + '@smithy/util-stream': 4.5.17 + tslib: 2.8.1 + '@smithy/types@4.12.0': dependencies: tslib: 2.8.1 + '@smithy/types@4.13.0': + dependencies: + tslib: 2.8.1 + + '@smithy/url-parser@4.2.11': + dependencies: + '@smithy/querystring-parser': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/url-parser@4.2.8': dependencies: '@smithy/querystring-parser': 4.2.8 @@ -21846,14 +22749,28 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@smithy/util-base64@4.3.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/util-body-length-browser@4.2.0': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-browser@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-body-length-node@4.2.1': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-node@4.2.3': + dependencies: + tslib: 2.8.1 + '@smithy/util-buffer-from@2.2.0': dependencies: '@smithy/is-array-buffer': 2.2.0 @@ -21864,10 +22781,19 @@ snapshots: '@smithy/is-array-buffer': 4.2.0 tslib: 2.8.1 + '@smithy/util-buffer-from@4.2.2': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + tslib: 2.8.1 + '@smithy/util-config-provider@4.2.0': dependencies: tslib: 2.8.1 + '@smithy/util-config-provider@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.30': dependencies: '@smithy/property-provider': 4.2.8 @@ -21875,6 +22801,13 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.39': + dependencies: + '@smithy/property-provider': 4.2.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.33': dependencies: '@smithy/config-resolver': 4.4.6 @@ -21885,21 +22818,52 @@ snapshots: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.42': + dependencies: + '@smithy/config-resolver': 4.4.10 + '@smithy/credential-provider-imds': 4.2.11 + '@smithy/node-config-provider': 4.3.11 + '@smithy/property-provider': 4.2.11 + '@smithy/smithy-client': 4.12.3 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-endpoints@3.2.8': dependencies: '@smithy/node-config-provider': 4.3.8 '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/util-endpoints@3.3.2': + dependencies: + '@smithy/node-config-provider': 4.3.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-hex-encoding@4.2.0': dependencies: tslib: 2.8.1 + '@smithy/util-hex-encoding@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-middleware@4.2.11': + dependencies: + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-middleware@4.2.8': dependencies: '@smithy/types': 4.12.0 tslib: 2.8.1 + '@smithy/util-retry@4.2.11': + dependencies: + '@smithy/service-error-classification': 4.2.11 + '@smithy/types': 4.13.0 + tslib: 2.8.1 + '@smithy/util-retry@4.2.8': dependencies: '@smithy/service-error-classification': 4.2.8 @@ -21917,10 +22881,25 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@smithy/util-stream@4.5.17': + dependencies: + '@smithy/fetch-http-handler': 5.3.13 + '@smithy/node-http-handler': 4.4.14 + '@smithy/types': 4.13.0 + '@smithy/util-base64': 4.3.2 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/util-uri-escape@4.2.0': dependencies: tslib: 2.8.1 + '@smithy/util-uri-escape@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-utf8@2.3.0': dependencies: '@smithy/util-buffer-from': 2.2.0 @@ -21931,6 +22910,11 @@ snapshots: '@smithy/util-buffer-from': 4.2.0 tslib: 2.8.1 + '@smithy/util-utf8@4.2.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + tslib: 2.8.1 + '@smithy/util-waiter@4.2.8': dependencies: '@smithy/abort-controller': 4.2.8 @@ -21941,6 +22925,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/uuid@1.1.2': + dependencies: + tslib: 2.8.1 + '@socket.io/component-emitter@3.1.2': {} '@speed-highlight/core@1.2.14': {} @@ -22127,18 +23115,33 @@ snapshots: '@superdoc-dev/sdk-darwin-arm64@1.0.0-alpha.39': optional: true + '@superdoc-dev/sdk-darwin-arm64@1.0.0-alpha.44': + optional: true + '@superdoc-dev/sdk-darwin-x64@1.0.0-alpha.39': optional: true + '@superdoc-dev/sdk-darwin-x64@1.0.0-alpha.44': + optional: true + '@superdoc-dev/sdk-linux-arm64@1.0.0-alpha.39': optional: true + '@superdoc-dev/sdk-linux-arm64@1.0.0-alpha.44': + optional: true + '@superdoc-dev/sdk-linux-x64@1.0.0-alpha.39': optional: true + '@superdoc-dev/sdk-linux-x64@1.0.0-alpha.44': + optional: true + '@superdoc-dev/sdk-windows-x64@1.0.0-alpha.39': optional: true + '@superdoc-dev/sdk-windows-x64@1.0.0-alpha.44': + optional: true + '@superdoc-dev/sdk@1.0.0-alpha.39': optionalDependencies: '@superdoc-dev/sdk-darwin-arm64': 1.0.0-alpha.39 @@ -22147,6 +23150,14 @@ snapshots: '@superdoc-dev/sdk-linux-x64': 1.0.0-alpha.39 '@superdoc-dev/sdk-windows-x64': 1.0.0-alpha.39 + '@superdoc-dev/sdk@1.0.0-alpha.44': + optionalDependencies: + '@superdoc-dev/sdk-darwin-arm64': 1.0.0-alpha.44 + '@superdoc-dev/sdk-darwin-x64': 1.0.0-alpha.44 + '@superdoc-dev/sdk-linux-arm64': 1.0.0-alpha.44 + '@superdoc-dev/sdk-linux-x64': 1.0.0-alpha.44 + '@superdoc-dev/sdk-windows-x64': 1.0.0-alpha.44 + '@superdoc-dev/sdk@file:packages/sdk/langs/node': optionalDependencies: '@superdoc-dev/sdk-darwin-arm64': link:packages/sdk/langs/node/platforms/sdk-darwin-arm64 @@ -26197,10 +27208,19 @@ snapshots: fast-uri@3.1.0: {} + fast-xml-builder@1.1.2: + dependencies: + path-expression-matcher: 1.1.3 + fast-xml-parser@5.3.4: dependencies: strnum: 2.1.2 + fast-xml-parser@5.4.1: + dependencies: + fast-xml-builder: 1.1.2 + strnum: 2.1.2 + fastify-plugin@5.1.0: {} fastify@5.8.2: @@ -30570,6 +31590,8 @@ snapshots: path-exists@5.0.0: {} + path-expression-matcher@1.1.3: {} + path-is-absolute@1.0.1: {} path-is-inside@1.0.2: {} From d478c73795348c9df89077cc0abdcb4ab0fe139d Mon Sep 17 00:00:00 2001 From: Luccas Correa Date: Thu, 12 Mar 2026 11:09:41 -0300 Subject: [PATCH 125/125] test: add missing test documents --- .../src/tests/data/diffing/diff_after16.docx | Bin 0 -> 15124 bytes .../src/tests/data/diffing/diff_before16.docx | Bin 0 -> 14678 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/super-editor/src/tests/data/diffing/diff_after16.docx create mode 100644 packages/super-editor/src/tests/data/diffing/diff_before16.docx diff --git a/packages/super-editor/src/tests/data/diffing/diff_after16.docx b/packages/super-editor/src/tests/data/diffing/diff_after16.docx new file mode 100644 index 0000000000000000000000000000000000000000..c8f01b4df0c341c9c0dcaa10c50640c897e18976 GIT binary patch literal 15124 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 literal 0 HcmV?d00001