From 16c177341ba1c9163f890fb9128e4f0fe57040e1 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:23:28 +0800 Subject: [PATCH 01/18] Migrate fuzz tests to Vitest --- _develop/webpack.config.js | 1 - package.json | 3 +++ test/fuzz.ts | 2 -- test/fuzz/{ => __helpers__}/utils.ts | 0 test/fuzz/{editor.test.ts => editor.spec.ts} | 9 +++++---- test/fuzz/{tableEmbed.test.ts => tableEmbed.spec.ts} | 6 ++++-- test/fuzz/vitest.config.ts | 11 +++++++++++ 7 files changed, 23 insertions(+), 9 deletions(-) delete mode 100644 test/fuzz.ts rename test/fuzz/{ => __helpers__}/utils.ts (100%) rename test/fuzz/{editor.test.ts => editor.spec.ts} (96%) rename test/fuzz/{tableEmbed.test.ts => tableEmbed.spec.ts} (96%) create mode 100644 test/fuzz/vitest.config.ts diff --git a/_develop/webpack.config.js b/_develop/webpack.config.js index 91fdf69f12..f8b02c75dd 100644 --- a/_develop/webpack.config.js +++ b/_develop/webpack.config.js @@ -65,7 +65,6 @@ const baseConfig = { 'quill.bubble': './assets/bubble.styl', 'quill.snow': './assets/snow.styl', 'unit.js': './test/unit.js', - 'fuzz.js': './test/fuzz.ts', }, output: { filename: '[name]', diff --git a/package.json b/package.json index b2d6ea4810..3fc095653e 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@types/lodash.clonedeep": "^4.5.7", "@typescript-eslint/eslint-plugin": "^5.59.8", "@typescript-eslint/parser": "^5.59.8", + "@vitest/browser": "^0.33.0", "babel-loader": "^9.1.2", "babel-plugin-istanbul": "^6.1.1", "css-loader": "^6.8.1", @@ -56,6 +57,7 @@ "lodash": "^4.17.15", "mini-css-extract-plugin": "^2.7.6", "npm-run-all": "^4.1.5", + "playwright": "^1.36.0", "prettier": "^2.7.1", "style-loader": "^3.3.3", "stylus": "^0.59.0", @@ -63,6 +65,7 @@ "ts-loader": "^9.4.3", "ts-node": "^10.9.1", "typescript": "^5.0.4", + "vitest": "^0.33.0", "webpack": "^5.87.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" diff --git a/test/fuzz.ts b/test/fuzz.ts deleted file mode 100644 index 57bf9d34a5..0000000000 --- a/test/fuzz.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './fuzz/editor.test'; -import './fuzz/tableEmbed.test'; diff --git a/test/fuzz/utils.ts b/test/fuzz/__helpers__/utils.ts similarity index 100% rename from test/fuzz/utils.ts rename to test/fuzz/__helpers__/utils.ts diff --git a/test/fuzz/editor.test.ts b/test/fuzz/editor.spec.ts similarity index 96% rename from test/fuzz/editor.test.ts rename to test/fuzz/editor.spec.ts index 4b239238a3..961817095e 100644 --- a/test/fuzz/editor.test.ts +++ b/test/fuzz/editor.spec.ts @@ -1,9 +1,10 @@ import Delta, { AttributeMap, Op } from 'quill-delta'; -import { choose, randomInt, runFuzz } from './utils'; +import { choose, randomInt, runFuzz } from './__helpers__/utils'; import { AlignClass } from '../../formats/align'; import { FontClass } from '../../formats/font'; import { SizeClass } from '../../formats/size'; import Quill from '../../quill'; +import { describe, expect, test } from 'vitest'; type AttributeDef = { name: string; values: (number | string | boolean)[] }; const BLOCK_EMBED_NAME = 'video'; @@ -222,7 +223,7 @@ const generateChange = ( }; describe('editor', () => { - it('setContents()', () => { + test('setContents()', () => { runFuzz(() => { const quill = new Quill(document.createElement('div')); const delta = generateDocument(); @@ -233,7 +234,7 @@ describe('editor', () => { }); }); - it('updateContents()', () => { + test('updateContents()', () => { runFuzz(() => { const quill = new Quill(document.createElement('div')); const delta = generateDocument(); @@ -248,7 +249,7 @@ describe('editor', () => { }); }); - it('insertContents() vs applyDelta()', () => { + test('insertContents() vs applyDelta()', () => { const quill1 = new Quill(document.createElement('div')); const quill2 = new Quill(document.createElement('div')); diff --git a/test/fuzz/tableEmbed.test.ts b/test/fuzz/tableEmbed.spec.ts similarity index 96% rename from test/fuzz/tableEmbed.test.ts rename to test/fuzz/tableEmbed.spec.ts index f30dc512da..1411311864 100644 --- a/test/fuzz/tableEmbed.test.ts +++ b/test/fuzz/tableEmbed.spec.ts @@ -4,7 +4,9 @@ import TableEmbed, { TableData, TableRowColumnOp, } from '../../modules/tableEmbed'; -import { choose, randomInt } from './utils'; +import { choose, randomInt } from './__helpers__/utils'; +import { describe, expect, test } from 'vitest'; +import { beforeAll } from 'vitest'; const getRandomRowColumnId = () => { const characters = 'abcdefghijklmnopqrstuvwxyz0123456789'; @@ -155,7 +157,7 @@ describe('tableEmbed', () => { TableEmbed.register(); }); - it('delta', () => { + test('delta', () => { for (let i = 0; i < 20; i += 1) { for (let j = 0; j < 1000; j += 1) { runTestCase(); diff --git a/test/fuzz/vitest.config.ts b/test/fuzz/vitest.config.ts new file mode 100644 index 0000000000..42f74e576c --- /dev/null +++ b/test/fuzz/vitest.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + resolve: { + extensions: ['.ts', '.js'], + }, + test: { + include: ['test/fuzz/**/*.spec.ts'], + environment: 'jsdom', + }, +}); From d5a7103149882f6d006f471dc8951281312553f1 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:24:37 +0800 Subject: [PATCH 02/18] Set up Vitest for unit tests --- .github/workflows/_unit.yml | 14 +-- .gitignore | 5 +- test/helpers/unit.js | 132 ------------------------- test/unit.js | 44 --------- test/unit/__helpers__/cleanup.ts | 5 + test/unit/__helpers__/expect.ts | 158 ++++++++++++++++++++++++++++++ test/unit/__helpers__/factory.ts | 43 ++++++++ test/unit/__helpers__/utils.ts | 9 ++ test/unit/__helpers__/vitest.d.ts | 10 ++ test/unit/vitest.config.ts | 20 ++++ 10 files changed, 248 insertions(+), 192 deletions(-) delete mode 100644 test/helpers/unit.js delete mode 100644 test/unit.js create mode 100644 test/unit/__helpers__/cleanup.ts create mode 100644 test/unit/__helpers__/expect.ts create mode 100644 test/unit/__helpers__/factory.ts create mode 100644 test/unit/__helpers__/utils.ts create mode 100644 test/unit/__helpers__/vitest.d.ts create mode 100644 test/unit/vitest.config.ts diff --git a/.github/workflows/_unit.yml b/.github/workflows/_unit.yml index 570f722e0e..091d733db9 100644 --- a/.github/workflows/_unit.yml +++ b/.github/workflows/_unit.yml @@ -7,16 +7,7 @@ jobs: strategy: fail-fast: false matrix: - browser: [ - mac-chrome-latest, - mac-firefox-latest, - mac-safari-latest, - windows-chrome-latest, - windows-firefox-latest, - windows-edge-latest, - ios-latest, - # android-latest, - ] + browser: [chromium, webkit, firefox] steps: - name: Git checkout @@ -29,8 +20,7 @@ jobs: cache: npm - run: npm ci - env: - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 1 + - run: npx playwright install --with-deps - run: npm run lint - run: npm run test:unit env: diff --git a/.gitignore b/.gitignore index 74d956fd9e..18f32fba7e 100644 --- a/.gitignore +++ b/.gitignore @@ -21,10 +21,7 @@ themes/*.js ui/*.js e2e/**/*.js -test/**/*.js -!test/helpers/**/*.js -!test/unit/**/*.js -!test/unit.js +!test/unit/__helpers__/vitest.d.ts core.js quill.js diff --git a/test/helpers/unit.js b/test/helpers/unit.js deleted file mode 100644 index 5142850ca5..0000000000 --- a/test/helpers/unit.js +++ /dev/null @@ -1,132 +0,0 @@ -import isEqual from 'lodash.isequal'; -import Editor from '../../core/editor'; -import Emitter from '../../core/emitter'; -import Selection from '../../core/selection'; -import Scroll from '../../blots/scroll'; -import Quill, { globalRegistry } from '../../core/quill'; - -const div = document.createElement('div'); -div.id = 'test-container'; -document.body.appendChild(div); - -window.onerror = function (msg) { - return msg === 'Script error.'; -}; - -beforeEach(function () { - jasmine.addMatchers({ - toEqualHTML() { - return { compare: compareHTML }; - }, - toBeApproximately() { - return { compare: compareApproximately }; - }, - }); - - div.innerHTML = '
'; - this.container = div.firstChild; - this.initialize = initialize.bind(this); -}); - -function compareApproximately(actual, expected, tolerance) { - const pass = Math.abs(actual - expected) <= tolerance; - return { - pass, - message: `${actual} is ${pass ? '' : 'not'} approximately ${expected}`, - }; -} - -function compareHTML(actual, expected, ignoreClassId, ignoreUI = true) { - const [div1, div2] = [actual, expected].map(function (html) { - if (html instanceof HTMLElement) { - html = html.innerHTML; - } - const container = document.createElement('div'); - container.innerHTML = html.replace(/\n\s*/g, ''); - // Heuristic for if DOM 'fixed' our input HTML - if ( - container.innerHTML.replace(/\s/g, '').length !== - html.replace(/\s/g, '').length - ) { - console.error('Invalid markup', html); // eslint-disable-line no-console - throw new Error('Invalid markup passed to compareHTML'); - } - if (ignoreUI) { - Array.from(container.querySelectorAll('.ql-ui')).forEach(node => { - node.remove(); - }); - } - return container; - }); - let ignoredAttributes = ['width', 'height', 'data-row', 'contenteditable']; - if (ignoreClassId) { - ignoredAttributes = ignoredAttributes.concat(['class', 'id']); - } - const message = compareNodes(div1, div2, ignoredAttributes); - if (message != null) { - console.error(div1.innerHTML); // eslint-disable-line no-console - console.error(div2.innerHTML); // eslint-disable-line no-console - return { pass: false, message }; - } - return { pass: true, message: 'HTMLs equal' }; -} - -function compareNodes(node1, node2, ignoredAttributes = []) { - if (node1.nodeType !== node2.nodeType) { - return `Expected nodeType '${node1.nodeType}' to equal '${node2.nodeType}'`; - } - if (node1.nodeType === node1.ELEMENT_NODE) { - if (node1.tagName !== node2.tagName) { - return `Expected tagName '${node1.tagName}' to equal '${node2.tagName}'`; - } - const [attr1, attr2] = [node1, node2].map(function (node) { - return Array.from(node.attributes || []).reduce(function (attr, elem) { - if (ignoredAttributes.indexOf(elem.name) < 0) { - attr[elem.name] = - elem.name === 'style' ? elem.value.trim() : elem.value; - } - return attr; - }, {}); - }); - if (!isEqual(attr1, attr2)) { - return `Expected attributes ${jasmine.pp(attr1)} to equal ${jasmine.pp( - attr2, - )}`; - } - if (node1.childNodes.length !== node2.childNodes.length) { - return `Expected node childNodes length '${node1.childNodes.length}' to equal '${node2.childNodes.length}'`; - } - if (node1.childNodes.length === 0) return null; - let message = ''; - if ( - Array.from(node1.childNodes).some(function (child1, i) { - message = compareNodes(child1, node2.childNodes[i], ignoredAttributes); - return message; - }) - ) { - return message; - } - } else if (node1.data !== node2.data) { - return `Expected node text '${node1.data}' to equal '${node2.data}'`; - } - return null; -} - -function initialize(klass, html, container = this.container, options = {}) { - if (typeof html === 'object') { - container.innerHTML = html.html; - } else { - container.innerHTML = html.replace(/\n\s*/g, ''); - } - if (klass === HTMLElement) return container; - if (klass === Quill) return new Quill(container, options); - const emitter = new Emitter(); - const scroll = new Scroll(globalRegistry, container, { emitter }); - if (klass === Scroll) return scroll; - if (klass === Editor) return new Editor(scroll); - if (klass === Selection) return new Selection(scroll, emitter); - if (klass[0] === Editor && klass[1] === Selection) { - return [new Editor(scroll), new Selection(scroll, emitter)]; - } - return null; -} diff --git a/test/unit.js b/test/unit.js deleted file mode 100644 index 88720ae8fe..0000000000 --- a/test/unit.js +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable */ - -import Quill from '../quill.ts'; -import CodeBlock, { CodeBlockContainer } from '../formats/code'; - -import './helpers/unit'; - -import './unit/blots/scroll'; -import './unit/blots/block'; -import './unit/blots/block-embed'; -import './unit/blots/inline'; - -import './unit/core/editor'; -import './unit/core/selection'; -import './unit/core/composition'; -import './unit/core/quill'; - -import './unit/formats/color'; -import './unit/formats/link'; -import './unit/formats/script'; -import './unit/formats/align'; -import './unit/formats/code'; -import './unit/formats/header'; -import './unit/formats/indent'; -import './unit/formats/list'; -import './unit/formats/bold'; -import './unit/formats/table'; - -import './unit/modules/clipboard'; -import './unit/modules/history'; -import './unit/modules/keyboard'; -import './unit/modules/syntax'; -import './unit/modules/table'; -import './unit/modules/tableEmbed'; -import './unit/modules/toolbar'; - -import './unit/ui/picker'; -import './unit/theme/base/tooltip'; - -// Syntax version will otherwise be registered -Quill.register(CodeBlockContainer, true); -Quill.register(CodeBlock, true); - -export default Quill; diff --git a/test/unit/__helpers__/cleanup.ts b/test/unit/__helpers__/cleanup.ts new file mode 100644 index 0000000000..2f6a3d3426 --- /dev/null +++ b/test/unit/__helpers__/cleanup.ts @@ -0,0 +1,5 @@ +import { beforeEach } from 'vitest'; + +beforeEach(() => { + document.body.innerHTML = ''; +}); diff --git a/test/unit/__helpers__/expect.ts b/test/unit/__helpers__/expect.ts new file mode 100644 index 0000000000..d9303c176e --- /dev/null +++ b/test/unit/__helpers__/expect.ts @@ -0,0 +1,158 @@ +import { expect } from 'vitest'; +import Cursor from '../../../blots/cursor'; +import { Blot, ContainerBlot, ScrollBlot } from 'parchment'; +import { normalizeHTML } from './utils'; + +expect.addSnapshotSerializer({ + serialize(val) { + return val.outerHTML.replace(Cursor.CONTENTS, '{Cursor.CONTENTS}'); + }, + test(val) { + return val instanceof HTMLElement && val.classList.contains('ql-cursor'); + }, +}); + +expect.addSnapshotSerializer({ + serialize() { + return ''; + }, + test(val) { + return val instanceof HTMLElement && val.classList.contains('ql-ui'); + }, +}); + +interface Config { + indent: string; + min: boolean; + spacingOuter: string; + spacingInner: string; +} + +const printBlot = ( + blot: Blot, + config: Config, + indentation: string, + depth: number, + refs: unknown, + printer: ( + value: unknown, + config: Config, + indentation: string, + depth: number, + refs: unknown, + ) => string, +) => { + const isScroll = blot instanceof ScrollBlot; + if (isScroll || blot instanceof ContainerBlot) { + const html = printer( + blot.domNode, + { + ...config, + min: true, + indent: '', + spacingOuter: '', + spacingInner: ' ', + }, + '', + depth, + refs, + ); + const childNodes = blot.children + .map(child => { + return ( + indentation + + printBlot( + child, + config, + indentation + config.indent, + depth, + refs, + printer, + ) + ); + }) + .join('\n'); + + if (isScroll) return childNodes; + const openTag = html.slice(0, html.indexOf('>') + 1); + const endTag = html.slice(html.lastIndexOf('<')); + + return `${openTag}\n${childNodes}\n${indentation.slice( + config.indent.length, + )}${endTag}`; + } + return printer( + blot.domNode, + { ...config, min: true, indent: '', spacingInner: ' ', spacingOuter: '' }, + '', + depth, + refs, + ); +}; + +expect.addSnapshotSerializer({ + serialize(val, config, indentation, depth, refs, printer) { + return printBlot(val, config, indentation, depth, refs, printer); + }, + test(blot) { + return typeof blot === 'object' && 'statics' in blot; + }, +}); + +const sortAttributes = (element: HTMLElement) => { + const attributes = Array.from(element.attributes); + const sortedAttributes = attributes.sort((a, b) => + a.name.localeCompare(b.name), + ); + + while (element.attributes.length > 0) { + element.removeAttribute(element.attributes[0].name); + } + + for (const attr of sortedAttributes) { + element.setAttribute(attr.name, attr.value); + } + + element.childNodes.forEach(child => { + if (child instanceof HTMLElement) { + sortAttributes(child); + } + }); +}; + +expect.extend({ + toEqualHTML(received, expected, options) { + const ignoreAttrs = options?.ignoreAttrs ?? []; + const receivedDOM = document.createElement('div'); + const expectedDOM = document.createElement('div'); + receivedDOM.innerHTML = normalizeHTML( + typeof received === 'string' ? received : received.innerHTML, + ); + expectedDOM.innerHTML = normalizeHTML(expected); + + const doms = [receivedDOM, expectedDOM]; + + doms.forEach(dom => { + Array.from(dom.querySelectorAll('.ql-ui')).forEach(node => { + node.remove(); + }); + + ignoreAttrs.forEach(attr => { + Array.from(dom.querySelectorAll(`[${attr}]`)).forEach(node => { + node.removeAttribute(attr); + }); + }); + + sortAttributes(dom); + }); + + if (this.equals(receivedDOM.innerHTML, expectedDOM.innerHTML)) { + return { pass: true, message: () => '' }; + } + return { + pass: false, + message: () => + `expected ${receivedDOM.innerHTML} to match html ${expectedDOM.innerHTML}`, + }; + }, +}); diff --git a/test/unit/__helpers__/factory.ts b/test/unit/__helpers__/factory.ts new file mode 100644 index 0000000000..3f74707105 --- /dev/null +++ b/test/unit/__helpers__/factory.ts @@ -0,0 +1,43 @@ +import { Registry } from 'parchment'; + +import Block from '../../../blots/block'; +import Break from '../../../blots/break'; +import Cursor from '../../../blots/cursor'; +import Scroll from '../../../blots/scroll'; +import TextBlot from '../../../blots/text'; +import ListItem, { ListContainer } from '../../../formats/list'; +import Inline from '../../../blots/inline'; +import Emitter from '../../../core/emitter'; +import { normalizeHTML } from './utils'; + +export const createRegistry = (formats: unknown[] = []) => { + const registry = new Registry(); + + formats.forEach(format => { + registry.register(format); + }); + registry.register(Block); + registry.register(Break); + registry.register(Cursor); + registry.register(Inline); + registry.register(Scroll); + registry.register(TextBlot); + registry.register(ListContainer); + registry.register(ListItem); + + return registry; +}; + +export const createScroll = ( + html: string | { html: string }, + registry = createRegistry(), + container = document.body, +) => { + const emitter = new Emitter(); + const root = container.appendChild(document.createElement('div')); + root.innerHTML = normalizeHTML(html); + const scroll = new Scroll(registry, root, { + emitter, + }); + return scroll; +}; diff --git a/test/unit/__helpers__/utils.ts b/test/unit/__helpers__/utils.ts new file mode 100644 index 0000000000..6e21717b68 --- /dev/null +++ b/test/unit/__helpers__/utils.ts @@ -0,0 +1,9 @@ +export const sleep = (ms: number) => + new Promise(r => { + setTimeout(() => { + r(); + }, ms); + }); + +export const normalizeHTML = (html: string | { html: string }) => + typeof html === 'object' ? html.html : html.replace(/\n\s*/g, ''); diff --git a/test/unit/__helpers__/vitest.d.ts b/test/unit/__helpers__/vitest.d.ts new file mode 100644 index 0000000000..4c978d4253 --- /dev/null +++ b/test/unit/__helpers__/vitest.d.ts @@ -0,0 +1,10 @@ +import type { Assertion, AsymmetricMatchersContaining } from 'vitest'; + +interface CustomMatchers { + toEqualHTML(html: string, options?: { ignoreAttrs?: string[] }): R; +} + +declare module 'vitest' { + interface Assertion extends CustomMatchers {} + interface AsymmetricMatchersContaining extends CustomMatchers {} +} diff --git a/test/unit/vitest.config.ts b/test/unit/vitest.config.ts new file mode 100644 index 0000000000..02bd8f543a --- /dev/null +++ b/test/unit/vitest.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + resolve: { + extensions: ['.ts', '.js'], + }, + test: { + include: ['test/unit/**/*.spec.ts'], + setupFiles: [ + 'test/unit/__helpers__/expect.ts', + 'test/unit/__helpers__/cleanup.ts', + ], + browser: { + enabled: true, + provider: 'playwright', + name: process.env.BROWSER || 'chromium', + slowHijackESM: false, + }, + }, +}); From dfa805493e5c6a37760c10f30561b0d6db5c8624 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:25:29 +0800 Subject: [PATCH 03/18] Update eslint for Vitest --- .eslintrc.json | 7 +------ test/.eslintrc.json | 9 --------- 2 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 test/.eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json index 070eae1113..340d2fb6a6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -13,12 +13,7 @@ } } }, - "ignorePatterns": [ - "website/**/*", - "*.js", - "!test/helpers/**/*.js", - "!test/unit/**/*.js" - ], + "ignorePatterns": ["website/**/*", "*.js"], "rules": { "arrow-parens": ["error", "as-needed"], "no-use-before-define": ["error", { "functions": false, "classes": false }], diff --git a/test/.eslintrc.json b/test/.eslintrc.json deleted file mode 100644 index 8a27227d2b..0000000000 --- a/test/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "env": { - "jasmine": true - }, - "rules": { - "func-names": ["off"], - "prefer-arrow-callback": ["off"] - } -} From f3d8d9dc0f153add79aeb427891a57fb00e4e31a Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:26:28 +0800 Subject: [PATCH 04/18] Improve typings for tests --- modules/history.ts | 2 +- modules/toolbar.ts | 7 ++++++- themes/base.ts | 2 +- ui/tooltip.ts | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/history.ts b/modules/history.ts index 72a52bd030..bdd5f8e13d 100644 --- a/modules/history.ts +++ b/modules/history.ts @@ -4,7 +4,7 @@ import Module from '../core/module'; import Quill from '../core/quill'; import type Scroll from '../blots/scroll'; -interface HistoryOptions { +export interface HistoryOptions { userOnly: boolean; delay: number; maxStack: number; diff --git a/modules/toolbar.ts b/modules/toolbar.ts index 6bb169f43a..0ee20fe701 100644 --- a/modules/toolbar.ts +++ b/modules/toolbar.ts @@ -192,7 +192,12 @@ function addButton(container: HTMLElement, format: string, value?: unknown) { container.appendChild(input); } -function addControls(container: HTMLElement, groups: string[][]) { +function addControls( + container: HTMLElement, + groups: + | (string | Record)[][] + | (string | Record)[], +) { if (!Array.isArray(groups[0])) { // @ts-expect-error groups = [groups]; diff --git a/themes/base.ts b/themes/base.ts index 88a0f3c8bf..c3ca4d6590 100644 --- a/themes/base.ts +++ b/themes/base.ts @@ -214,7 +214,7 @@ class BaseTooltip extends Tooltip { textbox: HTMLInputElement | null; linkRange?: Range; - constructor(quill: Quill, boundsContainer) { + constructor(quill: Quill, boundsContainer?: HTMLElement) { super(quill, boundsContainer); this.textbox = this.root.querySelector('input[type="text"]'); this.listen(); diff --git a/ui/tooltip.ts b/ui/tooltip.ts index fdedb1a5fc..d672fc76c3 100644 --- a/ui/tooltip.ts +++ b/ui/tooltip.ts @@ -5,7 +5,7 @@ class Tooltip { boundsContainer: HTMLElement; root: HTMLDivElement; - constructor(quill: Quill, boundsContainer: HTMLElement) { + constructor(quill: Quill, boundsContainer?: HTMLElement) { this.quill = quill; this.boundsContainer = boundsContainer || document.body; this.root = quill.addContainer('ql-tooltip'); From b625fee1ee7db07d59bfe7b609862efa6759d685 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:27:03 +0800 Subject: [PATCH 05/18] Migrate UI tests to Vitest --- test/unit/ui/picker.js | 160 ----------- test/unit/ui/picker.spec.ts | 176 ++++++++++++ test/unit/utils/delta.js | 516 ------------------------------------ 3 files changed, 176 insertions(+), 676 deletions(-) delete mode 100644 test/unit/ui/picker.js create mode 100644 test/unit/ui/picker.spec.ts delete mode 100644 test/unit/utils/delta.js diff --git a/test/unit/ui/picker.js b/test/unit/ui/picker.js deleted file mode 100644 index 0218495d36..0000000000 --- a/test/unit/ui/picker.js +++ /dev/null @@ -1,160 +0,0 @@ -import Picker from '../../../ui/picker'; - -describe('Picker', function () { - beforeEach(function () { - this.container.innerHTML = - ''; - this.pickerSelectorInstance = new Picker(this.container.firstChild); - this.pickerSelector = this.container.querySelector('.ql-picker'); - }); - - it('initialization', function () { - expect(this.container.querySelector('.ql-picker')).toBeTruthy(); - expect(this.container.querySelector('.ql-active')).toBeFalsy(); - expect( - this.container.querySelector('.ql-picker-item.ql-selected').outerHTML, - ).toEqualHTML( - '', - ); - expect( - this.container.querySelector('.ql-picker-item:not(.ql-selected)') - .outerHTML, - ).toEqualHTML( - '', - ); - }); - - it('escape charcters', function () { - const select = document.createElement('select'); - const option = document.createElement('option'); - this.container.appendChild(select); - select.appendChild(option); - let value = '"Helvetica Neue", \'Helvetica\', sans-serif'; - option.value = value; - value = value.replace(/"/g, '\\"'); - expect(select.querySelector(`option[value="${value}"]`)).toEqual(option); - }); - - it('label is initialized with the correct aria attributes', function () { - expect( - this.pickerSelector - .querySelector('.ql-picker-label') - .getAttribute('aria-expanded'), - ).toEqual('false'); - const optionsId = - this.pickerSelector.querySelector('.ql-picker-options').id; - expect( - this.pickerSelector - .querySelector('.ql-picker-label') - .getAttribute('aria-controls'), - ).toEqual(optionsId); - }); - - it('options container is initialized with the correct aria attributes', function () { - expect( - this.pickerSelector - .querySelector('.ql-picker-options') - .getAttribute('aria-hidden'), - ).toEqual('true'); - - const ariaControlsLabel = this.pickerSelector - .querySelector('.ql-picker-label') - .getAttribute('aria-controls'); - expect(this.pickerSelector.querySelector('.ql-picker-options').id).toEqual( - ariaControlsLabel, - ); - expect( - this.pickerSelector.querySelector('.ql-picker-options').tabIndex, - ).toEqual(-1); - }); - - it('aria attributes toggle correctly when the picker is opened via enter key', function () { - const pickerLabel = this.pickerSelector.querySelector('.ql-picker-label'); - pickerLabel.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); - expect(pickerLabel.getAttribute('aria-expanded')).toEqual('true'); - expect( - this.pickerSelector - .querySelector('.ql-picker-options') - .getAttribute('aria-hidden'), - ).toEqual('false'); - }); - - it('aria attributes toggle correctly when the picker is opened via mousedown', function () { - const pickerLabel = this.pickerSelector.querySelector('.ql-picker-label'); - pickerLabel.dispatchEvent( - new Event('mousedown', { - bubbles: true, - cancelable: true, - }), - ); - - expect(pickerLabel.getAttribute('aria-expanded')).toEqual('true'); - expect( - this.pickerSelector - .querySelector('.ql-picker-options') - .getAttribute('aria-hidden'), - ).toEqual('false'); - }); - - it('aria attributes toggle correctly when an item is selected via click', function () { - const pickerLabel = this.pickerSelector.querySelector('.ql-picker-label'); - pickerLabel.click(); - - const pickerItem = this.pickerSelector.querySelector('.ql-picker-item'); - pickerItem.click(); - - expect(pickerLabel.getAttribute('aria-expanded')).toEqual('false'); - expect( - this.pickerSelector - .querySelector('.ql-picker-options') - .getAttribute('aria-hidden'), - ).toEqual('true'); - expect(pickerLabel.textContent.trim()).toEqual( - pickerItem.textContent.trim(), - ); - }); - - it('aria attributes toggle correctly when an item is selected via enter', function () { - const pickerLabel = this.pickerSelector.querySelector('.ql-picker-label'); - pickerLabel.click(); - const pickerItem = this.pickerSelector.querySelector('.ql-picker-item'); - pickerItem.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); - expect(pickerLabel.getAttribute('aria-expanded')).toEqual('false'); - expect( - this.pickerSelector - .querySelector('.ql-picker-options') - .getAttribute('aria-hidden'), - ).toEqual('true'); - expect(pickerLabel.textContent.trim()).toEqual( - pickerItem.textContent.trim(), - ); - }); - - it('aria attributes toggle correctly when the picker is closed via clicking on the label again', function () { - const pickerLabel = this.pickerSelector.querySelector('.ql-picker-label'); - pickerLabel.click(); - pickerLabel.click(); - expect(pickerLabel.getAttribute('aria-expanded')).toEqual('false'); - expect( - this.pickerSelector - .querySelector('.ql-picker-options') - .getAttribute('aria-hidden'), - ).toEqual('true'); - }); - - it('aria attributes toggle correctly when the picker is closed via escaping out of it', function () { - const pickerLabel = this.pickerSelector.querySelector('.ql-picker-label'); - pickerLabel.click(); - pickerLabel.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' })); - expect(pickerLabel.getAttribute('aria-expanded')).toEqual('false'); - expect( - this.pickerSelector - .querySelector('.ql-picker-options') - .getAttribute('aria-hidden'), - ).toEqual('true'); - }); - - afterEach(function () { - this.pickerSelectorInstance = null; - }); -}); diff --git a/test/unit/ui/picker.spec.ts b/test/unit/ui/picker.spec.ts new file mode 100644 index 0000000000..13f9462c4f --- /dev/null +++ b/test/unit/ui/picker.spec.ts @@ -0,0 +1,176 @@ +import { describe, expect, test } from 'vitest'; +import Picker from '../../../ui/picker'; + +describe('Picker', () => { + const setup = () => { + const container = document.body.appendChild(document.createElement('div')); + container.innerHTML = + ''; + const pickerSelectorInstance = new Picker( + container.firstChild as HTMLSelectElement, + ); + const pickerSelector = container.querySelector('.ql-picker') as HTMLElement; + return { container, pickerSelectorInstance, pickerSelector }; + }; + + test('initialization', () => { + const { container } = setup(); + expect(container.querySelector('.ql-picker')).toBeTruthy(); + expect(container.querySelector('.ql-active')).toBeFalsy(); + expect( + container.querySelector('.ql-picker-item.ql-selected')?.outerHTML, + ).toEqualHTML( + '', + ); + expect( + container.querySelector('.ql-picker-item:not(.ql-selected)')?.outerHTML, + ).toEqualHTML( + '', + ); + }); + + test('escape charcters', () => { + const { container } = setup(); + const select = document.createElement('select'); + const option = document.createElement('option'); + container.appendChild(select); + select.appendChild(option); + let value = '"Helvetica Neue", \'Helvetica\', sans-serif'; + option.value = value; + value = value.replace(/"/g, '\\"'); + expect(select.querySelector(`option[value="${value}"]`)).toEqual(option); + }); + + test('label is initialized with the correct aria attributes', () => { + const { pickerSelector } = setup(); + expect( + pickerSelector + .querySelector('.ql-picker-label') + ?.getAttribute('aria-expanded'), + ).toEqual('false'); + const optionsId = pickerSelector.querySelector('.ql-picker-options')?.id; + expect( + pickerSelector + .querySelector('.ql-picker-label') + ?.getAttribute('aria-controls'), + ).toEqual(optionsId); + }); + + test('options container is initialized with the correct aria attributes', () => { + const { pickerSelector } = setup(); + expect( + pickerSelector + .querySelector('.ql-picker-options') + ?.getAttribute('aria-hidden'), + ).toEqual('true'); + + const ariaControlsLabel = pickerSelector + .querySelector('.ql-picker-label') + ?.getAttribute('aria-controls'); + expect(pickerSelector.querySelector('.ql-picker-options')?.id).toEqual( + ariaControlsLabel, + ); + expect( + (pickerSelector.querySelector('.ql-picker-options') as HTMLSelectElement) + .tabIndex, + ).toEqual(-1); + }); + + test('aria attributes toggle correctly when the picker is opened via enter key', () => { + const { pickerSelector } = setup(); + const pickerLabel = pickerSelector.querySelector('.ql-picker-label'); + pickerLabel?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); + expect(pickerLabel?.getAttribute('aria-expanded')).toEqual('true'); + expect( + pickerSelector + .querySelector('.ql-picker-options') + ?.getAttribute('aria-hidden'), + ).toEqual('false'); + }); + + test('aria attributes toggle correctly when the picker is opened via mousedown', () => { + const { pickerSelector } = setup(); + const pickerLabel = pickerSelector.querySelector('.ql-picker-label'); + pickerLabel?.dispatchEvent( + new Event('mousedown', { + bubbles: true, + cancelable: true, + }), + ); + + expect(pickerLabel?.getAttribute('aria-expanded')).toEqual('true'); + expect( + pickerSelector + .querySelector('.ql-picker-options') + ?.getAttribute('aria-hidden'), + ).toEqual('false'); + }); + + test('aria attributes toggle correctly when an item is selected via click', () => { + const { pickerSelector } = setup(); + const pickerLabel = pickerSelector.querySelector( + '.ql-picker-label', + ) as HTMLElement; + pickerLabel.click(); + + const pickerItem = pickerSelector.querySelector( + '.ql-picker-item', + ) as HTMLElement; + pickerItem.click(); + + expect(pickerLabel.getAttribute('aria-expanded')).toEqual('false'); + expect( + pickerSelector + .querySelector('.ql-picker-options') + ?.getAttribute('aria-hidden'), + ).toEqual('true'); + }); + + test('aria attributes toggle correctly when an item is selected via enter', () => { + const { pickerSelector } = setup(); + const pickerLabel = pickerSelector.querySelector( + '.ql-picker-label', + ) as HTMLElement; + pickerLabel.click(); + const pickerItem = pickerSelector.querySelector( + '.ql-picker-item', + ) as HTMLElement; + pickerItem.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); + expect(pickerLabel?.getAttribute('aria-expanded')).toEqual('false'); + expect( + pickerSelector + .querySelector('.ql-picker-options') + ?.getAttribute('aria-hidden'), + ).toEqual('true'); + }); + + test('aria attributes toggle correctly when the picker is closed via clicking on the label again', () => { + const { pickerSelector } = setup(); + const pickerLabel = pickerSelector.querySelector( + '.ql-picker-label', + ) as HTMLElement; + pickerLabel.click(); + pickerLabel.click(); + expect(pickerLabel.getAttribute('aria-expanded')).toEqual('false'); + expect( + pickerSelector + .querySelector('.ql-picker-options') + ?.getAttribute('aria-hidden'), + ).toEqual('true'); + }); + + test('aria attributes toggle correctly when the picker is closed via escaping out of it', () => { + const { pickerSelector } = setup(); + const pickerLabel = pickerSelector.querySelector( + '.ql-picker-label', + ) as HTMLElement; + pickerLabel.click(); + pickerLabel.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' })); + expect(pickerLabel.getAttribute('aria-expanded')).toEqual('false'); + expect( + pickerSelector + .querySelector('.ql-picker-options') + ?.getAttribute('aria-hidden'), + ).toEqual('true'); + }); +}); diff --git a/test/unit/utils/delta.js b/test/unit/utils/delta.js deleted file mode 100644 index d690c4919d..0000000000 --- a/test/unit/utils/delta.js +++ /dev/null @@ -1,516 +0,0 @@ -import Delta from 'quill-delta'; - -describe('Delta', () => { - describe('compose', () => { - it('adds a row', () => { - const base = new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '11111111' }, attributes: { height: 20 } }, - ], - columns: [ - { insert: { id: '22222222' } }, - { insert: { id: '33333333' }, attributes: { width: 30 } }, - { insert: { id: '44444444' } }, - ], - cells: { - '1:2': { - content: [{ insert: 'Hello' }], - attributes: { align: 'center' }, - }, - }, - }, - }, - }, - ]); - - const change = new Delta([ - { retain: { table: { rows: [{ insert: { id: '55555555' } }] } } }, - ]); - - expect(base.compose(change)).toEqual( - new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '55555555' } }, - { insert: { id: '11111111' }, attributes: { height: 20 } }, - ], - columns: [ - { insert: { id: '22222222' } }, - { insert: { id: '33333333' }, attributes: { width: 30 } }, - { insert: { id: '44444444' } }, - ], - cells: { - '2:2': { - content: [{ insert: 'Hello' }], - attributes: { align: 'center' }, - }, - }, - }, - }, - }, - ]), - ); - }); - - it('adds a row and changes cell content', () => { - const base = new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '11111111' } }, - { insert: { id: '22222222' }, attributes: { height: 20 } }, - ], - columns: [ - { insert: { id: '33333333' } }, - { insert: { id: '44444444' }, attributes: { width: 30 } }, - { insert: { id: '55555555' } }, - ], - cells: { - '2:2': { content: [{ insert: 'Hello' }] }, - '2:3': { content: [{ insert: 'World' }] }, - }, - }, - }, - }, - ]); - - const change = new Delta([ - { - retain: { - table: { - rows: [{ insert: { id: '66666666' } }], - cells: { - '3:2': { attributes: { align: 'right' } }, - '3:3': { content: [{ insert: 'Hello ' }] }, - }, - }, - }, - }, - ]); - - expect(base.compose(change)).toEqual( - new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '66666666' } }, - { insert: { id: '11111111' } }, - { insert: { id: '22222222' }, attributes: { height: 20 } }, - ], - columns: [ - { insert: { id: '33333333' } }, - { insert: { id: '44444444' }, attributes: { width: 30 } }, - { insert: { id: '55555555' } }, - ], - cells: { - '3:2': { - content: [{ insert: 'Hello' }], - attributes: { align: 'right' }, - }, - '3:3': { content: [{ insert: 'Hello World' }] }, - }, - }, - }, - }, - ]), - ); - }); - - it('deletes a column', () => { - const base = new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '11111111' }, attributes: { height: 20 } }, - ], - columns: [ - { insert: { id: '22222222' } }, - { insert: { id: '33333333' }, attributes: { width: 30 } }, - { insert: { id: '44444444' } }, - ], - cells: { - '1:2': { - content: [{ insert: 'Hello' }], - attributes: { align: 'center' }, - }, - }, - }, - }, - }, - ]); - - const change = new Delta([ - { - retain: { - table: { - columns: [{ retain: 1 }, { delete: 1 }], - }, - }, - }, - ]); - - expect(base.compose(change)).toEqual( - new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '11111111' }, attributes: { height: 20 } }, - ], - columns: [ - { insert: { id: '22222222' } }, - { insert: { id: '44444444' } }, - ], - }, - }, - }, - ]), - ); - }); - - it('removes a cell attributes', () => { - const base = new Delta([ - { - insert: { - table: { cells: { '1:2': { attributes: { align: 'center' } } } }, - }, - }, - ]); - - const change = new Delta([ - { - retain: { - table: { cells: { '1:2': { attributes: { align: null } } } }, - }, - }, - ]); - - expect(base.compose(change)).toEqual( - new Delta([{ insert: { table: {} } }]), - ); - }); - - it('removes all rows', () => { - const base = new Delta([ - { insert: { table: { rows: [{ insert: { id: '11111111' } }] } } }, - ]); - - const change = new Delta([ - { retain: { table: { rows: [{ delete: 1 }] } } }, - ]); - - expect(base.compose(change)).toEqual( - new Delta([{ insert: { table: {} } }]), - ); - }); - }); - - describe('transform', () => { - it('transform rows and columns', () => { - const change1 = new Delta([ - { - retain: { - table: { - rows: [ - { insert: { id: '11111111' } }, - { insert: { id: '22222222' } }, - { insert: { id: '33333333' }, attributes: { height: 100 } }, - ], - columns: [ - { insert: { id: '44444444' }, attributes: { width: 100 } }, - { insert: { id: '55555555' } }, - { insert: { id: '66666666' } }, - ], - }, - }, - }, - ]); - - const change2 = new Delta([ - { - retain: { - table: { - rows: [{ delete: 1 }, { retain: 1, attributes: { height: 50 } }], - columns: [ - { delete: 1 }, - { retain: 2, attributes: { width: 40 } }, - ], - }, - }, - }, - ]); - - expect(change1.transform(change2)).toEqual( - new Delta([ - { - retain: { - table: { - rows: [ - { retain: 3 }, - { delete: 1 }, - { retain: 1, attributes: { height: 50 } }, - ], - columns: [ - { retain: 3 }, - { delete: 1 }, - { retain: 2, attributes: { width: 40 } }, - ], - }, - }, - }, - ]), - ); - }); - - it('transform cells', () => { - const change1 = new Delta([ - { - retain: { - table: { - rows: [{ insert: { id: '22222222' } }], - cells: { - '8:1': { - content: [{ insert: 'Hello 8:1!' }], - }, - '21:2': { - content: [{ insert: 'Hello 21:2!' }], - }, - }, - }, - }, - }, - ]); - - const change2 = new Delta([ - { - retain: { - table: { - rows: [{ delete: 1 }], - cells: { - '6:1': { - content: [{ insert: 'Hello 6:1!' }], - }, - '52:8': { - content: [{ insert: 'Hello 52:8!' }], - }, - }, - }, - }, - }, - ]); - - expect(change1.transform(change2)).toEqual( - new Delta([ - { - retain: { - table: { - rows: [{ retain: 1 }, { delete: 1 }], - cells: { - '7:1': { - content: [{ insert: 'Hello 6:1!' }], - }, - '53:8': { - content: [{ insert: 'Hello 52:8!' }], - }, - }, - }, - }, - }, - ]), - ); - }); - - it('transform cell attributes', () => { - const change1 = new Delta([ - { - retain: { - table: { cells: { '8:1': { attributes: { align: 'right' } } } }, - }, - }, - ]); - - const change2 = new Delta([ - { - retain: { - table: { cells: { '8:1': { attributes: { align: 'left' } } } }, - }, - }, - ]); - - expect(change1.transform(change2)).toEqual( - new Delta([ - { - retain: { - table: { cells: { '8:1': { attributes: { align: 'left' } } } }, - }, - }, - ]), - ); - - expect(change1.transform(change2, true)).toEqual( - new Delta([{ retain: { table: {} } }]), - ); - }); - }); - - describe('invert', () => { - it('reverts rows and columns', () => { - const base = new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '11111111' } }, - { insert: { id: '22222222' } }, - ], - columns: [ - { insert: { id: '33333333' } }, - { insert: { id: '44444444' }, attributes: { width: 100 } }, - ], - }, - }, - }, - ]); - - const change = new Delta([ - { - retain: { - table: { - rows: [{ remove: { id: '22222222' } }], - columns: [{ retain: 1 }, { delete: 1 }], - }, - }, - }, - ]); - - expect(change.invert(base)).toEqual( - new Delta([ - { - retain: { - table: { - columns: [ - { retain: 1 }, - { insert: { id: '44444444' }, attributes: { width: 100 } }, - ], - }, - }, - }, - ]), - ); - }); - - it('inverts cell content', () => { - const base = new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '11111111' } }, - { insert: { id: '22222222' } }, - ], - columns: [ - { insert: { id: '33333333' } }, - { insert: { id: '44444444' } }, - ], - cells: { - '1:2': { - content: [{ insert: 'Hello 1:2' }], - attributes: { align: 'center' }, - }, - }, - }, - }, - }, - ]); - const change = new Delta([ - { - retain: { - table: { - rows: [{ insert: { id: '55555555' } }], - cells: { - '2:2': { - content: [{ retain: 6 }, { insert: '2' }, { delete: 1 }], - }, - }, - }, - }, - }, - ]); - expect(change.invert(base)).toEqual( - new Delta([ - { - retain: { - table: { - rows: [{ delete: 1 }], - cells: { - '1:2': { - content: [{ retain: 6 }, { insert: '1' }, { delete: 1 }], - }, - }, - }, - }, - }, - ]), - ); - }); - - it('inverts cells removed by row/column delta', () => { - const base = new Delta([ - { - insert: { - table: { - rows: [ - { insert: { id: '11111111' } }, - { insert: { id: '22222222' } }, - ], - columns: [ - { insert: { id: '33333333' } }, - { insert: { id: '44444444' } }, - ], - cells: { - '1:2': { - content: [{ insert: 'content' }], - attributes: { align: 'center' }, - }, - }, - }, - }, - }, - ]); - const change = new Delta([ - { - retain: { - table: { - columns: [{ retain: 1 }, { delete: 1 }], - }, - }, - }, - ]); - expect(change.invert(base)).toEqual( - new Delta([ - { - retain: { - table: { - columns: [{ retain: 1 }, { insert: { id: '44444444' } }], - cells: { - '1:2': { - content: [{ insert: 'content' }], - attributes: { align: 'center' }, - }, - }, - }, - }, - }, - ]), - ); - }); - }); -}); From 8d86b98e39af1c3374e05122c81acde8d830ff5b Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:27:30 +0800 Subject: [PATCH 06/18] Migrate themes to Vitest --- test/unit/theme/base/tooltip.js | 84 ------------------------ test/unit/theme/base/tooltip.spec.ts | 98 ++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 84 deletions(-) delete mode 100644 test/unit/theme/base/tooltip.js create mode 100644 test/unit/theme/base/tooltip.spec.ts diff --git a/test/unit/theme/base/tooltip.js b/test/unit/theme/base/tooltip.js deleted file mode 100644 index 3e71a0b581..0000000000 --- a/test/unit/theme/base/tooltip.js +++ /dev/null @@ -1,84 +0,0 @@ -import Quill from '../../../../core'; -import { BaseTooltip } from '../../../../themes/base'; - -class Tooltip extends BaseTooltip {} - -Tooltip.TEMPLATE = ''; - -describe('BaseTooltip', function () { - describe('save', function () { - beforeEach(function () { - this.quill = this.initialize(Quill, ''); - this.tooltip = new Tooltip(this.quill); - }); - - it('converts youtube video url to embedded', function () { - insertVideo(this.tooltip, 'http://youtube.com/watch?v=QHH3iSeDBLo'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'http://www.youtube.com/embed/QHH3iSeDBLo', - ); - }); - - it('converts www.youtube video url to embedded', function () { - insertVideo(this.tooltip, 'http://www.youtube.com/watch?v=QHH3iSeDBLo'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'http://www.youtube.com/embed/QHH3iSeDBLo', - ); - }); - - it('converts m.youtube video url to embedded', function () { - insertVideo(this.tooltip, 'http://m.youtube.com/watch?v=QHH3iSeDBLo'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'http://www.youtube.com/embed/QHH3iSeDBLo', - ); - }); - - it('preserves youtube video url protocol', function () { - insertVideo(this.tooltip, 'https://m.youtube.com/watch?v=QHH3iSeDBLo'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'https://www.youtube.com/embed/QHH3iSeDBLo', - ); - }); - - it('uses https as default youtube video url protocol', function () { - insertVideo(this.tooltip, 'youtube.com/watch?v=QHH3iSeDBLo'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'https://www.youtube.com/embed/QHH3iSeDBLo', - ); - }); - - it('converts vimeo video url to embedded', function () { - insertVideo(this.tooltip, 'http://vimeo.com/47762693'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'http://player.vimeo.com/video/47762693/', - ); - }); - - it('converts www.vimeo video url to embedded', function () { - insertVideo(this.tooltip, 'http://www.vimeo.com/47762693'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'http://player.vimeo.com/video/47762693/', - ); - }); - - it('preserves vimeo video url protocol', function () { - insertVideo(this.tooltip, 'https://www.vimeo.com/47762693'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'https://player.vimeo.com/video/47762693/', - ); - }); - - it('uses https as default vimeo video url protocol', function () { - insertVideo(this.tooltip, 'vimeo.com/47762693'); - expect(this.container.querySelector('.ql-video').src).toContain( - 'https://player.vimeo.com/video/47762693/', - ); - }); - - function insertVideo(tooltip, url) { - tooltip.textbox.value = url; - tooltip.root.setAttribute('data-mode', 'video'); - tooltip.save(); - } - }); -}); diff --git a/test/unit/theme/base/tooltip.spec.ts b/test/unit/theme/base/tooltip.spec.ts new file mode 100644 index 0000000000..7568c4be4b --- /dev/null +++ b/test/unit/theme/base/tooltip.spec.ts @@ -0,0 +1,98 @@ +import { describe, expect, test } from 'vitest'; +import Quill from '../../../../core'; +import Video from '../../../../formats/video'; +import { BaseTooltip } from '../../../../themes/base'; +import { createRegistry } from '../../__helpers__/factory'; + +class Tooltip extends BaseTooltip { + static TEMPLATE = ''; +} + +describe('BaseTooltip', () => { + const setup = () => { + const container = document.body.appendChild(document.createElement('div')); + const quill = new Quill(container, { registry: createRegistry([Video]) }); + const tooltip = new Tooltip(quill); + return { container, tooltip }; + }; + + const insertVideo = (tooltip: Tooltip, url: string) => { + (tooltip.textbox as HTMLInputElement).value = url; + tooltip.root.setAttribute('data-mode', 'video'); + tooltip.save(); + }; + + describe('save', () => { + test('converts youtube video url to embedded', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'http://youtube.com/watch?v=QHH3iSeDBLo'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('http://www.youtube.com/embed/QHH3iSeDBLo'); + }); + + test('converts www.youtube video url to embedded', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'http://www.youtube.com/watch?v=QHH3iSeDBLo'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('http://www.youtube.com/embed/QHH3iSeDBLo'); + }); + + test('converts m.youtube video url to embedded', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'http://m.youtube.com/watch?v=QHH3iSeDBLo'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('http://www.youtube.com/embed/QHH3iSeDBLo'); + }); + + test('preserves youtube video url protocol', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'https://m.youtube.com/watch?v=QHH3iSeDBLo'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('https://www.youtube.com/embed/QHH3iSeDBLo'); + }); + + test('uses https as default youtube video url protocol', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'youtube.com/watch?v=QHH3iSeDBLo'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('https://www.youtube.com/embed/QHH3iSeDBLo'); + }); + + test('converts vimeo video url to embedded', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'http://vimeo.com/47762693'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('http://player.vimeo.com/video/47762693/'); + }); + + test('converts www.vimeo video url to embedded', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'http://www.vimeo.com/47762693'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('http://player.vimeo.com/video/47762693/'); + }); + + test('preserves vimeo video url protocol', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'https://www.vimeo.com/47762693'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('https://player.vimeo.com/video/47762693/'); + }); + + test('uses https as default vimeo video url protocol', () => { + const { container, tooltip } = setup(); + insertVideo(tooltip, 'vimeo.com/47762693'); + expect( + (container.querySelector('.ql-video') as HTMLVideoElement).src, + ).toContain('https://player.vimeo.com/video/47762693/'); + }); + }); +}); From 0775c7de2e9385ba9903897c20081c17e87184c1 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:27:50 +0800 Subject: [PATCH 07/18] Migrate modules to Vitest --- .../{clipboard.js => clipboard.spec.ts} | 342 ++++++++++-------- test/unit/modules/history.js | 264 -------------- test/unit/modules/history.spec.ts | 270 ++++++++++++++ test/unit/modules/keyboard.js | 161 --------- test/unit/modules/keyboard.spec.ts | 70 ++++ test/unit/modules/syntax.js | 305 ---------------- test/unit/modules/syntax.spec.ts | 299 +++++++++++++++ test/unit/modules/table.js | 170 --------- test/unit/modules/table.spec.ts | 218 +++++++++++ .../{tableEmbed.js => tableEmbed.spec.ts} | 37 +- .../modules/{toolbar.js => toolbar.spec.ts} | 142 +++++--- 11 files changed, 1166 insertions(+), 1112 deletions(-) rename test/unit/modules/{clipboard.js => clipboard.spec.ts} (51%) delete mode 100644 test/unit/modules/history.js create mode 100644 test/unit/modules/history.spec.ts delete mode 100644 test/unit/modules/keyboard.js create mode 100644 test/unit/modules/keyboard.spec.ts delete mode 100644 test/unit/modules/syntax.js create mode 100644 test/unit/modules/syntax.spec.ts delete mode 100644 test/unit/modules/table.js create mode 100644 test/unit/modules/table.spec.ts rename test/unit/modules/{tableEmbed.js => tableEmbed.spec.ts} (94%) rename test/unit/modules/{toolbar.js => toolbar.spec.ts} (56%) diff --git a/test/unit/modules/clipboard.js b/test/unit/modules/clipboard.spec.ts similarity index 51% rename from test/unit/modules/clipboard.js rename to test/unit/modules/clipboard.spec.ts index 5467cf0797..e610a468f6 100644 --- a/test/unit/modules/clipboard.js +++ b/test/unit/modules/clipboard.spec.ts @@ -1,157 +1,199 @@ import Delta from 'quill-delta'; -import { Range } from '../../../core/selection'; +import { describe, expect, test, vitest } from 'vitest'; import Quill from '../../../core'; - -describe('Clipboard', function () { - describe('events', function () { - beforeEach(function () { - this.quill = this.initialize(Quill, '

0123

5678

'); - this.quill.setSelection(2, 5); - }); - - describe('paste', function () { - beforeAll(function () { - this.clipboardEvent = { - clipboardData: { - getData: type => - type === 'text/html' ? '|' : '|', - }, - preventDefault: () => {}, - }; - }); - - it('pastes html data', function (done) { - this.quill.clipboard.onCapturePaste(this.clipboardEvent); - setTimeout(() => { - expect(this.quill.root).toEqualHTML( - '

01|78

', - ); - expect(this.quill.getSelection()).toEqual(new Range(3)); - done(); - }, 2); +import { Range } from '../../../core/selection'; +import Bold from '../../../formats/bold'; +import Header from '../../../formats/header'; +import Image from '../../../formats/image'; +import IndentClass from '../../../formats/indent'; +import Italic from '../../../formats/italic'; +import Link from '../../../formats/link'; +import List, { ListContainer } from '../../../formats/list'; +import { + TableBody, + TableCell, + TableContainer, + TableRow, +} from '../../../formats/table'; +import Video from '../../../formats/video'; +import { createRegistry } from '../__helpers__/factory'; +import { sleep } from '../__helpers__/utils'; + +describe('Clipboard', () => { + describe('events', () => { + const createQuill = () => { + const container = document.body.appendChild( + document.createElement('div'), + ); + container.innerHTML = '

0123

5678

'; + const registry = createRegistry([Bold, Italic, Header]); + const quill = new Quill(container, { registry }); + quill.setSelection(2, 5); + return quill; + }; + + describe('paste', () => { + const clipboardEvent = { + clipboardData: { + getData: (type: string) => + type === 'text/html' ? '|' : '|', + }, + preventDefault: () => {}, + } as ClipboardEvent; + + test('pastes html data', async () => { + const quill = createQuill(); + quill.clipboard.onCapturePaste(clipboardEvent); + await sleep(2); + expect(quill.scroll).toMatchInlineSnapshot( + '

01|78

', + ); + expect(quill.getSelection()).toEqual(new Range(3)); }); // Copying from Word includes both html and files - it('pastes html data if present with file', function (done) { - const upload = spyOn(this.quill.uploader, 'upload'); - this.quill.clipboard.onCapturePaste({ - ...this.clipboardEvent, + test('pastes html data if present with file', async () => { + const quill = createQuill(); + const upload = vitest.spyOn(quill.uploader, 'upload'); + quill.clipboard.onCapturePaste({ + ...clipboardEvent, clipboardData: { - ...this.clipboardEvent.clipboardData, + ...clipboardEvent.clipboardData, + // @ts-expect-error files: ['file'], }, }); - setTimeout(() => { - expect(upload).not.toHaveBeenCalled(); - expect(this.quill.root).toEqualHTML( - '

01|78

', - ); - expect(this.quill.getSelection()).toEqual(new Range(3)); - done(); - }, 2); + await sleep(2); + expect(upload).not.toHaveBeenCalled(); + expect(quill.scroll).toMatchInlineSnapshot( + '

01|78

', + ); + expect(quill.getSelection()).toEqual(new Range(3)); }); - it('pastes image file if present with image only html', function (done) { - const upload = spyOn(this.quill.uploader, 'upload'); - this.quill.clipboard.onCapturePaste({ - ...this.clipboardEvent, + test('pastes image file if present with image only html', async () => { + const quill = createQuill(); + const upload = vitest.spyOn(quill.uploader, 'upload'); + quill.clipboard.onCapturePaste({ + ...clipboardEvent, clipboardData: { getData: type => type === 'text/html' ? `` : '|', + // @ts-expect-error files: ['file'], }, }); - setTimeout(() => { - expect(upload).toHaveBeenCalled(); - done(); - }, 2); + await sleep(2); + expect(upload).toHaveBeenCalled(); }); - it('does not fire selection-change', function (done) { - const change = jasmine.createSpy('change'); - this.quill.on('selection-change', change); - this.quill.clipboard.onCapturePaste(this.clipboardEvent); - setTimeout(function () { - expect(change).not.toHaveBeenCalled(); - done(); - }, 2); + test('does not fire selection-change', async () => { + const quill = createQuill(); + const change = vitest.fn(); + quill.on('selection-change', change); + quill.clipboard.onCapturePaste(clipboardEvent); + await sleep(2); + expect(change).not.toHaveBeenCalled(); }); }); describe('cut', () => { - beforeEach(function () { - this.clipboardData = {}; - this.clipboardEvent = { + const setup = () => { + const clipboardData = {}; + const clipboardEvent = { clipboardData: { setData: (type, data) => { - this.clipboardData[type] = data; + clipboardData[type] = data; }, }, preventDefault: () => {}, - }; - }); - - it('keeps formats of first line', function (done) { - this.quill.clipboard.onCaptureCopy(this.clipboardEvent, true); - setTimeout(() => { - expect(this.quill.root).toEqualHTML('

0178

'); - expect(this.quill.getSelection()).toEqual(new Range(2)); - expect(this.clipboardData['text/plain']).toEqual('23\n56'); - expect(this.clipboardData['text/html']).toEqual( - '

23

56

', - ); - done(); - }, 2); + } as ClipboardEvent; + return { clipboardData, clipboardEvent }; + }; + + test('keeps formats of first line', async () => { + const quill = createQuill(); + const { clipboardData, clipboardEvent } = setup(); + quill.clipboard.onCaptureCopy(clipboardEvent, true); + await sleep(2); + expect(quill.scroll).toMatchInlineSnapshot('

0178

'); + expect(quill.getSelection()).toEqual(new Range(2)); + expect(clipboardData['text/plain']).toEqual('23\n56'); + expect(clipboardData['text/html']).toEqual( + '

23

56

', + ); }); }); - it('dangerouslyPasteHTML(html)', function () { - this.quill.clipboard.dangerouslyPasteHTML('abcd'); - expect(this.quill.root).toEqualHTML( + test('dangerouslyPasteHTML(html)', () => { + const quill = createQuill(); + quill.clipboard.dangerouslyPasteHTML('abcd'); + expect(quill.scroll).toMatchInlineSnapshot( '

abcd

', ); }); - it('dangerouslyPasteHTML(index, html)', function () { - this.quill.clipboard.dangerouslyPasteHTML(2, 'ab'); - expect(this.quill.root).toEqualHTML( - '

01ab23

5678

', - ); + test('dangerouslyPasteHTML(index, html)', () => { + const quill = createQuill(); + quill.clipboard.dangerouslyPasteHTML(2, 'ab'); + expect(quill.scroll).toMatchInlineSnapshot(` +

01ab23

+

5678

+ `); }); }); - describe('convert', function () { - beforeEach(function () { - const quill = this.initialize(Quill, ''); - this.clipboard = quill.clipboard; - }); - - it('plain text', function () { - const delta = this.clipboard.convert({ html: 'simple plain text' }); + describe('convert', () => { + const createClipboard = () => { + const container = document.body.appendChild( + document.createElement('div'), + ); + const registry = createRegistry([ + Bold, + Italic, + Header, + TableBody, + TableContainer, + TableCell, + TableRow, + ListContainer, + List, + IndentClass, + Image, + Video, + Link, + ]); + const quill = new Quill(container, { registry }); + quill.setSelection(2, 5); + return quill.clipboard; + }; + + test('plain text', () => { + const delta = createClipboard().convert({ html: 'simple plain text' }); expect(delta).toEqual(new Delta().insert('simple plain text')); }); - it('whitespace', function () { + test('whitespace', () => { const html = '
0
1 2 3 4
' + '
5 6 7 8
'; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual(new Delta().insert('0\n1 2 3 4\n5 6 7 8')); }); - it('inline whitespace', function () { + test('inline whitespace', () => { const html = '

0 1 2

'; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual( new Delta().insert('0 ').insert('1', { bold: true }).insert(' 2'), ); }); - it('intentional whitespace', function () { + test('intentional whitespace', () => { const html = '1 2'; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual( new Delta() .insert('0\u00a0') @@ -160,24 +202,24 @@ describe('Clipboard', function () { ); }); - it('consecutive intentional whitespace', function () { + test('consecutive intentional whitespace', () => { const html = '  1  '; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual( new Delta().insert('\u00a0\u00a01\u00a0\u00a0', { bold: true }), ); }); - it('break', function () { + test('break', () => { const html = '
0
1
2
3

4

5
'; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual(new Delta().insert('0\n1\n2\n3\n\n4\n\n5')); }); - it('empty block', function () { + test('empty block', () => { const html = '

Test

Body

'; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual( new Delta() .insert('Test\n', { header: 1 }) @@ -186,15 +228,15 @@ describe('Clipboard', function () { ); }); - it('mixed inline and block', function () { - const delta = this.clipboard.convert({ + test('mixed inline and block', () => { + const delta = createClipboard().convert({ html: '
One
Two
', }); expect(delta).toEqual(new Delta().insert('One\nTwo')); }); - it('alias', function () { - const delta = this.clipboard.convert({ + test('alias', () => { + const delta = createClipboard().convert({ html: 'BoldItalic', }); expect(delta).toEqual( @@ -204,24 +246,24 @@ describe('Clipboard', function () { ); }); - it('pre', function () { + test('pre', () => { const html = '
 01 \n 23 
'; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual( new Delta().insert(' 01 \n 23 \n', { 'code-block': true }), ); }); - it('pre with \\n node', function () { + test('pre with \\n node', () => { const html = '
 01 \n 23 
'; - const delta = this.clipboard.convert({ html }); + const delta = createClipboard().convert({ html }); expect(delta).toEqual( new Delta().insert(' 01 \n 23 \n', { 'code-block': true }), ); }); - it('nested list', function () { - const delta = this.clipboard.convert({ + test('nested list', () => { + const delta = createClipboard().convert({ html: '
  1. One
  2. Alpha
', }); expect(delta).toEqual( @@ -231,8 +273,8 @@ describe('Clipboard', function () { ); }); - it('html nested list', function () { - const delta = this.clipboard.convert({ + test('html nested list', () => { + const delta = createClipboard().convert({ html: '
  1. One
    1. Alpha
    2. Beta
      1. I
', }); expect(delta).toEqual( @@ -243,8 +285,8 @@ describe('Clipboard', function () { ); }); - it('html nested bullet', function () { - const delta = this.clipboard.convert({ + test('html nested bullet', () => { + const delta = createClipboard().convert({ html: '
  • One
    • Alpha
    • Beta
      • I
', }); expect(delta).toEqual( @@ -255,8 +297,8 @@ describe('Clipboard', function () { ); }); - it('html nested checklist', function () { - const delta = this.clipboard.convert({ + test('html nested checklist', () => { + const delta = createClipboard().convert({ html: '
  • One
    • Alpha
    • Beta' + '
      • I
', @@ -269,8 +311,8 @@ describe('Clipboard', function () { ); }); - it('html partial list', function () { - const delta = this.clipboard.convert({ + test('html partial list', () => { + const delta = createClipboard().convert({ html: '
      1. iiii
    1. bbbb
  1. 2222
', }); expect(delta).toEqual( @@ -281,8 +323,8 @@ describe('Clipboard', function () { ); }); - it('html table', function () { - const delta = this.clipboard.convert({ + test('html table', () => { + const delta = createClipboard().convert({ html: '' + '' + @@ -296,8 +338,8 @@ describe('Clipboard', function () { ); }); - it('embeds', function () { - const delta = this.clipboard.convert({ + test('embeds', () => { + const delta = createClipboard().convert({ html: '
0134
', }); const expected = new Delta() @@ -310,8 +352,8 @@ describe('Clipboard', function () { expect(delta).toEqual(expected); }); - it('block embed', function () { - const delta = this.clipboard.convert({ + test('block embed', () => { + const delta = createClipboard().convert({ html: '

01

34

', }); expect(delta).toEqual( @@ -319,8 +361,8 @@ describe('Clipboard', function () { ); }); - it('block embeds within blocks', function () { - const delta = this.clipboard.convert({ + test('block embeds within blocks', () => { + const delta = createClipboard().convert({ html: '

0134

67

', }); expect(delta).toEqual( @@ -332,8 +374,8 @@ describe('Clipboard', function () { ); }); - it('wrapped block embed', function () { - const delta = this.clipboard.convert({ + test('wrapped block embed', () => { + const delta = createClipboard().convert({ html: '

0134

67

', }); expect(delta).toEqual( @@ -345,8 +387,8 @@ describe('Clipboard', function () { ); }); - it('wrapped block embed with siblings', function () { - const delta = this.clipboard.convert({ + test('wrapped block embed with siblings', () => { + const delta = createClipboard().convert({ html: '

01ab34

67

', }); expect(delta).toEqual( @@ -360,35 +402,36 @@ describe('Clipboard', function () { ); }); - it('attributor and style match', function () { - const delta = this.clipboard.convert({ + test('attributor and style match', () => { + const delta = createClipboard().convert({ html: '

Test

', }); expect(delta).toEqual(new Delta().insert('Test\n', { direction: 'rtl' })); }); - it('nested styles', function () { - const delta = this.clipboard.convert({ + test('nested styles', () => { + const delta = createClipboard().convert({ html: 'Test', }); expect(delta).toEqual(new Delta().insert('Test', { color: 'blue' })); }); - it('custom matcher', function () { - this.clipboard.addMatcher(Node.TEXT_NODE, function (node, delta) { + test('custom matcher', () => { + const clipboard = createClipboard(); + clipboard.addMatcher(Node.TEXT_NODE, (node, delta) => { let index = 0; const regex = /https?:\/\/[^\s]+/g; - let match = null; + let match: RegExpExecArray | null = null; const composer = new Delta(); // eslint-disable-next-line no-cond-assign - while ((match = regex.exec(node.data))) { + while ((match = regex.exec((node as Text).data))) { composer.retain(match.index - index); index = regex.lastIndex; composer.retain(match[0].length, { link: match[0] }); } return delta.compose(composer); }); - const delta = this.clipboard.convert({ + const delta = clipboard.convert({ html: 'http://github.com https://quilljs.com', }); const expected = new Delta() @@ -398,17 +441,20 @@ describe('Clipboard', function () { expect(delta).toEqual(expected); }); - it('does not execute javascript', function () { - window.unsafeFunction = jasmine.createSpy('unsafeFunction'); + test('does not execute javascript', () => { + // @ts-expect-error + window.unsafeFunction = vitest.fn(); const html = ""; - this.clipboard.convert({ html }); + createClipboard().convert({ html }); + // @ts-expect-error expect(window.unsafeFunction).not.toHaveBeenCalled(); + // @ts-expect-error delete window.unsafeFunction; }); - it('xss', function () { - const delta = this.clipboard.convert({ + test('xss', () => { + const delta = createClipboard().convert({ html: '', }); expect(delta).toEqual(new Delta().insert('')); diff --git a/test/unit/modules/history.js b/test/unit/modules/history.js deleted file mode 100644 index d961c823c4..0000000000 --- a/test/unit/modules/history.js +++ /dev/null @@ -1,264 +0,0 @@ -import Delta from 'quill-delta'; -import Quill from '../../../core'; -import { globalRegistry } from '../../../core/quill'; -import { getLastChangeIndex } from '../../../modules/history'; - -describe('History', function () { - describe('getLastChangeIndex', function () { - it('delete', function () { - const delta = new Delta().retain(4).delete(2); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(4); - }); - - it('delete with inserts', function () { - const delta = new Delta().retain(4).insert('test').delete(2); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(8); - }); - - it('insert text', function () { - const delta = new Delta().retain(4).insert('testing'); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(11); - }); - - it('insert embed', function () { - const delta = new Delta().retain(4).insert({ image: true }); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(5); - }); - - it('insert with deletes', function () { - const delta = new Delta().retain(4).delete(3).insert('!'); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(5); - }); - - it('format', function () { - const delta = new Delta().retain(4).retain(3, { bold: true }); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(7); - }); - - it('format newline', function () { - const delta = new Delta().retain(4).retain(1, { align: 'left' }); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(4); - }); - - it('format mixed', function () { - const delta = new Delta() - .retain(4) - .retain(1, { align: 'left', bold: true }); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(4); - }); - - it('insert newline', function () { - const delta = new Delta().retain(4).insert('a\n'); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(5); - }); - - it('mutliple newline inserts', function () { - const delta = new Delta().retain(4).insert('ab\n\n'); - expect(getLastChangeIndex(globalRegistry, delta)).toEqual(7); - }); - }); - - describe('undo/redo', function () { - beforeEach(function () { - this.initialize(HTMLElement, '

The lazy fox

'); - this.quill = new Quill(this.container.firstChild, { - modules: { - history: { delay: 400 }, - }, - }); - this.original = this.quill.getContents(); - }); - - it('limits undo stack size', function () { - const quill = new Quill(this.container.firstChild, { - modules: { - history: { delay: 0, maxStack: 2 }, - }, - }); - ['A', 'B', 'C'].forEach(function (text) { - quill.insertText(0, text); - }); - expect(quill.history.stack.undo.length).toEqual(2); - }); - - it('emits selection changes', function () { - const quill = new Quill(this.container.firstChild, { - modules: { - history: { delay: 0 }, - }, - }); - quill.insertText(0, 'foo'); - const change = jasmine.createSpy('change'); - quill.on('selection-change', change); - quill.history.undo(); - - expect(change).toHaveBeenCalledOnceWith(jasmine.anything(), null, 'user'); - }); - - it('user change', function () { - this.quill.root.firstChild.innerHTML = 'The lazy foxes'; - this.quill.update(); - const changed = this.quill.getContents(); - expect(changed).not.toEqual(this.original); - this.quill.history.undo(); - expect(this.quill.getContents()).toEqual(this.original); - this.quill.history.redo(); - expect(this.quill.getContents()).toEqual(changed); - }); - - it('merge changes', function () { - expect(this.quill.history.stack.undo.length).toEqual(0); - this.quill.updateContents(new Delta().retain(12).insert('e')); - expect(this.quill.history.stack.undo.length).toEqual(1); - this.quill.updateContents(new Delta().retain(13).insert('s')); - expect(this.quill.history.stack.undo.length).toEqual(1); - this.quill.history.undo(); - expect(this.quill.getContents()).toEqual(this.original); - expect(this.quill.history.stack.undo.length).toEqual(0); - }); - - it('dont merge changes', function (done) { - expect(this.quill.history.stack.undo.length).toEqual(0); - this.quill.updateContents(new Delta().retain(12).insert('e')); - expect(this.quill.history.stack.undo.length).toEqual(1); - setTimeout(() => { - this.quill.updateContents(new Delta().retain(13).insert('s')); - expect(this.quill.history.stack.undo.length).toEqual(2); - done(); - }, this.quill.history.options.delay * 1.25); - }); - - it('multiple undos', function (done) { - expect(this.quill.history.stack.undo.length).toEqual(0); - this.quill.updateContents(new Delta().retain(12).insert('e')); - const contents = this.quill.getContents(); - setTimeout(() => { - this.quill.updateContents(new Delta().retain(13).insert('s')); - this.quill.history.undo(); - expect(this.quill.getContents()).toEqual(contents); - this.quill.history.undo(); - expect(this.quill.getContents()).toEqual(this.original); - done(); - }, this.quill.history.options.delay * 1.25); - }); - - it('transform api change', function () { - this.quill.history.options.userOnly = true; - this.quill.updateContents( - new Delta().retain(12).insert('es'), - Quill.sources.USER, - ); - this.quill.history.lastRecorded = 0; - this.quill.updateContents( - new Delta().retain(14).insert('!'), - Quill.sources.USER, - ); - this.quill.history.undo(); - this.quill.updateContents( - new Delta().retain(4).delete(5), - Quill.sources.API, - ); - expect(this.quill.getContents()).toEqual( - new Delta().insert('The foxes\n'), - ); - this.quill.history.undo(); - expect(this.quill.getContents()).toEqual(new Delta().insert('The fox\n')); - this.quill.history.redo(); - expect(this.quill.getContents()).toEqual( - new Delta().insert('The foxes\n'), - ); - this.quill.history.redo(); - expect(this.quill.getContents()).toEqual( - new Delta().insert('The foxes!\n'), - ); - }); - - it('transform preserve intention', function () { - const url = 'https://www.google.com/'; - this.quill.history.options.userOnly = true; - this.quill.updateContents( - new Delta().insert(url, { link: url }), - Quill.sources.USER, - ); - this.quill.history.lastRecorded = 0; - this.quill.updateContents( - new Delta().delete(url.length).insert('Google', { link: url }), - Quill.sources.API, - ); - this.quill.history.lastRecorded = 0; - this.quill.updateContents( - new Delta().retain(this.quill.getLength() - 1).insert('!'), - Quill.sources.USER, - ); - this.quill.history.lastRecorded = 0; - expect(this.quill.getContents()).toEqual( - new Delta().insert('Google', { link: url }).insert('The lazy fox!\n'), - ); - this.quill.history.undo(); - expect(this.quill.getContents()).toEqual( - new Delta().insert('Google', { link: url }).insert('The lazy fox\n'), - ); - this.quill.history.undo(); - expect(this.quill.getContents()).toEqual( - new Delta().insert('Google', { link: url }).insert('The lazy fox\n'), - ); - }); - - it('ignore remote changes', function () { - this.quill.history.options.delay = 0; - this.quill.history.options.userOnly = true; - this.quill.setText('\n'); - this.quill.insertText(0, 'a', Quill.sources.USER); - this.quill.insertText(1, 'b', Quill.sources.API); - this.quill.insertText(2, 'c', Quill.sources.USER); - this.quill.insertText(3, 'd', Quill.sources.API); - expect(this.quill.getText()).toEqual('abcd\n'); - this.quill.history.undo(); - expect(this.quill.getText()).toEqual('abd\n'); - this.quill.history.undo(); - expect(this.quill.getText()).toEqual('bd\n'); - this.quill.history.redo(); - expect(this.quill.getText()).toEqual('abd\n'); - this.quill.history.redo(); - expect(this.quill.getText()).toEqual('abcd\n'); - }); - - it('correctly transform against remote changes', function () { - this.quill.history.options.delay = 0; - this.quill.history.options.userOnly = true; - this.quill.setText('b\n'); - this.quill.insertText(1, 'd', Quill.sources.USER); - this.quill.insertText(0, 'a', Quill.sources.USER); - this.quill.insertText(2, 'c', Quill.sources.API); - expect(this.quill.getText()).toEqual('abcd\n'); - this.quill.history.undo(); - expect(this.quill.getText()).toEqual('bcd\n'); - this.quill.history.undo(); - expect(this.quill.getText()).toEqual('bc\n'); - this.quill.history.redo(); - expect(this.quill.getText()).toEqual('bcd\n'); - this.quill.history.redo(); - expect(this.quill.getText()).toEqual('abcd\n'); - }); - - it('correctly transform against remote changes breaking up an insert', function () { - this.quill.history.options.delay = 0; - this.quill.history.options.userOnly = true; - this.quill.setText('\n'); - this.quill.insertText(0, 'ABC', Quill.sources.USER); - this.quill.insertText(3, '4', Quill.sources.API); - this.quill.insertText(2, '3', Quill.sources.API); - this.quill.insertText(1, '2', Quill.sources.API); - this.quill.insertText(0, '1', Quill.sources.API); - expect(this.quill.getText()).toEqual('1A2B3C4\n'); - this.quill.history.undo(); - expect(this.quill.getText()).toEqual('1234\n'); - this.quill.history.redo(); - expect(this.quill.getText()).toEqual('1A2B3C4\n'); - this.quill.history.undo(); - expect(this.quill.getText()).toEqual('1234\n'); - this.quill.history.redo(); - expect(this.quill.getText()).toEqual('1A2B3C4\n'); - }); - }); -}); diff --git a/test/unit/modules/history.spec.ts b/test/unit/modules/history.spec.ts new file mode 100644 index 0000000000..ebf6aceeef --- /dev/null +++ b/test/unit/modules/history.spec.ts @@ -0,0 +1,270 @@ +import Delta from 'quill-delta'; +import { describe, expect, test, vitest } from 'vitest'; +import Quill from '../../../core'; +import { HistoryOptions, getLastChangeIndex } from '../../../modules/history'; +import { createRegistry, createScroll } from '../__helpers__/factory'; +import { sleep } from '../__helpers__/utils'; +import Bold from '../../../formats/bold'; +import Image from '../../../formats/image'; +import Link from '../../../formats/link'; +import { AlignClass } from '../../../formats/align'; + +describe('History', () => { + const scroll = createScroll( + '', + createRegistry([Bold, Image, Link, AlignClass]), + ); + + describe('getLastChangeIndex', () => { + test('delete', () => { + const delta = new Delta().retain(4).delete(2); + expect(getLastChangeIndex(scroll, delta)).toEqual(4); + }); + + test('delete with inserts', () => { + const delta = new Delta().retain(4).insert('test').delete(2); + expect(getLastChangeIndex(scroll, delta)).toEqual(8); + }); + + test('insert text', () => { + const delta = new Delta().retain(4).insert('testing'); + expect(getLastChangeIndex(scroll, delta)).toEqual(11); + }); + + test('insert embed', () => { + const delta = new Delta().retain(4).insert({ image: true }); + expect(getLastChangeIndex(scroll, delta)).toEqual(5); + }); + + test('insert with deletes', () => { + const delta = new Delta().retain(4).delete(3).insert('!'); + expect(getLastChangeIndex(scroll, delta)).toEqual(5); + }); + + test('format', () => { + const delta = new Delta().retain(4).retain(3, { bold: true }); + expect(getLastChangeIndex(scroll, delta)).toEqual(7); + }); + + test('format newline', () => { + const delta = new Delta().retain(4).retain(1, { align: 'left' }); + expect(getLastChangeIndex(scroll, delta)).toEqual(4); + }); + + test('format mixed', () => { + const delta = new Delta() + .retain(4) + .retain(1, { align: 'left', bold: true }); + expect(getLastChangeIndex(scroll, delta)).toEqual(4); + }); + + test('insert newline', () => { + const delta = new Delta().retain(4).insert('a\n'); + expect(getLastChangeIndex(scroll, delta)).toEqual(5); + }); + + test('mutliple newline inserts', () => { + const delta = new Delta().retain(4).insert('ab\n\n'); + expect(getLastChangeIndex(scroll, delta)).toEqual(7); + }); + }); + + describe('undo/redo', () => { + const setup = (options?: Partial) => { + const container = document.body.appendChild( + document.createElement('div'), + ); + container.innerHTML = '

The lazy fox

'; + const quill = new Quill(container, { + modules: { + history: { delay: 400, ...options }, + }, + registry: scroll.registry, + }); + return { quill, original: quill.getContents() }; + }; + + test('limits undo stack size', () => { + const { quill } = setup({ delay: 0, maxStack: 2 }); + ['A', 'B', 'C'].forEach(text => { + // @ts-expect-error + quill.insertText(0, text); + }); + expect(quill.history.stack.undo.length).toEqual(2); + }); + + test('emits selection changes', () => { + const { quill } = setup({ delay: 0 }); + // @ts-expect-error + quill.insertText(0, 'foo'); + const change = vitest.fn(); + quill.on('selection-change', change); + quill.history.undo(); + + expect(change).toHaveBeenCalledOnce(); + expect(change).toHaveBeenCalledWith(expect.anything(), null, 'user'); + }); + + test('user change', () => { + const { quill, original } = setup({ delay: 0 }); + (quill.root.firstChild as HTMLElement).innerHTML = 'The lazy foxes'; + quill.update(); + const changed = quill.getContents(); + expect(changed).not.toEqual(original); + quill.history.undo(); + expect(quill.getContents()).toEqual(original); + quill.history.redo(); + expect(quill.getContents()).toEqual(changed); + }); + + test('merge changes', () => { + const { quill, original } = setup(); + expect(quill.history.stack.undo.length).toEqual(0); + quill.updateContents(new Delta().retain(12).insert('e')); + expect(quill.history.stack.undo.length).toEqual(1); + quill.updateContents(new Delta().retain(13).insert('s')); + expect(quill.history.stack.undo.length).toEqual(1); + quill.history.undo(); + expect(quill.getContents()).toEqual(original); + expect(quill.history.stack.undo.length).toEqual(0); + }); + + test('dont merge changes', async () => { + const { quill } = setup(); + expect(quill.history.stack.undo.length).toEqual(0); + quill.updateContents(new Delta().retain(12).insert('e')); + expect(quill.history.stack.undo.length).toEqual(1); + // @ts-expect-error + await sleep((quill.history.options.delay as number) * 1.25); + quill.updateContents(new Delta().retain(13).insert('s')); + expect(quill.history.stack.undo.length).toEqual(2); + }); + + test('multiple undos', async () => { + const { quill, original } = setup(); + expect(quill.history.stack.undo.length).toEqual(0); + quill.updateContents(new Delta().retain(12).insert('e')); + const contents = quill.getContents(); + // @ts-expect-error + await sleep((quill.history.options.delay as number) * 1.25); + quill.updateContents(new Delta().retain(13).insert('s')); + quill.history.undo(); + expect(quill.getContents()).toEqual(contents); + quill.history.undo(); + expect(quill.getContents()).toEqual(original); + }); + + test('transform api change', () => { + const { quill } = setup(); + // @ts-expect-error + quill.history.options.userOnly = true; + quill.updateContents( + new Delta().retain(12).insert('es'), + Quill.sources.USER, + ); + quill.history.lastRecorded = 0; + quill.updateContents( + new Delta().retain(14).insert('!'), + Quill.sources.USER, + ); + quill.history.undo(); + quill.updateContents(new Delta().retain(4).delete(5), Quill.sources.API); + expect(quill.getContents()).toEqual(new Delta().insert('The foxes\n')); + quill.history.undo(); + expect(quill.getContents()).toEqual(new Delta().insert('The fox\n')); + quill.history.redo(); + expect(quill.getContents()).toEqual(new Delta().insert('The foxes\n')); + quill.history.redo(); + expect(quill.getContents()).toEqual(new Delta().insert('The foxes!\n')); + }); + + test('transform preserve intention', () => { + const { quill } = setup({ userOnly: true }); + const url = 'https://www.google.com/'; + quill.updateContents( + new Delta().insert(url, { link: url }), + Quill.sources.USER, + ); + quill.history.lastRecorded = 0; + quill.updateContents( + new Delta().delete(url.length).insert('Google', { link: url }), + Quill.sources.API, + ); + quill.history.lastRecorded = 0; + quill.updateContents( + new Delta().retain(quill.getLength() - 1).insert('!'), + Quill.sources.USER, + ); + quill.history.lastRecorded = 0; + expect(quill.getContents()).toEqual( + new Delta().insert('Google', { link: url }).insert('The lazy fox!\n'), + ); + quill.history.undo(); + expect(quill.getContents()).toEqual( + new Delta().insert('Google', { link: url }).insert('The lazy fox\n'), + ); + quill.history.undo(); + expect(quill.getContents()).toEqual( + new Delta().insert('Google', { link: url }).insert('The lazy fox\n'), + ); + }); + + test('ignore remote changes', () => { + const { quill } = setup(); + // @ts-expect-error + quill.history.options.delay = 0; + // @ts-expect-error + quill.history.options.userOnly = true; + quill.setText('\n'); + quill.insertText(0, 'a', Quill.sources.USER); + quill.insertText(1, 'b', Quill.sources.API); + quill.insertText(2, 'c', Quill.sources.USER); + quill.insertText(3, 'd', Quill.sources.API); + expect(quill.getText()).toEqual('abcd\n'); + quill.history.undo(); + expect(quill.getText()).toEqual('abd\n'); + quill.history.undo(); + expect(quill.getText()).toEqual('bd\n'); + quill.history.redo(); + expect(quill.getText()).toEqual('abd\n'); + quill.history.redo(); + expect(quill.getText()).toEqual('abcd\n'); + }); + + test('correctly transform against remote changes', () => { + const { quill } = setup({ delay: 0, userOnly: true }); + quill.setText('b\n'); + quill.insertText(1, 'd', Quill.sources.USER); + quill.insertText(0, 'a', Quill.sources.USER); + quill.insertText(2, 'c', Quill.sources.API); + expect(quill.getText()).toEqual('abcd\n'); + quill.history.undo(); + expect(quill.getText()).toEqual('bcd\n'); + quill.history.undo(); + expect(quill.getText()).toEqual('bc\n'); + quill.history.redo(); + expect(quill.getText()).toEqual('bcd\n'); + quill.history.redo(); + expect(quill.getText()).toEqual('abcd\n'); + }); + + test('correctly transform against remote changes breaking up an insert', () => { + const { quill } = setup({ delay: 0, userOnly: true }); + quill.setText('\n'); + quill.insertText(0, 'ABC', Quill.sources.USER); + quill.insertText(3, '4', Quill.sources.API); + quill.insertText(2, '3', Quill.sources.API); + quill.insertText(1, '2', Quill.sources.API); + quill.insertText(0, '1', Quill.sources.API); + expect(quill.getText()).toEqual('1A2B3C4\n'); + quill.history.undo(); + expect(quill.getText()).toEqual('1234\n'); + quill.history.redo(); + expect(quill.getText()).toEqual('1A2B3C4\n'); + quill.history.undo(); + expect(quill.getText()).toEqual('1234\n'); + quill.history.redo(); + expect(quill.getText()).toEqual('1A2B3C4\n'); + }); + }); +}); diff --git a/test/unit/modules/keyboard.js b/test/unit/modules/keyboard.js deleted file mode 100644 index 90424509f0..0000000000 --- a/test/unit/modules/keyboard.js +++ /dev/null @@ -1,161 +0,0 @@ -import Keyboard, { SHORTKEY, normalize } from '../../../modules/keyboard'; - -describe('Keyboard', function () { - describe('match', function () { - it('no modifiers', function () { - const binding = normalize({ - key: 'a', - }); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: false, - }, - binding, - ), - ).toBe(true); - expect( - Keyboard.match( - { - key: 'A', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: true, - }, - binding, - ), - ).toBe(false); - }); - - it('simple modifier', function () { - const binding = normalize({ - key: 'a', - altKey: true, - }); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: false, - }, - binding, - ), - ).toBe(false); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: true, - }, - binding, - ), - ).toBe(true); - }); - - it('optional modifier', function () { - const binding = normalize({ - key: 'a', - altKey: null, - }); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: false, - }, - binding, - ), - ).toBe(true); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: true, - }, - binding, - ), - ).toBe(true); - }); - - it('shortkey modifier', function () { - const binding = normalize({ - key: 'a', - shortKey: true, - }); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: false, - }, - binding, - ), - ).toBe(false); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: false, - [SHORTKEY]: true, - }, - binding, - ), - ).toBe(true); - }); - - it('native shortkey modifier', function () { - const binding = normalize({ - key: 'a', - [SHORTKEY]: true, - }); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: false, - }, - binding, - ), - ).toBe(false); - expect( - Keyboard.match( - { - key: 'a', - shiftKey: false, - metaKey: false, - ctrlKey: false, - altKey: false, - [SHORTKEY]: true, - }, - binding, - ), - ).toBe(true); - }); - }); -}); diff --git a/test/unit/modules/keyboard.spec.ts b/test/unit/modules/keyboard.spec.ts new file mode 100644 index 0000000000..eaaa9fb825 --- /dev/null +++ b/test/unit/modules/keyboard.spec.ts @@ -0,0 +1,70 @@ +import { describe, expect, test } from 'vitest'; +import Keyboard, { SHORTKEY, normalize } from '../../../modules/keyboard'; + +const createKeyboardEvent = (key: string, override?: Partial) => + new KeyboardEvent('keydown', { + key, + shiftKey: false, + metaKey: false, + ctrlKey: false, + altKey: false, + ...override, + }); + +describe('Keyboard', () => { + describe('match', () => { + test('no modifiers', () => { + const binding = normalize({ + key: 'a', + }); + expect(Keyboard.match(createKeyboardEvent('a'), binding)).toBe(true); + expect( + Keyboard.match(createKeyboardEvent('A', { altKey: true }), binding), + ).toBe(false); + }); + + test('simple modifier', () => { + const binding = normalize({ + key: 'a', + altKey: true, + }); + expect(Keyboard.match(createKeyboardEvent('a'), binding)).toBe(false); + expect( + Keyboard.match(createKeyboardEvent('a', { altKey: true }), binding), + ).toBe(true); + }); + + test('optional modifier', () => { + const binding = normalize({ + key: 'a', + altKey: null, + }); + expect(Keyboard.match(createKeyboardEvent('a'), binding)).toBe(true); + expect( + Keyboard.match(createKeyboardEvent('a', { altKey: true }), binding), + ).toBe(true); + }); + + test('shortkey modifier', () => { + const binding = normalize({ + key: 'a', + shortKey: true, + }); + expect(Keyboard.match(createKeyboardEvent('a'), binding)).toBe(false); + expect( + Keyboard.match(createKeyboardEvent('a', { [SHORTKEY]: true }), binding), + ).toBe(true); + }); + + test('native shortkey modifier', () => { + const binding = normalize({ + key: 'a', + [SHORTKEY]: true, + }); + expect(Keyboard.match(createKeyboardEvent('a'), binding)).toBe(false); + expect( + Keyboard.match(createKeyboardEvent('a', { [SHORTKEY]: true }), binding), + ).toBe(true); + }); + }); +}); diff --git a/test/unit/modules/syntax.js b/test/unit/modules/syntax.js deleted file mode 100644 index 2303b50395..0000000000 --- a/test/unit/modules/syntax.js +++ /dev/null @@ -1,305 +0,0 @@ -import hljs from 'highlight.js'; -import Delta from 'quill-delta'; -import Quill from '../../../core/quill'; -import BoldBlot from '../../../formats/bold'; -import CodeBlock, { CodeBlockContainer } from '../../../formats/code'; -import Syntax, { CodeBlock as SyntaxCodeBlock } from '../../../modules/syntax'; - -const HIGHLIGHT_INTERVAL = 10; - -describe('Syntax', function () { - beforeAll(function () { - Syntax.register(); - Syntax.DEFAULTS.languages = [ - { key: 'javascript', label: 'Javascript' }, - { key: 'ruby', label: 'Ruby' }, - ]; - }); - - beforeEach(function () { - const container = this.initialize( - HTMLElement, - `
var test = 1;
var bugz = 0;
-


`, - ); - this.quill = new Quill(container, { - modules: { - syntax: { - hljs, - interval: HIGHLIGHT_INTERVAL, - }, - }, - }); - }); - - afterAll(function () { - Quill.register(CodeBlock, true); - Quill.register(CodeBlockContainer, true); - }); - - describe('highlighting', function () { - it('initialize', function () { - expect(this.quill.root).toEqualHTML( - `
-
var test = 1;
-
var bugz = 0;
-
-


`, - ); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('var bugz = 0;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('\n'), - ); - }); - - it('adds token', function (done) { - setTimeout(() => { - expect(this.quill.root).toEqualHTML( - `
-
var test = 1;
-
var bugz = 0;
-
-


`, - ); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('var bugz = 0;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('tokens do not escape', function (done) { - this.quill.deleteText(22, 6); - setTimeout(() => { - expect(this.quill.root).toEqualHTML(` -
-
var test = 1;
-
-

var bugz

`); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('var bugz\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('change language', function (done) { - this.quill.formatLine(0, 20, 'code-block', 'ruby'); - setTimeout(() => { - expect(this.quill.root).toEqualHTML(` -
-
var test = 1;
-
var bugz = 0;
-
-


`); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;') - .insert('\n', { 'code-block': 'ruby' }) - .insert('var bugz = 0;') - .insert('\n', { 'code-block': 'ruby' }) - .insert('\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('invalid language', function (done) { - this.quill.formatLine(0, 20, 'code-block', 'invalid'); - setTimeout(() => { - expect(this.quill.root).toEqualHTML(` -
-
var test = 1;
-
var bugz = 0;
-
-


`); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;') - .insert('\n', { 'code-block': 'plain' }) - .insert('var bugz = 0;') - .insert('\n', { 'code-block': 'plain' }) - .insert('\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('unformat first line', function (done) { - this.quill.formatLine(0, 1, 'code-block', false); - setTimeout(() => { - expect(this.quill.root).toEqualHTML(` -

var test = 1;

-
-
var bugz = 0;
-
-


`); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;\nvar bugz = 0;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('split container', function (done) { - this.quill.updateContents(new Delta().retain(14).insert('\n')); - setTimeout(() => { - expect(this.quill.root).toEqualHTML( - ` -
- -
var test = 1;
-
-


-
- -
var bugz = 0;
-
-


`, - false, - false, - ); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('\nvar bugz = 0;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('merge containers', function (done) { - this.quill.updateContents(new Delta().retain(14).insert('\n')); - setTimeout(() => { - this.quill.deleteText(14, 1); - setTimeout(() => { - expect(this.quill.root).toEqualHTML( - ` -
- -
var test = 1;
-
var bugz = 0;
-
-


`, - false, - false, - ); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('var test = 1;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('var bugz = 0;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }, HIGHLIGHT_INTERVAL + 1); - }); - - describe('allowedChildren', function () { - beforeAll(function () { - SyntaxCodeBlock.allowedChildren.push(BoldBlot); - }); - - afterAll(function () { - SyntaxCodeBlock.allowedChildren.pop(); - }); - - it('modification', function (done) { - this.quill.formatText(2, 3, 'bold', true); - setTimeout(() => { - expect(this.quill.root).toEqualHTML(` -
-
var test = 1;
-
var bugz = 0;
-
-


`); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('va') - .insert('r t', { bold: true }) - .insert('est = 1;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('var bugz = 0;') - .insert('\n', { 'code-block': 'javascript' }) - .insert('\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('removal', function (done) { - this.quill.formatText(2, 3, 'bold', true); - setTimeout(() => { - this.quill.formatLine(0, 15, 'code-block', false); - expect(this.quill.root).toEqualHTML( - `

var test = 1;

var bugz = 0;


`, - ); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('va') - .insert('r t', { bold: true }) - .insert('est = 1;\nvar bugz = 0;\n\n'), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - - it('addition', function (done) { - this.quill.setText('var test = 1;\n'); - this.quill.formatText(2, 3, 'bold', true); - this.quill.formatLine(0, 1, 'code-block', 'javascript'); - setTimeout(() => { - expect(this.quill.root).toEqualHTML(` -
-
var test = 1;
-
`); - expect(this.quill.getContents()).toEqual( - new Delta() - .insert('va') - .insert('r t', { bold: true }) - .insert('est = 1;') - .insert('\n', { 'code-block': 'javascript' }), - ); - done(); - }, HIGHLIGHT_INTERVAL + 1); - }); - }); - }); - - describe('html', function () { - it('code language', function () { - expect(this.quill.getSemanticHTML()).toContain( - 'data-language="javascript"', - ); - }); - }); -}); diff --git a/test/unit/modules/syntax.spec.ts b/test/unit/modules/syntax.spec.ts new file mode 100644 index 0000000000..db5f07ac36 --- /dev/null +++ b/test/unit/modules/syntax.spec.ts @@ -0,0 +1,299 @@ +import hljs from 'highlight.js'; +import Delta from 'quill-delta'; +import Quill from '../../../core'; +import BoldBlot from '../../../formats/bold'; +import Syntax, { CodeToken, CodeBlock } from '../../../modules/syntax'; +import { afterAll, beforeAll, describe, expect, test } from 'vitest'; +import { normalizeHTML, sleep } from '../__helpers__/utils'; +import { createRegistry } from '../__helpers__/factory'; +import Bold from '../../../formats/bold'; + +const HIGHLIGHT_INTERVAL = 10; + +describe('Syntax', () => { + beforeAll(() => { + Quill.register({ 'modules/syntax': Syntax }, true); + Syntax.register(); + Syntax.DEFAULTS.languages = [ + { key: 'javascript', label: 'Javascript' }, + { key: 'ruby', label: 'Ruby' }, + ]; + }); + + const createQuill = () => { + const container = document.body.appendChild(document.createElement('div')); + container.innerHTML = normalizeHTML( + `
var test = 1;
var bugz = 0;
+


`, + ); + const quill = new Quill(container, { + modules: { + syntax: { + hljs, + interval: HIGHLIGHT_INTERVAL, + }, + }, + registry: createRegistry([ + Bold, + CodeToken, + CodeBlock, + Quill.import('formats/code-block-container'), + ]), + }); + return quill; + }; + + describe('highlighting', () => { + test('initialize', () => { + const quill = createQuill(); + expect(quill.root).toEqualHTML( + `
+
var test = 1;
+
var bugz = 0;
+
+


`, + ); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('var bugz = 0;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('\n'), + ); + }); + + test('adds token', async () => { + const quill = createQuill(); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML( + `
+
var test = 1;
+
var bugz = 0;
+
+


`, + ); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('var bugz = 0;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('\n'), + ); + }); + + test('tokens do not escape', async () => { + const quill = createQuill(); + quill.deleteText(22, 6); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML(` +
+
var test = 1;
+
+

var bugz

`); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('var bugz\n'), + ); + }); + + test('change language', async () => { + const quill = createQuill(); + quill.formatLine(0, 20, 'code-block', 'ruby'); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML(` +
+
var test = 1;
+
var bugz = 0;
+
+


`); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;') + .insert('\n', { 'code-block': 'ruby' }) + .insert('var bugz = 0;') + .insert('\n', { 'code-block': 'ruby' }) + .insert('\n'), + ); + }); + + test('invalid language', async () => { + const quill = createQuill(); + quill.formatLine(0, 20, 'code-block', 'invalid'); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML(` +
+
var test = 1;
+
var bugz = 0;
+
+


`); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;') + .insert('\n', { 'code-block': 'plain' }) + .insert('var bugz = 0;') + .insert('\n', { 'code-block': 'plain' }) + .insert('\n'), + ); + }); + + test('unformat first line', async () => { + const quill = createQuill(); + quill.formatLine(0, 1, 'code-block', false); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML(` +

var test = 1;

+
+
var bugz = 0;
+
+


`); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;\nvar bugz = 0;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('\n'), + ); + }); + + test('split container', async () => { + const quill = createQuill(); + quill.updateContents(new Delta().retain(14).insert('\n')); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML( + ` +
+ +
var test = 1;
+
+


+
+ +
var bugz = 0;
+
+


`, + ); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('\nvar bugz = 0;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('\n'), + ); + }); + + test('merge containers', async () => { + const quill = createQuill(); + quill.updateContents(new Delta().retain(14).insert('\n')); + await sleep(HIGHLIGHT_INTERVAL + 1); + quill.deleteText(14, 1); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML( + ` +
+ +
var test = 1;
+
var bugz = 0;
+
+


`, + ); + expect(quill.getContents()).toEqual( + new Delta() + .insert('var test = 1;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('var bugz = 0;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('\n'), + ); + }); + + describe('allowedChildren', () => { + beforeAll(() => { + CodeBlock.allowedChildren.push(BoldBlot); + }); + + afterAll(() => { + CodeBlock.allowedChildren.pop(); + }); + + test('modification', async () => { + const quill = createQuill(); + // @ts-expect-error + quill.formatText(2, 3, 'bold', true); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML(` +
+
var test = 1;
+
var bugz = 0;
+
+


`); + expect(quill.getContents()).toEqual( + new Delta() + .insert('va') + .insert('r t', { bold: true }) + .insert('est = 1;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('var bugz = 0;') + .insert('\n', { 'code-block': 'javascript' }) + .insert('\n'), + ); + }); + + test('removal', async () => { + const quill = createQuill(); + // @ts-expect-error + quill.formatText(2, 3, 'bold', true); + await sleep(HIGHLIGHT_INTERVAL + 1); + quill.formatLine(0, 15, 'code-block', false); + expect(quill.root).toEqualHTML( + `

var test = 1;

var bugz = 0;


`, + ); + expect(quill.getContents()).toEqual( + new Delta() + .insert('va') + .insert('r t', { bold: true }) + .insert('est = 1;\nvar bugz = 0;\n\n'), + ); + }); + + test('addition', async () => { + const quill = createQuill(); + quill.setText('var test = 1;\n'); + // @ts-expect-error + quill.formatText(2, 3, 'bold', true); + quill.formatLine(0, 1, 'code-block', 'javascript'); + await sleep(HIGHLIGHT_INTERVAL + 1); + expect(quill.root).toEqualHTML(` +
+
var test = 1;
+
`); + expect(quill.getContents()).toEqual( + new Delta() + .insert('va') + .insert('r t', { bold: true }) + .insert('est = 1;') + .insert('\n', { 'code-block': 'javascript' }), + ); + }); + }); + }); + + describe('html', () => { + test('code language', () => { + const quill = createQuill(); + expect(quill.getSemanticHTML()).toContain('data-language="javascript"'); + }); + }); +}); diff --git a/test/unit/modules/table.js b/test/unit/modules/table.js deleted file mode 100644 index 67d795f6b0..0000000000 --- a/test/unit/modules/table.js +++ /dev/null @@ -1,170 +0,0 @@ -import Delta from 'quill-delta'; -import Quill from '../../../core/quill'; - -describe('Table Module', function () { - describe('insert table', function () { - it('empty', function () { - const quill = this.initialize(Quill, '


', this.container, { - modules: { - table: true, - }, - }); - const table = quill.getModule('table'); - quill.setSelection(0); - table.insertTable(2, 3); - expect(quill.root).toEqualHTML(` -
A1A2A3
- - - - -






-


- `); - }); - - it('split', function () { - const quill = this.initialize(Quill, '

0123

', this.container, { - modules: { - table: true, - }, - }); - const table = quill.getModule('table'); - quill.setSelection(2); - table.insertTable(2, 3); - expect(quill.root).toEqualHTML(` - - - - - -
01




-

23

- `); - }); - }); - - describe('modify table', function () { - beforeEach(function () { - const tableHTML = ` - - - - - -
a1a2a3
b1b2b3
- `; - this.quill = this.initialize(Quill, tableHTML, this.container, { - modules: { - table: true, - }, - }); - this.table = this.quill.getModule('table'); - }); - - it('insertRowAbove', function () { - this.quill.setSelection(0); - this.table.insertRowAbove(); - expect(this.quill.root).toEqualHTML(` - - - - - - -



a1a2a3
b1b2b3
- `); - }); - - it('insertRowBelow', function () { - this.quill.setSelection(0); - this.table.insertRowBelow(); - expect(this.quill.root).toEqualHTML(` - - - - - - -
a1a2a3



b1b2b3
- `); - }); - - it('insertColumnLeft', function () { - this.quill.setSelection(0); - this.table.insertColumnLeft(); - expect(this.quill.root).toEqualHTML(` - - - - - -

a1a2a3

b1b2b3
- `); - }); - - it('insertColumnRight', function () { - this.quill.setSelection(0); - this.table.insertColumnRight(); - expect(this.quill.root).toEqualHTML(` - - - - - -
a1
a2a3
b1
b2b3
- `); - }); - - it('deleteRow', function () { - this.quill.setSelection(0); - this.table.deleteRow(); - expect(this.quill.root).toEqualHTML(` - - - - -
b1b2b3
- `); - }); - - it('deleteColumn', function () { - this.quill.setSelection(0); - this.table.deleteColumn(); - expect(this.quill.root).toEqualHTML(` - - - - - -
a2a3
b2b3
- `); - }); - - it('insertText before', function () { - this.quill.updateContents(new Delta().insert('\n')); - expect(this.quill.root).toEqualHTML(` -


- - - - - -
a1a2a3
b1b2b3
- `); - }); - - it('insertText after', function () { - this.quill.updateContents(new Delta().retain(18).insert('\n')); - expect(this.quill.root).toEqualHTML(` - - - - - -
a1a2a3
b1b2b3
-


- `); - }); - }); -}); diff --git a/test/unit/modules/table.spec.ts b/test/unit/modules/table.spec.ts new file mode 100644 index 0000000000..6b10ac369e --- /dev/null +++ b/test/unit/modules/table.spec.ts @@ -0,0 +1,218 @@ +import Delta from 'quill-delta'; +import Quill from '../../../core'; +import { describe, expect, test } from 'vitest'; +import { createRegistry } from '../__helpers__/factory'; +import { + TableBody, + TableCell, + TableContainer, + TableRow, +} from '../../../formats/table'; +import { normalizeHTML } from '../__helpers__/utils'; +import Table from '../../../modules/table'; + +const createQuill = (html: string) => { + Quill.register({ 'modules/table': Table }, true); + const container = document.body.appendChild(document.createElement('div')); + container.innerHTML = normalizeHTML(html); + const quill = new Quill(container, { + modules: { table: true }, + registry: createRegistry([TableBody, TableCell, TableContainer, TableRow]), + }); + return quill; +}; + +describe('Table Module', () => { + describe('insert table', () => { + test('empty', () => { + const quill = createQuill('


'); + const table = quill.getModule('table') as Table; + quill.setSelection(0); + table.insertTable(2, 3); + expect(quill.root).toEqualHTML( + ` + + + + + +






+


+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('split', () => { + const quill = createQuill('

0123

'); + const table = quill.getModule('table') as Table; + quill.setSelection(2); + table.insertTable(2, 3); + expect(quill.root).toEqualHTML( + ` + + + + + +
01




+

23

+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + }); + + describe('modify table', () => { + const setup = () => { + const tableHTML = ` + + + + + +
a1a2a3
b1b2b3
+ `; + const quill = createQuill(tableHTML); + const table = quill.getModule('table') as Table; + return { quill, table }; + }; + + test('insertRowAbove', () => { + const { quill, table } = setup(); + quill.setSelection(0); + table.insertRowAbove(); + expect(quill.root).toEqualHTML( + ` + + + + + + +



a1a2a3
b1b2b3
+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('insertRowBelow', () => { + const { quill, table } = setup(); + quill.setSelection(0); + table.insertRowBelow(); + expect(quill.root).toEqualHTML( + ` + + + + + + +
a1a2a3



b1b2b3
+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('insertColumnLeft', () => { + const { quill, table } = setup(); + quill.setSelection(0); + table.insertColumnLeft(); + expect(quill.root).toEqualHTML( + ` + + + + + +

a1a2a3

b1b2b3
+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('insertColumnRight', () => { + const { quill, table } = setup(); + quill.setSelection(0); + table.insertColumnRight(); + expect(quill.root).toEqualHTML( + ` + + + + + +
a1
a2a3
b1
b2b3
+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('deleteRow', () => { + const { quill, table } = setup(); + quill.setSelection(0); + table.deleteRow(); + expect(quill.root).toEqualHTML( + ` + + + + +
b1b2b3
+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('deleteColumn', () => { + const { quill, table } = setup(); + quill.setSelection(0); + table.deleteColumn(); + expect(quill.root).toEqualHTML( + ` + + + + + +
a2a3
b2b3
+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('insertText before', () => { + const { quill } = setup(); + quill.updateContents(new Delta().insert('\n')); + expect(quill.root).toEqualHTML( + ` +


+ + + + + +
a1a2a3
b1b2b3
+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + + test('insertText after', () => { + const { quill } = setup(); + quill.updateContents(new Delta().retain(18).insert('\n')); + expect(quill.root).toEqualHTML( + ` + + + + + +
a1a2a3
b1b2b3
+


+ `, + { ignoreAttrs: ['data-row'] }, + ); + }); + }); +}); diff --git a/test/unit/modules/tableEmbed.js b/test/unit/modules/tableEmbed.spec.ts similarity index 94% rename from test/unit/modules/tableEmbed.js rename to test/unit/modules/tableEmbed.spec.ts index 670692bce5..a779085675 100644 --- a/test/unit/modules/tableEmbed.js +++ b/test/unit/modules/tableEmbed.spec.ts @@ -1,13 +1,18 @@ import Delta from 'quill-delta'; -import TableEmbed from '../../../modules/tableEmbed'; +import { tableHandler } from '../../../modules/tableEmbed'; +import { afterEach, beforeEach, describe, expect, test } from 'vitest'; -describe('Delta', () => { - beforeAll(() => { - TableEmbed.register(); +describe('tableHandler', () => { + beforeEach(() => { + Delta.registerEmbed('table-embed', tableHandler); + }); + + afterEach(() => { + Delta.unregisterEmbed('table-embed'); }); describe('compose', () => { - it('adds a row', () => { + test('adds a row', () => { const base = new Delta([ { insert: { @@ -64,7 +69,7 @@ describe('Delta', () => { ); }); - it('adds two rows', () => { + test('adds two rows', () => { const base = new Delta([ { insert: { @@ -129,7 +134,7 @@ describe('Delta', () => { ); }); - it('adds a row and changes cell content', () => { + test('adds a row and changes cell content', () => { const base = new Delta([ { insert: { @@ -195,7 +200,7 @@ describe('Delta', () => { ); }); - it('deletes a column', () => { + test('deletes a column', () => { const base = new Delta([ { insert: { @@ -248,7 +253,7 @@ describe('Delta', () => { ); }); - it('removes a cell attributes', () => { + test('removes a cell attributes', () => { const base = new Delta([ { insert: { @@ -274,7 +279,7 @@ describe('Delta', () => { ); }); - it('removes all rows', () => { + test('removes all rows', () => { const base = new Delta([ { insert: { 'table-embed': { rows: [{ insert: { id: '11111111' } }] } }, @@ -292,7 +297,7 @@ describe('Delta', () => { }); describe('transform', () => { - it('transform rows and columns', () => { + test('transform rows and columns', () => { const change1 = new Delta([ { retain: { @@ -348,7 +353,7 @@ describe('Delta', () => { ); }); - it('transform cells', () => { + test('transform cells', () => { const change1 = new Delta([ { retain: { @@ -406,7 +411,7 @@ describe('Delta', () => { ); }); - it('transform cell attributes', () => { + test('transform cell attributes', () => { const change1 = new Delta([ { retain: { @@ -446,7 +451,7 @@ describe('Delta', () => { }); describe('invert', () => { - it('reverts rows and columns', () => { + test('reverts rows and columns', () => { const base = new Delta([ { insert: { @@ -492,7 +497,7 @@ describe('Delta', () => { ); }); - it('inverts cell content', () => { + test('inverts cell content', () => { const base = new Delta([ { insert: { @@ -547,7 +552,7 @@ describe('Delta', () => { ); }); - it('inverts cells removed by row/column delta', () => { + test('inverts cells removed by row/column delta', () => { const base = new Delta([ { insert: { diff --git a/test/unit/modules/toolbar.js b/test/unit/modules/toolbar.spec.ts similarity index 56% rename from test/unit/modules/toolbar.js rename to test/unit/modules/toolbar.spec.ts index 29c0a03e15..62e9861147 100644 --- a/test/unit/modules/toolbar.js +++ b/test/unit/modules/toolbar.spec.ts @@ -1,11 +1,32 @@ +import { describe, expect, test } from 'vitest'; import Quill from '../../../core/quill'; import { addControls } from '../../../modules/toolbar'; +import { normalizeHTML } from '../__helpers__/utils'; +import SnowTheme from '../../../themes/snow'; +import Toolbar from '../../../modules/toolbar'; +import Clipboard from '../../../modules/clipboard'; +import Keyboard from '../../../modules/keyboard'; +import History from '../../../modules/history'; +import Uploader from '../../../modules/uploader'; +import { createRegistry } from '../__helpers__/factory'; +import Input from '../../../modules/input'; +import { SizeClass } from '../../../formats/size'; +import Bold from '../../../formats/bold'; +import Link from '../../../formats/link'; +import { AlignClass } from '../../../formats/align'; -describe('Toolbar', function () { - describe('add controls', function () { - it('single level', function () { - addControls(this.container, ['bold', 'italic']); - expect(this.container).toEqualHTML(` +const createContainer = (html = '') => { + const container = document.body.appendChild(document.createElement('div')); + container.innerHTML = normalizeHTML(html); + return container; +}; + +describe('Toolbar', () => { + describe('add controls', () => { + test('single level', () => { + const container = createContainer(); + addControls(container, ['bold', 'italic']); + expect(container).toEqualHTML(` @@ -13,12 +34,13 @@ describe('Toolbar', function () { `); }); - it('nested group', function () { - addControls(this.container, [ + test('nested group', () => { + const container = createContainer(); + addControls(container, [ ['bold', 'italic'], ['underline', 'strike'], ]); - expect(this.container).toEqualHTML(` + expect(container).toEqualHTML(` @@ -30,9 +52,10 @@ describe('Toolbar', function () { `); }); - it('button value', function () { - addControls(this.container, ['bold', { header: '2' }]); - expect(this.container).toEqualHTML(` + test('button value', () => { + const container = createContainer(); + addControls(container, ['bold', { header: '2' }]); + expect(container).toEqualHTML(` @@ -40,9 +63,10 @@ describe('Toolbar', function () { `); }); - it('select', function () { - addControls(this.container, [{ size: ['10px', false, '18px', '32px'] }]); - expect(this.container).toEqualHTML(` + test('select', () => { + const container = createContainer(); + addControls(container, [{ size: ['10px', false, '18px', '32px'] }]); + expect(container).toEqualHTML(` @@ -106,10 +131,9 @@ describe('Toolbar', function () { }); }); - describe('active', function () { - beforeEach(function () { - const container = this.initialize( - HTMLElement, + describe('active', () => { + const setup = () => { + const container = createContainer( `

0123

5678

@@ -118,7 +142,20 @@ describe('Toolbar', function () {

0123

`, ); - this.quill = new Quill(container, { + + Quill.register( + { + 'themes/snow': SnowTheme, + 'modules/toolbar': Toolbar, + 'modules/clipboard': Clipboard, + 'modules/keyboard': Keyboard, + 'modules/history': History, + 'modules/uploader': Uploader, + 'modules/input': Input, + }, + true, + ); + const quill = new Quill(container, { modules: { toolbar: [ ['bold', 'link'], @@ -127,54 +164,63 @@ describe('Toolbar', function () { ], }, theme: 'snow', + registry: createRegistry([SizeClass, Bold, AlignClass, Link]), }); - }); + return { container, quill }; + }; - it('toggle button', function () { - const boldButton = - this.container.parentNode.querySelector('button.ql-bold'); - this.quill.setSelection(7); + test('toggle button', () => { + const { container, quill } = setup(); + const boldButton = container.parentNode?.querySelector( + 'button.ql-bold', + ) as HTMLButtonElement; + quill.setSelection(7); expect(boldButton.classList.contains('ql-active')).toBe(true); - this.quill.setSelection(2); + quill.setSelection(2); expect(boldButton.classList.contains('ql-active')).toBe(false); }); - it('link', function () { - const linkButton = - this.container.parentNode.querySelector('button.ql-link'); - this.quill.setSelection(12); + test('link', () => { + const { container, quill } = setup(); + const linkButton = container.parentNode?.querySelector( + 'button.ql-link', + ) as HTMLButtonElement; + quill.setSelection(12); expect(linkButton.classList.contains('ql-active')).toBe(true); - this.quill.setSelection(2); + quill.setSelection(2); expect(linkButton.classList.contains('ql-active')).toBe(false); }); - it('dropdown', function () { - const sizeSelect = - this.container.parentNode.querySelector('select.ql-size'); - this.quill.setSelection(21); + test('dropdown', () => { + const { container, quill } = setup(); + const sizeSelect = container.parentNode?.querySelector( + 'select.ql-size', + ) as HTMLSelectElement; + quill.setSelection(21); expect(sizeSelect.selectedIndex).toEqual(0); - this.quill.setSelection(23); + quill.setSelection(23); expect(sizeSelect.selectedIndex).toEqual(2); - this.quill.setSelection(21, 2); + quill.setSelection(21, 2); expect(sizeSelect.selectedIndex).toBeLessThan(0); - this.quill.setSelection(2); + quill.setSelection(2); expect(sizeSelect.selectedIndex).toEqual(1); }); - it('custom button', function () { - const centerButton = this.container.parentNode.querySelector( + test('custom button', () => { + const { container, quill } = setup(); + const centerButton = container.parentNode?.querySelector( 'button.ql-align[value="center"]', - ); - const leftButton = this.container.parentNode.querySelector( + ) as HTMLButtonElement; + const leftButton = container.parentNode?.querySelector( 'button.ql-align[value]', - ); - this.quill.setSelection(17); + ) as HTMLButtonElement; + quill.setSelection(17); expect(centerButton.classList.contains('ql-active')).toBe(true); expect(leftButton.classList.contains('ql-active')).toBe(false); - this.quill.setSelection(2); + quill.setSelection(2); expect(centerButton.classList.contains('ql-active')).toBe(false); expect(leftButton.classList.contains('ql-active')).toBe(true); - this.quill.blur(); + quill.blur(); expect(centerButton.classList.contains('ql-active')).toBe(false); expect(leftButton.classList.contains('ql-active')).toBe(false); }); From 71a8dc36ec84d73304b05f7fb753a5e65e49ace4 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:28:10 +0800 Subject: [PATCH 08/18] Migrate formats to Vitest --- test/unit/formats/align.js | 46 -- test/unit/formats/align.spec.ts | 53 +++ test/unit/formats/bold.js | 18 - test/unit/formats/bold.spec.ts | 23 + test/unit/formats/{code.js => code.spec.ts} | 242 ++++++----- test/unit/formats/color.js | 47 --- test/unit/formats/color.spec.ts | 54 +++ test/unit/formats/header.js | 31 -- test/unit/formats/header.spec.ts | 41 ++ test/unit/formats/indent.js | 32 -- test/unit/formats/indent.spec.ts | 46 ++ test/unit/formats/link.js | 77 ---- test/unit/formats/link.spec.ts | 88 ++++ test/unit/formats/list.js | 344 --------------- test/unit/formats/list.spec.ts | 393 ++++++++++++++++++ test/unit/formats/script.js | 34 -- test/unit/formats/script.spec.ts | 40 ++ test/unit/formats/{table.js => table.spec.ts} | 262 ++++++------ 18 files changed, 1021 insertions(+), 850 deletions(-) delete mode 100644 test/unit/formats/align.js create mode 100644 test/unit/formats/align.spec.ts delete mode 100644 test/unit/formats/bold.js create mode 100644 test/unit/formats/bold.spec.ts rename test/unit/formats/{code.js => code.spec.ts} (54%) delete mode 100644 test/unit/formats/color.js create mode 100644 test/unit/formats/color.spec.ts delete mode 100644 test/unit/formats/header.js create mode 100644 test/unit/formats/header.spec.ts delete mode 100644 test/unit/formats/indent.js create mode 100644 test/unit/formats/indent.spec.ts delete mode 100644 test/unit/formats/link.js create mode 100644 test/unit/formats/link.spec.ts delete mode 100644 test/unit/formats/list.js create mode 100644 test/unit/formats/list.spec.ts delete mode 100644 test/unit/formats/script.js create mode 100644 test/unit/formats/script.spec.ts rename test/unit/formats/{table.js => table.spec.ts} (53%) diff --git a/test/unit/formats/align.js b/test/unit/formats/align.js deleted file mode 100644 index 8e298a0d6b..0000000000 --- a/test/unit/formats/align.js +++ /dev/null @@ -1,46 +0,0 @@ -import Delta from 'quill-delta'; -import Editor from '../../../core/editor'; - -describe('Align', function () { - it('add', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(4, 1, { align: 'center' }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123').insert('\n', { align: 'center' }), - ); - expect(editor.scroll.domNode).toEqualHTML( - '

0123

', - ); - }); - - it('remove', function () { - const editor = this.initialize( - Editor, - '

0123

', - ); - editor.formatText(4, 1, { align: false }); - expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); - }); - - it('whitelist', function () { - const editor = this.initialize( - Editor, - '

0123

', - ); - const initial = editor.scroll.domNode.innerHTML; - editor.formatText(4, 1, { align: 'middle' }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123').insert('\n', { align: 'center' }), - ); - expect(editor.scroll.domNode).toEqualHTML(initial); - }); - - it('invalid scope', function () { - const editor = this.initialize(Editor, '

0123

'); - const initial = editor.scroll.domNode.innerHTML; - editor.formatText(1, 2, { align: 'center' }); - expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll.domNode).toEqualHTML(initial); - }); -}); diff --git a/test/unit/formats/align.spec.ts b/test/unit/formats/align.spec.ts new file mode 100644 index 0000000000..5d399ae34e --- /dev/null +++ b/test/unit/formats/align.spec.ts @@ -0,0 +1,53 @@ +import Delta from 'quill-delta'; +import Editor from '../../../core/editor'; +import { describe, test, expect } from 'vitest'; +import { + createRegistry, + createScroll as baseCreateScroll, +} from '../__helpers__/factory'; +import { AlignClass } from '../../../formats/align'; + +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([AlignClass])); + +describe('Align', () => { + test('add', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(4, 1, { align: 'center' }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123').insert('\n', { align: 'center' }), + ); + expect(editor.scroll).toMatchInlineSnapshot( + '

0123

', + ); + }); + + test('remove', () => { + const editor = new Editor( + createScroll('

0123

'), + ); + editor.formatText(4, 1, { align: false }); + expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); + + test('whitelist', () => { + const editor = new Editor( + createScroll('

0123

'), + ); + editor.formatText(4, 1, { align: 'middle' }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123').insert('\n', { align: 'center' }), + ); + expect(editor.scroll).toMatchInlineSnapshot( + '

0123

', + ); + }); + + test('invalid scope', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(1, 2, { align: 'center' }); + expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); +}); diff --git a/test/unit/formats/bold.js b/test/unit/formats/bold.js deleted file mode 100644 index ad3648f0cd..0000000000 --- a/test/unit/formats/bold.js +++ /dev/null @@ -1,18 +0,0 @@ -import Scroll from '../../../blots/scroll'; - -describe('Bold', function () { - it('optimize and merge', function () { - const scroll = this.initialize( - Scroll, - '

abc

', - ); - const bold = document.createElement('b'); - bold.appendChild(scroll.domNode.firstChild.childNodes[1]); - scroll.domNode.firstChild.insertBefore( - bold, - scroll.domNode.firstChild.lastChild, - ); - scroll.update(); - expect(scroll.domNode).toEqualHTML('

abc

'); - }); -}); diff --git a/test/unit/formats/bold.spec.ts b/test/unit/formats/bold.spec.ts new file mode 100644 index 0000000000..0bd8e14773 --- /dev/null +++ b/test/unit/formats/bold.spec.ts @@ -0,0 +1,23 @@ +import { describe, expect, test } from 'vitest'; +import { + createRegistry, + createScroll as baseCreateScroll, +} from '../__helpers__/factory'; +import Bold from '../../../formats/bold'; + +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([Bold])); + +describe('Bold', () => { + test('optimize and merge', () => { + const scroll = createScroll('

abc

'); + const bold = document.createElement('b'); + bold.appendChild(scroll.domNode.firstChild?.childNodes[1] as Node); + scroll.domNode.firstChild?.insertBefore( + bold, + scroll.domNode.firstChild.lastChild, + ); + scroll.update(); + expect(scroll).toMatchInlineSnapshot('

abc

'); + }); +}); diff --git a/test/unit/formats/code.js b/test/unit/formats/code.spec.ts similarity index 54% rename from test/unit/formats/code.js rename to test/unit/formats/code.spec.ts index 39de6f5006..1863c2a2b3 100644 --- a/test/unit/formats/code.js +++ b/test/unit/formats/code.spec.ts @@ -1,19 +1,33 @@ import Delta from 'quill-delta'; import Editor from '../../../core/editor'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import { describe, expect, test } from 'vitest'; +import CodeBlock, { Code, CodeBlockContainer } from '../../../formats/code'; +import Italic from '../../../formats/italic'; +import Header from '../../../formats/header'; -describe('Code', function () { - it('format newline', function () { - const editor = this.initialize(Editor, '


'); +const createScroll = (html: string) => + baseCreateScroll( + html, + createRegistry([Code, CodeBlock, CodeBlockContainer, Italic, Header]), + ); + +describe('Code', () => { + test('format newline', () => { + const editor = new Editor(createScroll('


')); editor.formatLine(0, 1, { 'code-block': true }); - expect(editor.scroll.domNode).toEqualHTML( - `
-

-
`, - ); + expect(editor.scroll).toMatchInlineSnapshot(` +
+

+
+ `); }); - it('format lines', function () { - const editor = this.initialize(Editor, '

0123

5678

'); + test('format lines', () => { + const editor = new Editor(createScroll('

0123

5678

')); editor.formatLine(2, 5, { 'code-block': true }); expect(editor.getDelta()).toEqual( new Delta() @@ -22,28 +36,30 @@ describe('Code', function () { .insert('5678') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll.domNode).toEqualHTML( - `
+ expect(editor.scroll).toMatchInlineSnapshot(` +
0123
5678
-
`, - ); +
+ `); }); - it('remove format', function () { - const editor = this.initialize( - Editor, - '
0123
', + test('remove format', () => { + const editor = new Editor( + createScroll( + '
0123
', + ), ); editor.formatText(4, 1, { 'code-block': false }); expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); }); - it('delete last', function () { - const editor = this.initialize( - Editor, - '

0123


5678

', + test('delete last', () => { + const editor = new Editor( + createScroll( + '

0123


5678

', + ), ); editor.deleteText(4, 1); expect(editor.getDelta()).toEqual( @@ -52,46 +68,54 @@ describe('Code', function () { .insert('\n', { 'code-block': true }) .insert('5678\n'), ); - expect(editor.scroll.domNode).toEqualHTML( - '
0123

5678

', - ); + expect(editor.scroll).toMatchInlineSnapshot(` +
+
0123
+
+

5678

+ `); }); - it('delete merge before', function () { - const editor = this.initialize( - Editor, - '

0123

4567
', + test('delete merge before', () => { + const editor = new Editor( + createScroll( + '

0123

4567
', + ), ); editor.deleteText(4, 1); expect(editor.getDelta()).toEqual( new Delta().insert('01234567').insert('\n', { 'code-block': true }), ); - expect(editor.scroll.domNode).toEqualHTML( - '
01234567
', - ); + expect(editor.scroll).toMatchInlineSnapshot(` +
+
01234567
+
+ `); }); - it('delete merge after', function () { - const editor = this.initialize( - Editor, - '
0123

4567

', + test('delete merge after', () => { + const editor = new Editor( + createScroll( + '
0123

4567

', + ), ); editor.deleteText(4, 1); expect(editor.getDelta()).toEqual( new Delta().insert('01234567').insert('\n', { header: 1 }), ); - expect(editor.scroll.domNode).toEqualHTML('

01234567

'); + expect(editor.scroll).toMatchInlineSnapshot('

01234567

'); }); - it('delete across before partial merge', function () { - const editor = this.initialize( - Editor, - `
+ test('delete across before partial merge', () => { + const editor = new Editor( + createScroll( + `
01
34
67

90

`, + ), ); editor.deleteText(7, 3); expect(editor.getDelta()).toEqual( @@ -103,23 +127,24 @@ describe('Code', function () { .insert('60') .insert('\n', { header: 1 }), ); - expect(editor.scroll.domNode.innerHTML).toEqualHTML( - `
+ expect(editor.scroll).toMatchInlineSnapshot(` +
01
34
-

60

`, - ); +

60

+ `); }); - it('delete across before no merge', function () { - const editor = this.initialize( - Editor, - `
+ test('delete across before no merge', () => { + const editor = new Editor( + createScroll( + `
01
34

6789

`, + ), ); editor.deleteText(3, 5); expect(editor.getDelta()).toEqual( @@ -129,19 +154,23 @@ describe('Code', function () { .insert('89') .insert('\n', { header: 1 }), ); - expect(editor.scroll.domNode.innerHTML).toEqualHTML( - '
01

89

', - ); + expect(editor.scroll).toMatchInlineSnapshot(` +
+
01
+
+

89

+ `); }); - it('delete across after', function () { - const editor = this.initialize( - Editor, - `

0123

+ test('delete across after', () => { + const editor = new Editor( + createScroll( + `

0123

56
89
`, + ), ); editor.deleteText(2, 4); expect(editor.getDelta()).toEqual( @@ -151,7 +180,7 @@ describe('Code', function () { .insert('89') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll.domNode.innerHTML).toEqualHTML(` + expect(editor.scroll).toMatchInlineSnapshot(`
016
89
@@ -159,27 +188,29 @@ describe('Code', function () { `); }); - it('replace', function () { - const editor = this.initialize( - Editor, - '
0123
', + test('replace', () => { + const editor = new Editor( + createScroll( + '
0123
', + ), ); editor.formatText(4, 1, { header: 1 }); expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { header: 1 }), ); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); }); - it('replace multiple', function () { - const editor = this.initialize( - Editor, - ` + test('replace multiple', () => { + const editor = new Editor( + createScroll( + `
01
23
`, + ), ); editor.formatText(0, 6, { header: 1 }); expect(editor.getDelta()).toEqual( @@ -189,19 +220,20 @@ describe('Code', function () { .insert('23') .insert('\n', { header: 1 }), ); - expect(editor.scroll.domNode).toEqualHTML('

01

23

'); + expect(editor.scroll).toMatchInlineSnapshot('

01

\n

23

'); }); - it('format imprecise bounds', function () { - const editor = this.initialize( - Editor, - ` + test('format imprecise bounds', () => { + const editor = new Editor( + createScroll( + `
01
23
45
`, + ), ); editor.formatText(1, 6, { header: 1 }); expect(editor.getDelta()).toEqual( @@ -213,21 +245,26 @@ describe('Code', function () { .insert('45') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll.domNode.innerHTML).toEqualHTML( - '

01

23

45
', - ); + expect(editor.scroll).toMatchInlineSnapshot(` +

01

+

23

+
+
45
+
+ `); }); - it('format without newline', function () { - const editor = this.initialize( - Editor, - ` + test('format without newline', () => { + const editor = new Editor( + createScroll( + `
01
23
45
`, + ), ); editor.formatText(3, 1, { header: 1 }); expect(editor.getDelta()).toEqual( @@ -239,7 +276,7 @@ describe('Code', function () { .insert('45') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll.domNode.innerHTML).toEqualHTML(` + expect(editor.scroll).toMatchInlineSnapshot(`
01
23
@@ -248,16 +285,17 @@ describe('Code', function () { `); }); - it('format line', function () { - const editor = this.initialize( - Editor, - ` + test('format line', () => { + const editor = new Editor( + createScroll( + `
01
23
45
`, + ), ); editor.formatLine(3, 1, { header: 1 }); expect(editor.getDelta()).toEqual( @@ -269,7 +307,7 @@ describe('Code', function () { .insert('45') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll.domNode.innerHTML).toEqualHTML(` + expect(editor.scroll).toMatchInlineSnapshot(`
01
@@ -280,28 +318,32 @@ describe('Code', function () { `); }); - it('ignore formatAt', function () { - const editor = this.initialize( - Editor, - '
0123
', + test('ignore formatAt', () => { + const editor = new Editor( + createScroll( + '
0123
', + ), ); editor.formatText(1, 1, { bold: true }); expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { 'code-block': true }), ); - expect(editor.scroll.domNode).toEqualHTML( - '
0123
', - ); + expect(editor.scroll).toMatchInlineSnapshot(` +
+
0123
+
+ `); }); - it('partial block modification applyDelta', function () { - const editor = this.initialize( - Editor, - `
+ test('partial block modification applyDelta', () => { + const editor = new Editor( + createScroll( + `
a
b

`, + ), ); const delta = new Delta() .retain(3) @@ -309,12 +351,12 @@ describe('Code', function () { .delete(1) .retain(1, { 'code-block': null }); editor.applyDelta(delta); - expect(editor.scroll.domNode.innerHTML).toEqualHTML( - `
+ expect(editor.scroll).toMatchInlineSnapshot(` +
a
b
-


`, - ); +


+ `); }); }); diff --git a/test/unit/formats/color.js b/test/unit/formats/color.js deleted file mode 100644 index 2e8c38e92e..0000000000 --- a/test/unit/formats/color.js +++ /dev/null @@ -1,47 +0,0 @@ -import Delta from 'quill-delta'; -import Editor from '../../../core/editor'; - -describe('Color', function () { - it('add', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(1, 2, { color: 'red' }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0').insert('12', { color: 'red' }).insert('3\n'), - ); - expect(editor.scroll.domNode).toEqualHTML( - '

0123

', - ); - }); - - it('remove', function () { - const editor = this.initialize( - Editor, - '

0123

', - ); - editor.formatText(1, 2, { color: false }); - const delta = new Delta() - .insert('0') - .insert('12', { bold: true }) - .insert('3\n'); - expect(editor.getDelta()).toEqual(delta); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); - }); - - it('remove unwrap', function () { - const editor = this.initialize( - Editor, - '

0123

', - ); - editor.formatText(1, 2, { color: false }); - expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); - }); - - it('invalid scope', function () { - const editor = this.initialize(Editor, '

0123

'); - const initial = editor.scroll.domNode.innerHTML; - editor.formatText(4, 1, { color: 'red' }); - expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll.domNode).toEqualHTML(initial); - }); -}); diff --git a/test/unit/formats/color.spec.ts b/test/unit/formats/color.spec.ts new file mode 100644 index 0000000000..b376d5e662 --- /dev/null +++ b/test/unit/formats/color.spec.ts @@ -0,0 +1,54 @@ +import Delta from 'quill-delta'; +import Editor from '../../../core/editor'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import { ColorStyle } from '../../../formats/color'; +import { describe, expect, test } from 'vitest'; +import Bold from '../../../formats/bold'; + +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([ColorStyle, Bold])); + +describe('Color', () => { + test('add', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(1, 2, { color: 'red' }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0').insert('12', { color: 'red' }).insert('3\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot( + '

0123

', + ); + }); + + test('remove', () => { + const editor = new Editor( + createScroll('

0123

'), + ); + editor.formatText(1, 2, { color: false }); + const delta = new Delta() + .insert('0') + .insert('12', { bold: true }) + .insert('3\n'); + expect(editor.getDelta()).toEqual(delta); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); + + test('remove unwrap', () => { + const editor = new Editor( + createScroll('

0123

'), + ); + editor.formatText(1, 2, { color: false }); + expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); + + test('invalid scope', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(4, 1, { color: 'red' }); + expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); +}); diff --git a/test/unit/formats/header.js b/test/unit/formats/header.js deleted file mode 100644 index af64a09162..0000000000 --- a/test/unit/formats/header.js +++ /dev/null @@ -1,31 +0,0 @@ -import Delta from 'quill-delta'; -import Editor from '../../../core/editor'; - -describe('Header', function () { - it('add', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(4, 1, { header: 1 }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123', { italic: true }).insert('\n', { header: 1 }), - ); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); - }); - - it('remove', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(4, 1, { header: false }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123', { italic: true }).insert('\n'), - ); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); - }); - - it('change', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(4, 1, { header: 2 }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123', { italic: true }).insert('\n', { header: 2 }), - ); - expect(editor.scroll.domNode).toEqualHTML('

0123

'); - }); -}); diff --git a/test/unit/formats/header.spec.ts b/test/unit/formats/header.spec.ts new file mode 100644 index 0000000000..541b7f42c4 --- /dev/null +++ b/test/unit/formats/header.spec.ts @@ -0,0 +1,41 @@ +import Delta from 'quill-delta'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import Editor from '../../../core/editor'; +import Header from '../../../formats/header'; +import Italic from '../../../formats/italic'; +import { describe, expect, test } from 'vitest'; + +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([Header, Italic])); + +describe('Header', () => { + test('add', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(4, 1, { header: 1 }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123', { italic: true }).insert('\n', { header: 1 }), + ); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); + + test('remove', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(4, 1, { header: false }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123', { italic: true }).insert('\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); + + test('change', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(4, 1, { header: 2 }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123', { italic: true }).insert('\n', { header: 2 }), + ); + expect(editor.scroll).toMatchInlineSnapshot('

0123

'); + }); +}); diff --git a/test/unit/formats/indent.js b/test/unit/formats/indent.js deleted file mode 100644 index d7c30d338e..0000000000 --- a/test/unit/formats/indent.js +++ /dev/null @@ -1,32 +0,0 @@ -import Delta from 'quill-delta'; -import Editor from '../../../core/editor'; - -describe('Indent', function () { - it('+1', function () { - const editor = this.initialize( - Editor, - '
  1. 0123
', - ); - editor.formatText(4, 1, { indent: '+1' }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123').insert('\n', { list: 'bullet', indent: 1 }), - ); - expect(editor.scroll.domNode).toEqualHTML( - '
  1. 0123
', - ); - }); - - it('-1', function () { - const editor = this.initialize( - Editor, - '
  1. 0123
', - ); - editor.formatText(4, 1, { indent: '-1' }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123').insert('\n', { list: 'bullet' }), - ); - expect(editor.scroll.domNode).toEqualHTML( - '
  1. 0123
', - ); - }); -}); diff --git a/test/unit/formats/indent.spec.ts b/test/unit/formats/indent.spec.ts new file mode 100644 index 0000000000..c862092422 --- /dev/null +++ b/test/unit/formats/indent.spec.ts @@ -0,0 +1,46 @@ +import Delta from 'quill-delta'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import Editor from '../../../core/editor'; +import List, { ListContainer } from '../../../formats/list'; +import IndentClass from '../../../formats/indent'; +import { describe, expect, test } from 'vitest'; + +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([ListContainer, List, IndentClass])); + +describe('Indent', () => { + test('+1', () => { + const editor = new Editor( + createScroll('
  1. 0123
'), + ); + editor.formatText(4, 1, { indent: '+1' }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123').insert('\n', { list: 'bullet', indent: 1 }), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
+ `); + }); + + test('-1', () => { + const editor = new Editor( + createScroll( + '
  1. 0123
', + ), + ); + editor.formatText(4, 1, { indent: '-1' }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123').insert('\n', { list: 'bullet' }), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
+ `); + }); +}); diff --git a/test/unit/formats/link.js b/test/unit/formats/link.js deleted file mode 100644 index a2f70fa4ea..0000000000 --- a/test/unit/formats/link.js +++ /dev/null @@ -1,77 +0,0 @@ -import Delta from 'quill-delta'; -import Editor from '../../../core/editor'; -import Link from '../../../formats/link'; - -describe('Link', function () { - it('add', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(1, 2, { link: 'https://quilljs.com' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0') - .insert('12', { link: 'https://quilljs.com' }) - .insert('3\n'), - ); - expect(editor.scroll.domNode).toEqualHTML( - '

0123

', - ); - }); - - it('add invalid', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(1, 2, { link: 'javascript:alert(0);' }); // eslint-disable-line no-script-url - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0') - .insert('12', { link: Link.SANITIZED_URL }) - .insert('3\n'), - ); - }); - - it('add non-whitelisted protocol', function () { - const editor = this.initialize(Editor, '

0123

'); - editor.formatText(1, 2, { link: 'gopher://quilljs.com' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0') - .insert('12', { link: Link.SANITIZED_URL }) - .insert('3\n'), - ); - expect(editor.scroll.domNode).toEqualHTML( - '

0123

', - ); - }); - - it('change', function () { - const editor = this.initialize( - Editor, - '

0123

', - ); - editor.formatText(1, 2, { link: 'https://quilljs.com' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0') - .insert('12', { link: 'https://quilljs.com' }) - .insert('3\n'), - ); - expect(editor.scroll.domNode).toEqualHTML( - '

0123

', - ); - }); - - it('remove', function () { - const editor = this.initialize( - Editor, - '

0123

', - ); - editor.formatText(1, 2, { link: false }); - const delta = new Delta() - .insert('0') - .insert('12', { size: 'large' }) - .insert('3\n'); - expect(editor.getDelta()).toEqual(delta); - expect(editor.scroll.domNode).toEqualHTML( - '

0123

', - ); - }); -}); diff --git a/test/unit/formats/link.spec.ts b/test/unit/formats/link.spec.ts new file mode 100644 index 0000000000..b584bf481a --- /dev/null +++ b/test/unit/formats/link.spec.ts @@ -0,0 +1,88 @@ +import Delta from 'quill-delta'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import Editor from '../../../core/editor'; +import Link from '../../../formats/link'; +import { describe, expect, test } from 'vitest'; +import { SizeClass } from '../../../formats/size'; + +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([Link, SizeClass])); + +describe('Link', () => { + test('add', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(1, 2, { link: 'https://quilljs.com' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0') + .insert('12', { link: 'https://quilljs.com' }) + .insert('3\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot( + '

0123

', + ); + }); + + test('add invalid', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(1, 2, { link: 'javascript:alert(0);' }); // eslint-disable-line no-script-url + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0') + .insert('12', { link: Link.SANITIZED_URL }) + .insert('3\n'), + ); + }); + + test('add non-whitelisted protocol', () => { + const editor = new Editor(createScroll('

0123

')); + editor.formatText(1, 2, { link: 'gopher://quilljs.com' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0') + .insert('12', { link: Link.SANITIZED_URL }) + .insert('3\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot( + '

0123

', + ); + }); + + test('change', () => { + const editor = new Editor( + createScroll( + '

0123

', + ), + ); + editor.formatText(1, 2, { link: 'https://quilljs.com' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0') + .insert('12', { link: 'https://quilljs.com' }) + .insert('3\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot( + '

0123

', + ); + }); + + test('remove', () => { + const editor = new Editor( + createScroll( + '

0123

', + ), + ); + editor.formatText(1, 2, { link: false }); + const delta = new Delta() + .insert('0') + .insert('12', { size: 'large' }) + .insert('3\n'); + expect(editor.getDelta()).toEqual(delta); + expect(editor.scroll).toMatchInlineSnapshot( + '

0123

', + ); + }); +}); diff --git a/test/unit/formats/list.js b/test/unit/formats/list.js deleted file mode 100644 index 29f9c450e9..0000000000 --- a/test/unit/formats/list.js +++ /dev/null @@ -1,344 +0,0 @@ -import Delta from 'quill-delta'; -import Editor from '../../../core/editor'; - -describe('List', function () { - it('add', function () { - const editor = this.initialize( - Editor, - ` -

0123

-

5678

-

0123

`, - ); - editor.formatText(9, 1, { list: 'ordered' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0123\n5678') - .insert('\n', { list: 'ordered' }) - .insert('0123\n'), - ); - expect(this.container).toEqualHTML(` -

0123

-
  1. 5678
-

0123

- `); - }); - - it('checklist', function () { - const editor = this.initialize( - Editor, - ` -

0123

-

5678

-

0123

- `, - ); - editor.scroll.domNode.classList.add('ql-editor'); - editor.formatText(4, 1, { list: 'checked' }); - editor.formatText(9, 1, { list: 'unchecked' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0123') - .insert('\n', { list: 'checked' }) - .insert('5678') - .insert('\n', { list: 'unchecked' }) - .insert('0123\n'), - ); - expect(this.container).toEqualHTML(` -
    -
  1. 0123
  2. -
  3. 5678
  4. -
-

0123

- `); - }); - - it('remove', function () { - const editor = this.initialize( - Editor, - ` -

0123

-
  1. 5678
-

0123

- `, - ); - editor.formatText(9, 1, { list: null }); - expect(editor.getDelta()).toEqual(new Delta().insert('0123\n5678\n0123\n')); - expect(this.container).toEqualHTML(` -

0123

-

5678

-

0123

- `); - }); - - it('replace', function () { - const editor = this.initialize( - Editor, - ` -

0123

-
  1. 5678
-

0123

- `, - ); - editor.formatText(9, 1, { list: 'bullet' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0123\n5678') - .insert('\n', { list: 'bullet' }) - .insert('0123\n'), - ); - expect(this.container).toEqualHTML(` -

0123

-
  1. 5678
-

0123

- `); - }); - - it('replace checklist with bullet', function () { - const editor = this.initialize( - Editor, - ` -
    -
  1. 0123
  2. -
- `, - ); - editor.formatText(4, 1, { list: 'bullet' }); - expect(editor.getDelta()).toEqual( - new Delta().insert('0123').insert('\n', { list: 'bullet' }), - ); - expect(this.container).toEqualHTML(` -
  1. 0123
- `); - }); - - it('replace with attributes', function () { - const editor = this.initialize( - Editor, - '
  1. 0123
', - ); - editor.formatText(4, 1, { list: 'bullet' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0123') - .insert('\n', { align: 'center', list: 'bullet' }), - ); - expect(this.container).toEqualHTML( - '
  1. 0123
', - ); - }); - - it('format merge', function () { - const editor = this.initialize( - Editor, - ` -
  1. 0123
-

5678

-
  1. 0123
- `, - ); - editor.formatText(9, 1, { list: 'ordered' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0123') - .insert('\n', { list: 'ordered' }) - .insert('5678') - .insert('\n', { list: 'ordered' }) - .insert('0123') - .insert('\n', { list: 'ordered' }), - ); - expect(this.container).toEqualHTML(` -
    -
  1. 0123
  2. -
  3. 5678
  4. -
  5. 0123
  6. -
`); - }); - - it('delete merge', function () { - const editor = this.initialize( - Editor, - ` -
  1. 0123
-

5678

-
  1. 0123
`, - ); - editor.deleteText(5, 5); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0123') - .insert('\n', { list: 'ordered' }) - .insert('0123') - .insert('\n', { list: 'ordered' }), - ); - expect(this.container).toEqualHTML(` -
    -
  1. 0123
  2. -
  3. 0123
  4. -
`); - }); - - it('merge checklist', function () { - const editor = this.initialize( - Editor, - ` -
  1. 0123
-

5678

-
  1. 0123
- `, - ); - editor.formatText(9, 1, { list: 'checked' }); - expect(editor.getDelta()).toEqual( - new Delta() - .insert('0123') - .insert('\n', { list: 'checked' }) - .insert('5678') - .insert('\n', { list: 'checked' }) - .insert('0123') - .insert('\n', { list: 'checked' }), - ); - expect(this.container).toEqualHTML(` -
    -
  1. 0123
  2. -
  3. 5678
  4. -
  5. 0123
  6. -
`); - }); - - it('empty line interop', function () { - const editor = this.initialize( - Editor, - '

', - ); - editor.insertText(0, 'Test'); - expect(this.container).toEqualHTML( - '
  1. Test
', - ); - editor.deleteText(0, 4); - expect(this.container).toEqualHTML( - '

', - ); - }); - - it('delete multiple items', function () { - const editor = this.initialize( - Editor, - ` -
    -
  1. 0123
  2. -
  3. 5678
  4. -
  5. 0123
  6. -
`, - ); - editor.deleteText(2, 5); - expect(this.container).toEqualHTML(` -
    -
  1. 0178
  2. -
  3. 0123
  4. -
`); - }); - - it('delete across last item', function () { - const editor = this.initialize( - Editor, - ` -
  1. 0123
-

5678

`, - ); - editor.deleteText(2, 5); - expect(this.container).toEqualHTML('

0178

'); - }); - - it('delete partial', function () { - const editor = this.initialize( - Editor, - '

0123

  1. 5678
', - ); - editor.deleteText(2, 5); - expect(this.container).toEqualHTML( - '
  1. 0178
', - ); - }); - - it('nested list replacement', function () { - const editor = this.initialize( - Editor, - ` -
    -
  1. One
  2. -
  3. Alpha
  4. -
  5. Two
  6. -
- `, - ); - editor.formatLine(1, 10, { list: 'bullet' }); - expect(this.container).toEqualHTML(` -
    -
  1. One
  2. -
  3. Alpha
  4. -
  5. Two
  6. -
- `); - }); - - it('copy atttributes', function () { - const editor = this.initialize( - Editor, - '

Test

', - ); - editor.formatLine(4, 1, { list: 'bullet' }); - expect(this.container).toEqualHTML( - '
  1. Test
', - ); - }); - - it('insert block embed', function () { - const editor = this.initialize( - Editor, - '
  1. Test
', - ); - editor.insertEmbed( - 2, - 'video', - 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0', - ); - expect(this.container).toEqualHTML(` -
  1. Te
- -
  1. st
- `); - }); - - it('insert block embed at beginning', function () { - const editor = this.initialize( - Editor, - '
  1. Test
', - ); - editor.insertEmbed( - 0, - 'video', - 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0', - ); - expect(this.container).toEqualHTML(` - -
  1. Test
- `); - }); - - it('insert block embed at end', function () { - const editor = this.initialize( - Editor, - '
  1. Test
', - ); - editor.insertEmbed( - 4, - 'video', - 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0', - ); - expect(this.container).toEqualHTML(` -
  1. Test
- -

- `); - }); -}); diff --git a/test/unit/formats/list.spec.ts b/test/unit/formats/list.spec.ts new file mode 100644 index 0000000000..391f2240c2 --- /dev/null +++ b/test/unit/formats/list.spec.ts @@ -0,0 +1,393 @@ +import Delta from 'quill-delta'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import Editor from '../../../core/editor'; +import { describe, expect, test } from 'vitest'; +import List, { ListContainer } from '../../../formats/list'; +import IndentClass from '../../../formats/indent'; +import { AlignClass } from '../../../formats/align'; +import Video from '../../../formats/video'; + +const createScroll = (html: string) => + baseCreateScroll( + html, + createRegistry([ListContainer, List, IndentClass, AlignClass, Video]), + ); + +describe('List', () => { + test('add', () => { + const editor = new Editor( + createScroll(` +

0123

+

5678

+

0123

`), + ); + editor.formatText(9, 1, { list: 'ordered' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0123\n5678') + .insert('\n', { list: 'ordered' }) + .insert('0123\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +

0123

+
    +
  1. 5678
  2. +
+

0123

+ `); + }); + + test('checklist', () => { + const editor = new Editor( + createScroll( + ` +

0123

+

5678

+

0123

+ `, + ), + ); + editor.scroll.domNode.classList.add('ql-editor'); + editor.formatText(4, 1, { list: 'checked' }); + editor.formatText(9, 1, { list: 'unchecked' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0123') + .insert('\n', { list: 'checked' }) + .insert('5678') + .insert('\n', { list: 'unchecked' }) + .insert('0123\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
  3. 5678
  4. +
+

0123

+ `); + }); + + test('remove', () => { + const editor = new Editor( + createScroll( + ` +

0123

+
  1. 5678
+

0123

+ `, + ), + ); + editor.formatText(9, 1, { list: null }); + expect(editor.getDelta()).toEqual(new Delta().insert('0123\n5678\n0123\n')); + expect(editor.scroll).toMatchInlineSnapshot(` +

0123

+

5678

+

0123

+ `); + }); + + test('replace', () => { + const editor = new Editor( + createScroll( + ` +

0123

+
  1. 5678
+

0123

+ `, + ), + ); + editor.formatText(9, 1, { list: 'bullet' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0123\n5678') + .insert('\n', { list: 'bullet' }) + .insert('0123\n'), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +

0123

+
    +
  1. 5678
  2. +
+

0123

+ `); + }); + + test('replace checklist with bullet', () => { + const editor = new Editor( + createScroll( + ` +
    +
  1. 0123
  2. +
+ `, + ), + ); + editor.formatText(4, 1, { list: 'bullet' }); + expect(editor.getDelta()).toEqual( + new Delta().insert('0123').insert('\n', { list: 'bullet' }), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
+ `); + }); + + test('replace with attributes', () => { + const editor = new Editor( + createScroll( + '
  1. 0123
', + ), + ); + editor.formatText(4, 1, { list: 'bullet' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0123') + .insert('\n', { align: 'center', list: 'bullet' }), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
+ `); + }); + + test('format merge', () => { + const editor = new Editor( + createScroll( + ` +
  1. 0123
+

5678

+
  1. 0123
+ `, + ), + ); + editor.formatText(9, 1, { list: 'ordered' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0123') + .insert('\n', { list: 'ordered' }) + .insert('5678') + .insert('\n', { list: 'ordered' }) + .insert('0123') + .insert('\n', { list: 'ordered' }), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
  3. 5678
  4. +
  5. 0123
  6. +
+ `); + }); + + test('delete merge', () => { + const editor = new Editor( + createScroll( + ` +
  1. 0123
+

5678

+
  1. 0123
`, + ), + ); + editor.deleteText(5, 5); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0123') + .insert('\n', { list: 'ordered' }) + .insert('0123') + .insert('\n', { list: 'ordered' }), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
  3. 0123
  4. +
+ `); + }); + + test('merge checklist', () => { + const editor = new Editor( + createScroll( + ` +
  1. 0123
+

5678

+
  1. 0123
+ `, + ), + ); + editor.formatText(9, 1, { list: 'checked' }); + expect(editor.getDelta()).toEqual( + new Delta() + .insert('0123') + .insert('\n', { list: 'checked' }) + .insert('5678') + .insert('\n', { list: 'checked' }) + .insert('0123') + .insert('\n', { list: 'checked' }), + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0123
  2. +
  3. 5678
  4. +
  5. 0123
  6. +
+ `); + }); + + test('empty line interop', () => { + const editor = new Editor( + createScroll('

'), + ); + editor.insertText(0, 'Test'); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. Test
  2. +
+ `); + editor.deleteText(0, 4); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +

  1. +
+ `); + }); + + test('delete multiple items', () => { + const editor = new Editor( + createScroll( + ` +
    +
  1. 0123
  2. +
  3. 5678
  4. +
  5. 0123
  6. +
`, + ), + ); + editor.deleteText(2, 5); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0178
  2. +
  3. 0123
  4. +
+ `); + }); + + test('delete across last item', () => { + const editor = new Editor( + createScroll( + ` +
  1. 0123
+

5678

`, + ), + ); + editor.deleteText(2, 5); + expect(editor.scroll).toMatchInlineSnapshot('

0178

'); + }); + + test('delete partial', () => { + const editor = new Editor( + createScroll('

0123

  1. 5678
'), + ); + editor.deleteText(2, 5); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. 0178
  2. +
+ `); + }); + + test('nested list replacement', () => { + const editor = new Editor( + createScroll( + ` +
    +
  1. One
  2. +
  3. Alpha
  4. +
  5. Two
  6. +
+ `, + ), + ); + editor.formatLine(1, 10, { list: 'bullet' }); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. One
  2. +
  3. Alpha
  4. +
  5. Two
  6. +
+ `); + }); + + test('copy atttributes', () => { + const editor = new Editor( + createScroll('

Test

'), + ); + editor.formatLine(4, 1, { list: 'bullet' }); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. Test
  2. +
+ `); + }); + + test('insert block embed', () => { + const editor = new Editor( + createScroll('
  1. Test
'), + ); + editor.insertEmbed( + 2, + 'video', + 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0', + ); + expect(editor.scroll).toMatchInlineSnapshot(` +
    +
  1. Te
  2. +
+ ', ); editor.applyDelta(new Delta().retain(5).insert('5678')); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

5678

', ); }); - it('insert attributed text before block embed', function () { - const editor = this.initialize( - Editor, + test('insert attributed text before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta(new Delta().retain(5).insert('5678', { bold: true })); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

5678

', ); }); - it('insert text with newline before block embed', function () { - const editor = this.initialize( - Editor, + test('insert text with newline before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta(new Delta().retain(5).insert('5678\n')); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

5678

', ); }); - it('insert formatted lines before block embed', function () { - const editor = this.initialize( - Editor, + test('insert formatted lines before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( new Delta().retain(5).insert('a\nb').insert('\n', { header: 1 }), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

a

b

', ); }); - it('insert attributed text with newline before block embed', function () { - const editor = this.initialize( - Editor, + test('insert attributed text with newline before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( new Delta().retain(5).insert('5678', { bold: true }).insert('\n'), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

5678

', ); }); - it('multiple inserts and deletes', function () { - const editor = this.initialize(Editor, '

0123

'); + test('multiple inserts and deletes', () => { + const editor = createEditor('

0123

'); editor.applyDelta( new Delta() .retain(1) @@ -430,12 +453,11 @@ describe('Editor', function () { .delete(1) .insert('efg'), ); - expect(this.container).toEqualHTML('

0acdefg

'); + expect(editor.scroll.domNode).toEqualHTML('

0acdefg

'); }); - it('insert text with delete in existing block', function () { - const editor = this.initialize( - Editor, + test('insert text with delete in existing block', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( @@ -446,12 +468,11 @@ describe('Editor', function () { .retain(1) .delete(1), ); - expect(this.container).toEqualHTML('

0123abc

'); + expect(editor.scroll.domNode).toEqualHTML('

0123abc

'); }); - it('insert text with delete before block embed', function () { - const editor = this.initialize( - Editor, + test('insert text with delete before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( @@ -461,12 +482,11 @@ describe('Editor', function () { .insert('abc\n') .delete(1), ); - expect(this.container).toEqualHTML('

0123

abc

'); + expect(editor.scroll.domNode).toEqualHTML('

0123

abc

'); }); - it('insert inline embed with delete in existing block', function () { - const editor = this.initialize( - Editor, + test('insert inline embed with delete in existing block', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( @@ -477,14 +497,13 @@ describe('Editor', function () { .retain(1) .delete(1), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

', ); }); - it('insert inline embed with delete before block embed', function () { - const editor = this.initialize( - Editor, + test('insert inline embed with delete before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( @@ -495,14 +514,13 @@ describe('Editor', function () { .insert('\n') .delete(1), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

', ); }); - it('insert inline embed with delete before block embed using delete op first', function () { - const editor = this.initialize( - Editor, + test('insert inline embed with delete before block embed using delete op first', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( @@ -513,14 +531,13 @@ describe('Editor', function () { // Explicit newline required to maintain correct index calculation for the delete. .insert('\n'), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

', ); }); - it('insert inline embed and text with delete before block embed', function () { - const editor = this.initialize( - Editor, + test('insert inline embed and text with delete before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( @@ -531,73 +548,69 @@ describe('Editor', function () { .insert('abc\n') .delete(1), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

abc

', ); }); - it('insert inline embed to the middle of formatted content', function () { - const editor = this.initialize(Editor, '

0123

'); + test('insert inline embed to the middle of formatted content', () => { + const editor = createEditor('

0123

'); editor.applyDelta( new Delta().retain(2).insert({ image: '/assets/favicon.png' }), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

', ); }); - it('insert inline embed between plain text and formatted content', function () { - const editor = this.initialize(Editor, '

ab

'); + test('insert inline embed between plain text and formatted content', () => { + const editor = createEditor('

ab

'); editor.applyDelta(new Delta().retain(1).insert({ image: '#' })); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

ab

', ); }); - it('prepend inline embed to another inline embed with same attributes', function () { - const editor = this.initialize(Editor, '

hi

'); + test('prepend inline embed to another inline embed with same attributes', () => { + const editor = createEditor('

hi

'); editor.applyDelta(new Delta().insert({ image: '#' }, { alt: 'hi' })); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

hihi

', ); }); - it('insert block embed with delete before block embed', function () { - const editor = this.initialize( - Editor, + test('insert block embed with delete before block embed', () => { + const editor = createEditor( '

0123

', ); editor.applyDelta( new Delta().retain(5).insert({ video: '#changed' }).delete(1), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

', ); }); - it('deletes block embed and appends text', function () { - const editor = this.initialize( - Editor, + test('deletes block embed and appends text', () => { + const editor = createEditor( `


b

`, ); editor.applyDelta(new Delta().retain(1).insert('a').delete(1)); - expect(this.container).toEqualHTML('


ab

'); + expect(editor.scroll.domNode).toEqualHTML('


ab

'); }); - it('multiple delete block embed and append texts', function () { - const editor = this.initialize( - Editor, + test('multiple delete block embed and append texts', () => { + const editor = createEditor( `


b

`, ); editor.applyDelta( new Delta().retain(1).insert('a').delete(1).insert('!').delete(1), ); - expect(this.container).toEqualHTML('


a!b

'); + expect(editor.scroll.domNode).toEqualHTML('


a!b

'); }); - it('multiple nonconsecutive delete block embed and append texts', function () { - const editor = this.initialize( - Editor, + test('multiple nonconsecutive delete block embed and append texts', () => { + const editor = createEditor( `


a

@@ -624,115 +637,113 @@ describe('Editor', function () { .delete(1); editor.applyDelta(delta); expect(editor.getDelta()).toEqual(old.compose(delta)); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '


1a

2bb

3ccc

4dddd

', ); }); - describe('block embed', function () { - it('improper block embed insert', function () { - const editor = this.initialize(Editor, '

0123

'); + describe('block embed', () => { + test('improper block embed insert', () => { + const editor = createEditor('

0123

'); editor.applyDelta(new Delta().retain(2).insert({ video: '#' })); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

01

23

', ); }); - describe('insert and delete', function () { - it('prepend', function () { - const editor = this.initialize(Editor, '

0123

'); + describe('insert and delete', () => { + test('prepend', () => { + const editor = createEditor('

0123

'); editor.applyDelta(new Delta().insert({ video: '#' }).delete(2)); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

23

', ); }); - it('insert to the middle of text', function () { - const editor = this.initialize(Editor, `

abc

`); + test('insert to the middle of text', () => { + const editor = createEditor(`

abc

`); editor.applyDelta( new Delta().retain(1).insert({ video: '#' }).delete(2), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

a


', ); }); - it('insert after \\n', function () { - const editor = this.initialize(Editor, `

a

cda

`); + test('insert after \\n', () => { + const editor = createEditor(`

a

cda

`); editor.applyDelta( new Delta().retain(2).insert({ video: '#' }).delete(2), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

a

a

', ); }); - it('insert after an inline embed', function () { - const editor = this.initialize( - Editor, + test('insert after an inline embed', () => { + const editor = createEditor( `

abc

`, ); editor.applyDelta( new Delta().retain(1).insert({ video: '#' }).delete(2), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

bc

', ); }); - it('insert after a block embed', function () { - const editor = this.initialize( - Editor, + test('insert after a block embed', () => { + const editor = createEditor( `

abc

`, ); editor.applyDelta( new Delta().retain(1).insert({ video: '#' }).delete(2), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

c

', ); }); }); - it('append formatted block embed', function () { - const editor = this.initialize(Editor, '

0123


'); + test('append formatted block embed', () => { + const editor = createEditor('

0123


'); editor.applyDelta( new Delta().retain(5).insert({ video: '#' }, { align: 'right' }), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123


', ); }); }); - it('append', function () { - const editor = this.initialize(Editor, '

0123

'); + test('append', () => { + const editor = createEditor('

0123

'); editor.applyDelta(new Delta().retain(5).insert('5678')); - expect(this.container).toEqualHTML('

0123

5678

'); + expect(editor.scroll.domNode).toEqualHTML('

0123

5678

'); }); - it('append newline', function () { - const editor = this.initialize(Editor, '

0123

'); + test('append newline', () => { + const editor = createEditor('

0123

'); editor.applyDelta(new Delta().retain(5).insert('\n', { header: 2 })); - expect(this.container).toEqualHTML('

0123


'); + expect(editor.scroll.domNode).toEqualHTML('

0123


'); }); - it('append text with newline', function () { - const editor = this.initialize(Editor, '

0123

'); + test('append text with newline', () => { + const editor = createEditor('

0123

'); editor.applyDelta( new Delta().retain(5).insert('5678').insert('\n', { header: 2 }), ); - expect(this.container).toEqualHTML('

0123

5678

'); + expect(editor.scroll.domNode).toEqualHTML('

0123

5678

'); }); - it('append non-isolated newline', function () { - const editor = this.initialize(Editor, '

0123

'); + test('append non-isolated newline', () => { + const editor = createEditor('

0123

'); editor.applyDelta(new Delta().retain(5).insert('5678\n', { header: 2 })); - expect(this.container).toEqualHTML('

0123

5678

'); + expect(editor.scroll.domNode).toEqualHTML('

0123

5678

'); }); - it('eventual append', function () { - const editor = this.initialize(Editor, '

0123

'); + test('eventual append', () => { + const editor = createEditor('

0123

'); editor.applyDelta( new Delta() .retain(2) @@ -740,11 +751,13 @@ describe('Editor', function () { .retain(3) .insert('cd\n', { header: 2 }), ); - expect(this.container).toEqualHTML('

01ab

23

cd

'); + expect(editor.scroll.domNode).toEqualHTML( + '

01ab

23

cd

', + ); }); - it('append text, embed and newline', function () { - const editor = this.initialize(Editor, '

0123

'); + test('append text, embed and newline', () => { + const editor = createEditor('

0123

'); editor.applyDelta( new Delta() .retain(5) @@ -752,13 +765,13 @@ describe('Editor', function () { .insert({ image: '/assets/favicon.png' }) .insert('\n', { header: 2 }), ); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '

0123

5678

', ); }); - it('append multiple lines', function () { - const editor = this.initialize(Editor, '

0123

'); + test('append multiple lines', () => { + const editor = createEditor('

0123

'); editor.applyDelta( new Delta() .retain(5) @@ -767,32 +780,34 @@ describe('Editor', function () { .insert('89') .insert('\n', { header: 2 }), ); - expect(this.container).toEqualHTML('

0123

56

89

'); + expect(editor.scroll.domNode).toEqualHTML( + '

0123

56

89

', + ); }); - it('code block', function () { - const editor = this.initialize(Editor, { + test('code block', () => { + const editor = createEditor({ html: '

0

1
23


', }); editor.applyDelta(new Delta().delete(4).retain(1).delete(2)); expect(editor.scroll.domNode.innerHTML).toEqual('

2

'); }); - it('prepending bold with a newline and unformatted text', function () { - const editor = this.initialize(Editor, '

a

'); + test('prepending bold with a newline and unformatted text', () => { + const editor = createEditor('

a

'); editor.applyDelta(new Delta().insert('\n1')); - expect(this.container).toEqualHTML( + expect(editor.scroll.domNode).toEqualHTML( '


1a

', ); }); }); - describe('insertContents', function () { + describe('insertContents', () => { const video = ''; - it('ignores empty delta', function () { - const editor = this.initialize(Editor, '

1

'); + test('ignores empty delta', () => { + const editor = createEditor('

1

'); editor.insertContents(0, new Delta()); expect(editor.getDelta().ops).toEqual([{ insert: '1\n' }]); @@ -800,8 +815,8 @@ describe('Editor', function () { expect(editor.getDelta().ops).toEqual([{ insert: '1\n' }]); }); - it('prepend to paragraph', function () { - const editor = this.initialize(Editor, '

2

'); + test('prepend to paragraph', () => { + const editor = createEditor('

2

'); editor.insertContents(0, new Delta().insert('1')); expect(editor.getDelta().ops).toEqual([{ insert: '12\n' }]); @@ -821,11 +836,8 @@ describe('Editor', function () { ]); }); - it('prepend to list item', function () { - const editor = this.initialize( - Editor, - '
  1. 2
', - ); + test('prepend to list item', () => { + const editor = createEditor('
  1. 2
'); editor.insertContents(0, new Delta().insert('1')); expect(editor.getDelta().ops).toEqual([ { insert: '12' }, @@ -849,7 +861,7 @@ describe('Editor', function () { ]); }); - it('insert before formatting', function () { + test('insert before formatting', () => { class MyBlot extends Block { static className = 'my-blot'; static blotName = 'my-blot'; @@ -880,9 +892,9 @@ describe('Editor', function () { expect(editor.scroll.domNode.innerHTML).toContain('test-style="random"'); }); - describe('prepend to block embed', function () { - it('without ending with \\n', function () { - const editor = this.initialize(Editor, `${video}`); + describe('prepend to block embed', () => { + test('without ending with \\n', () => { + const editor = createEditor(`${video}`); editor.insertContents(0, new Delta().insert('a')); expect(editor.getDelta().ops).toEqual([ { insert: 'a\n' }, @@ -890,8 +902,8 @@ describe('Editor', function () { ]); }); - it('empty first line', function () { - const editor = this.initialize(Editor, `

${video}`); + test('empty first line', () => { + const editor = createEditor(`

${video}`); editor.insertContents(1, new Delta().insert('\nworld\n')); expect(editor.getDelta().ops).toEqual([ { insert: '\n\nworld\n' }, @@ -899,8 +911,8 @@ describe('Editor', function () { ]); }); - it('multiple lines', function () { - const editor = this.initialize(Editor, `${video}`); + test('multiple lines', () => { + const editor = createEditor(`${video}`); editor.insertContents( 0, new Delta().insert('a').insert('\n', { header: 1 }), @@ -913,9 +925,9 @@ describe('Editor', function () { }); }); - describe('append', function () { - it('appends to editor', function () { - const editor = this.initialize(Editor, '

1

'); + describe('append', () => { + test('appends to editor', () => { + const editor = createEditor('

1

'); editor.insertContents(2, new Delta().insert('a')); expect(editor.getDelta().ops).toEqual([{ insert: '1\na\n' }]); editor.insertContents( @@ -928,8 +940,8 @@ describe('Editor', function () { ]); }); - it('appends to paragraph', function () { - const editor = this.initialize(Editor, '

1

2

'); + test('appends to paragraph', () => { + const editor = createEditor('

1

2

'); editor.insertContents(2, new Delta().insert('a')); expect(editor.getDelta().ops).toEqual([{ insert: '1\na2\n' }]); editor.insertContents( @@ -943,8 +955,8 @@ describe('Editor', function () { ]); }); - it('appends to block embed', function () { - const editor = this.initialize(Editor, `${video}

2

`); + test('appends to block embed', () => { + const editor = createEditor(`${video}

2

`); editor.insertContents(1, new Delta().insert('1')); expect(editor.getDelta().ops).toEqual([ { insert: { video: '#' } }, @@ -963,8 +975,8 @@ describe('Editor', function () { }); }); - it('inserts formatted block embeds (styles)', function () { - const editor = this.initialize(Editor, `

`); + test('inserts formatted block embeds (styles)', () => { + const editor = createEditor(`

`); editor.insertContents( 0, new Delta() @@ -981,8 +993,8 @@ describe('Editor', function () { ]); }); - it('inserts formatted block embeds (attributor)', function () { - const editor = this.initialize(Editor, `

`); + test('inserts formatted block embeds (attributor)', () => { + const editor = createEditor(`

`); editor.insertContents( 0, new Delta() @@ -999,8 +1011,8 @@ describe('Editor', function () { ]); }); - it('inserts inline embeds to bold text', function () { - const editor = this.initialize(Editor, `

ab

`); + test('inserts inline embeds to bold text', () => { + const editor = createEditor(`

ab

`); editor.insertContents(1, new Delta().insert({ image: '#' })); expect(editor.getDelta().ops).toEqual([ { insert: 'a', attributes: { bold: true } }, @@ -1010,11 +1022,8 @@ describe('Editor', function () { ]); }); - it('inserts multiple lines to a container', function () { - const editor = this.initialize( - Editor, - `
`, - ); + test('inserts multiple lines to a container', () => { + const editor = createEditor(`
`); editor.insertContents( 0, new Delta() @@ -1030,14 +1039,14 @@ describe('Editor', function () { ]); }); - describe('invalid delta', function () { - const getEditorDelta = (context, modify) => { - const editor = context.initialize(Editor, `

`); + describe('invalid delta', () => { + const getEditorDelta = (modify: (editor: Editor) => void) => { + const editor = createEditor(`

`); modify(editor); return editor.getDelta().ops; }; - it('conflict block formats', function () { + test('conflict block formats', () => { const change = new Delta() .insert('a') .insert('\n', { header: 1, list: 'bullet' }) @@ -1045,11 +1054,11 @@ describe('Editor', function () { .insert('\n', { header: 1, list: 'bullet' }); expect( - getEditorDelta(this, editor => editor.insertContents(0, change)), - ).toEqual(getEditorDelta(this, editor => editor.applyDelta(change))); + getEditorDelta(editor => editor.insertContents(0, change)), + ).toEqual(getEditorDelta(editor => editor.applyDelta(change))); }); - it('block embeds with line formats', function () { + test('block embeds with line formats', () => { const change = new Delta() .insert('a\n') .insert({ video: '#' }, { header: 1 }) @@ -1057,37 +1066,36 @@ describe('Editor', function () { .insert('\n', { header: 1 }); expect( - getEditorDelta(this, editor => editor.insertContents(0, change)), - ).toEqual(getEditorDelta(this, editor => editor.applyDelta(change))); + getEditorDelta(editor => editor.insertContents(0, change)), + ).toEqual(getEditorDelta(editor => editor.applyDelta(change))); }); - it('missing \\n before block embeds', function () { + test('missing \\n before block embeds', () => { const change = new Delta() .insert('a') .insert({ video: '#' }) .insert('b\n'); expect( - getEditorDelta(this, editor => editor.insertContents(0, change)), - ).toEqual(getEditorDelta(this, editor => editor.applyDelta(change))); + getEditorDelta(editor => editor.insertContents(0, change)), + ).toEqual(getEditorDelta(editor => editor.applyDelta(change))); }); }); }); - describe('getFormat()', function () { - it('unformatted', function () { - const editor = this.initialize(Editor, '

0123

'); + describe('getFormat()', () => { + test('unformatted', () => { + const editor = createEditor('

0123

'); expect(editor.getFormat(1)).toEqual({}); }); - it('formatted', function () { - const editor = this.initialize(Editor, '

0123

'); + test('formatted', () => { + const editor = createEditor('

0123

'); expect(editor.getFormat(1)).toEqual({ header: 1, italic: true }); }); - it('cursor', function () { - const editor = this.initialize( - Editor, + test('cursor', () => { + const editor = createEditor( '

0123

5678

', ); expect(editor.getFormat(2)).toEqual({ @@ -1097,11 +1105,9 @@ describe('Editor', function () { }); }); - it('cursor with preformat', function () { - const [editor, selection] = this.initialize( - [Editor, Selection], - '

0123

', - ); + test('cursor with preformat', () => { + const editor = createEditor('

0123

'); + const selection = new Selection(editor.scroll, editor.scroll.emitter); selection.setRange(new Range(2)); selection.format('underline', true); selection.format('color', 'red'); @@ -1114,9 +1120,8 @@ describe('Editor', function () { }); }); - it('across leaves', function () { - const editor = this.initialize( - Editor, + test('across leaves', () => { + const editor = createEditor( `

01 @@ -1132,9 +1137,8 @@ describe('Editor', function () { }); }); - it('across leaves repeated', function () { - const editor = this.initialize( - Editor, + test('across leaves repeated', () => { + const editor = createEditor( `

01 @@ -1151,9 +1155,8 @@ describe('Editor', function () { }); }); - it('across lines repeated', function () { - const editor = this.initialize( - Editor, + test('across lines repeated', () => { + const editor = createEditor( `

01

34

@@ -1167,9 +1170,8 @@ describe('Editor', function () { align: ['right', 'center'], }); }); - it('across lines', function () { - const editor = this.initialize( - Editor, + test('across lines', () => { + const editor = createEditor( `

01

34

@@ -1183,15 +1185,14 @@ describe('Editor', function () { }); }); - describe('getHTML', function () { - it('inline', function () { - const editor = this.initialize(Editor, '
Test
'); + describe('getHTML', () => { + test('inline', () => { + const editor = createEditor('
Test
'); expect(editor.getHTML(1, 2)).toEqual('es'); }); - it('across lines', function () { - const editor = this.initialize( - Editor, + test('across lines', () => { + const editor = createEditor( '

Header

Text

Quote
', ); expect(editor.getHTML(1, 14)).toEqual( @@ -1199,9 +1200,8 @@ describe('Editor', function () { ); }); - it('mixed list', function () { - const editor = this.initialize( - Editor, + test('mixed list', () => { + const editor = createEditor( `
  1. One
  2. @@ -1223,9 +1223,8 @@ describe('Editor', function () { `); }); - it('nested list', function () { - const editor = this.initialize( - Editor, + test('nested list', () => { + const editor = createEditor( `
    1. One
    2. @@ -1255,9 +1254,8 @@ describe('Editor', function () { `); }); - it('nested checklist', function () { - const editor = this.initialize( - Editor, + test('nested checklist', () => { + const editor = createEditor( `
      1. One
      2. @@ -1287,9 +1285,8 @@ describe('Editor', function () { `); }); - it('partial list', function () { - const editor = this.initialize( - Editor, + test('partial list', () => { + const editor = createEditor( `
        1. 1111
        2. @@ -1317,20 +1314,19 @@ describe('Editor', function () { `); }); - it('text within tag', function () { - const editor = this.initialize(Editor, '

          a

          '); + test('text within tag', () => { + const editor = createEditor('

          a

          '); expect(editor.getHTML(0, 1)).toEqual('a'); }); - it('escape html', function () { - const editor = this.initialize(Editor, '


          '); + test('escape html', () => { + const editor = createEditor('


          '); editor.insertText(0, 'Test'); expect(editor.getHTML(0, 11)).toEqual('<b>Test</b>'); }); - it('multiline code', function () { - const editor = this.initialize( - Editor, + test('multiline code', () => { + const editor = createEditor( '


          0123



          4567


          ', ); const length = editor.scroll.length(); diff --git a/test/unit/core/quill.js b/test/unit/core/quill.js deleted file mode 100644 index 803ad21219..0000000000 --- a/test/unit/core/quill.js +++ /dev/null @@ -1,918 +0,0 @@ -import Delta from 'quill-delta'; -import Quill, { expandConfig, overload } from '../../../core/quill'; -import Theme from '../../../core/theme'; -import Emitter from '../../../core/emitter'; -import Toolbar from '../../../modules/toolbar'; -import Snow from '../../../themes/snow'; -import { Range } from '../../../core/selection'; - -describe('Quill', function () { - it('imports', function () { - Object.keys(Quill.imports).forEach(function (path) { - expect(Quill.import(path)).toBeTruthy(); - }); - }); - - describe('construction', function () { - it('empty', function () { - const quill = this.initialize(Quill, ''); - expect(quill.getContents()).toEqual(new Delta().insert('\n')); - expect(quill.root).toEqualHTML('


          '); - }); - - it('text', function () { - const quill = this.initialize(Quill, '0123'); - expect(quill.getContents()).toEqual(new Delta().insert('0123\n')); - expect(quill.root).toEqualHTML('

          0123

          '); - }); - - it('newlines', function () { - const quill = this.initialize(Quill, '




          '); - expect(quill.getContents()).toEqual(new Delta().insert('\n\n\n')); - expect(quill.root).toEqualHTML('




          '); - }); - - it('formatted ending', function () { - const quill = this.initialize( - Quill, - '

          Test

          ', - ); - expect(quill.getContents()).toEqual( - new Delta().insert('Test').insert('\n', { align: 'center' }), - ); - expect(quill.root).toEqualHTML('

          Test

          '); - }); - }); - - describe('api', function () { - beforeEach(function () { - this.quill = this.initialize(Quill, '

          01234567

          '); - this.oldDelta = this.quill.getContents(); - spyOn(this.quill.emitter, 'emit').and.callThrough(); - }); - - it('deleteText()', function () { - this.quill.deleteText(3, 2); - const change = new Delta().retain(3).delete(2); - expect(this.quill.root).toEqualHTML('

          012567

          '); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - change, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('format()', function () { - this.quill.setSelection(3, 2); - this.quill.format('bold', true); - const change = new Delta().retain(3).retain(2, { bold: true }); - expect(this.quill.root).toEqualHTML( - '

          01234567

          ', - ); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - change, - this.oldDelta, - Emitter.sources.API, - ); - expect(this.quill.getSelection()).toEqual(new Range(3, 2)); - }); - - it('formatLine()', function () { - this.quill.formatLine(1, 1, 'header', 2); - const change = new Delta().retain(8).retain(1, { header: 2 }); - expect(this.quill.root).toEqualHTML('

          01234567

          '); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - change, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('formatText()', function () { - this.quill.formatText(3, 2, 'bold', true); - const change = new Delta().retain(3).retain(2, { bold: true }); - expect(this.quill.root).toEqualHTML( - '

          01234567

          ', - ); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - change, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('insertEmbed()', function () { - this.quill.insertEmbed(5, 'image', '/assets/favicon.png'); - const change = new Delta() - .retain(5) - .insert({ image: '/assets/favicon.png' }, { italic: true }); - expect(this.quill.root).toEqualHTML( - '

          01234567

          ', - ); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - change, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('insertText()', function () { - this.quill.insertText(5, '|', 'bold', true); - const change = new Delta() - .retain(5) - .insert('|', { bold: true, italic: true }); - expect(this.quill.root).toEqualHTML( - '

          01234|567

          ', - ); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - change, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('enable/disable', function () { - this.quill.disable(); - expect(this.quill.root.getAttribute('contenteditable')).toEqual('false'); - this.quill.enable(); - expect(this.quill.root.getAttribute('contenteditable')).toBeTruthy(); - }); - - it('getBounds() index', function () { - expect(this.quill.getBounds(1)).toBeTruthy(); - }); - - it('getBounds() range', function () { - expect(this.quill.getBounds(new Range(3, 4))).toBeTruthy(); - }); - - it('getFormat()', function () { - const formats = this.quill.getFormat(5); - expect(formats).toEqual({ italic: true }); - }); - - it('getSelection()', function () { - expect(this.quill.getSelection()).toEqual(null); - const range = new Range(1, 2); - this.quill.setSelection(range); - expect(this.quill.getSelection()).toEqual(range); - }); - - it('removeFormat()', function () { - this.quill.removeFormat(5, 1); - const change = new Delta().retain(5).retain(1, { italic: null }); - expect(this.quill.root).toEqualHTML('

          01234567

          '); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - change, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('updateContents() delta', function () { - const delta = new Delta().retain(5).insert('|'); - this.quill.updateContents(delta); - expect(this.quill.root).toEqualHTML('

          01234|567

          '); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - delta, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('updateContents() ops array', function () { - const delta = new Delta().retain(5).insert('|'); - this.quill.updateContents(delta.ops); - expect(this.quill.root).toEqualHTML('

          01234|567

          '); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - delta, - this.oldDelta, - Emitter.sources.API, - ); - }); - }); - - describe('events', function () { - beforeEach(function () { - this.quill = this.initialize(Quill, '

          0123

          '); - this.quill.update(); - spyOn(this.quill.emitter, 'emit').and.callThrough(); - this.oldDelta = this.quill.getContents(); - }); - - it('api text insert', function () { - this.quill.insertText(2, '!'); - const delta = new Delta().retain(2).insert('!'); - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - delta, - this.oldDelta, - Emitter.sources.API, - ); - }); - - it('user text insert', function (done) { - this.container.firstChild.firstChild.firstChild.data = '01!23'; - const delta = new Delta().retain(2).insert('!'); - setTimeout(() => { - expect(this.quill.emitter.emit).toHaveBeenCalledWith( - Emitter.events.TEXT_CHANGE, - delta, - this.oldDelta, - Emitter.sources.USER, - ); - done(); - }, 1); - }); - - function editTest( - oldText, - oldSelection, - newText, - newSelection, - expectedDelta, - ) { - return function (done) { - this.quill.setText(`${oldText}\n`); - this.quill.setSelection(oldSelection); // number or Range - this.quill.update(); - const oldContents = this.quill.getContents(); - const textNode = this.container.firstChild.firstChild.firstChild; - textNode.data = newText; - if (typeof newSelection === 'number') { - this.quill.selection.setNativeRange(textNode, newSelection); - } else { - this.quill.selection.setNativeRange( - textNode, - newSelection.index, - textNode, - newSelection.index + newSelection.length, - ); - } - setTimeout(() => { - const calls = this.quill.emitter.emit.calls.all(); - if ( - calls[calls.length - 1].args[1] === Emitter.events.SELECTION_CHANGE - ) { - calls.pop(); - } - const { args } = calls.pop(); - expect(args).toEqual([ - Emitter.events.TEXT_CHANGE, - expectedDelta, - oldContents, - Emitter.sources.USER, - ]); - done(); - }, 1); - }; - } - - describe('insert a in aaaa', function () { - it( - 'at index 0', - editTest('aaaa', 0, 'aaaaa', 1, new Delta().insert('a')), - ); - it( - 'at index 1', - editTest('aaaa', 1, 'aaaaa', 2, new Delta().retain(1).insert('a')), - ); - it( - 'at index 2', - editTest('aaaa', 2, 'aaaaa', 3, new Delta().retain(2).insert('a')), - ); - it( - 'at index 3', - editTest('aaaa', 3, 'aaaaa', 4, new Delta().retain(3).insert('a')), - ); - }); - - describe('insert a in xaa', function () { - it( - 'at index 1', - editTest('xaa', 1, 'xaaa', 2, new Delta().retain(1).insert('a')), - ); - it( - 'at index 2', - editTest('xaa', 2, 'xaaa', 3, new Delta().retain(2).insert('a')), - ); - it( - 'at index 3', - editTest('xaa', 3, 'xaaa', 4, new Delta().retain(3).insert('a')), - ); - }); - - describe('insert aa in ax', function () { - it('at index 0', editTest('ax', 0, 'aaax', 2, new Delta().insert('aa'))); - it( - 'at index 1', - editTest('ax', 1, 'aaax', 3, new Delta().retain(1).insert('aa')), - ); - }); - - describe('delete a in xaa', function () { - it( - 'at index 1', - editTest('xaa', 2, 'xa', 1, new Delta().retain(1).delete(1)), - ); - it( - 'at index 2', - editTest('xaa', 3, 'xa', 2, new Delta().retain(2).delete(1)), - ); - }); - - describe('forward-delete a in xaa', function () { - it( - 'at index 1', - editTest('xaa', 1, 'xa', 1, new Delta().retain(1).delete(1)), - ); - it( - 'at index 2', - editTest('xaa', 2, 'xa', 2, new Delta().retain(2).delete(1)), - ); - }); - - it( - 'replace yay with y', - editTest( - 'yay', - new Range(0, 3), - 'y', - 1, - new Delta().insert('y').delete(3), - ), - ); - }); - - describe('setContents()', function () { - it('empty', function () { - const quill = this.initialize(Quill, ''); - const delta = new Delta().insert('\n'); - quill.setContents(delta); - expect(quill.getContents()).toEqual(delta); - expect(quill.root).toEqualHTML('


          '); - }); - - it('single line', function () { - const quill = this.initialize(Quill, ''); - const delta = new Delta().insert('Hello World!\n'); - quill.setContents(delta); - expect(quill.getContents()).toEqual(delta); - expect(quill.root).toEqualHTML('

          Hello World!

          '); - }); - - it('multiple lines', function () { - const quill = this.initialize(Quill, ''); - const delta = new Delta().insert('Hello\n\nWorld!\n'); - quill.setContents(delta); - expect(quill.getContents()).toEqual(delta); - expect(quill.root).toEqualHTML('

          Hello


          World!

          '); - }); - - it('basic formats', function () { - const quill = this.initialize(Quill, ''); - const delta = new Delta() - .insert('Welcome') - .insert('\n', { header: 1 }) - .insert('Hello\n') - .insert('World') - .insert('!', { bold: true }) - .insert('\n'); - quill.setContents(delta); - expect(quill.getContents()).toEqual(delta); - expect(quill.root).toEqualHTML(` -

          Welcome

          -

          Hello

          -

          World!

          - `); - }); - - it('array of operations', function () { - const quill = this.initialize(Quill, ''); - const delta = new Delta() - .insert('test') - .insert('123', { bold: true }) - .insert('\n'); - quill.setContents(delta.ops); - expect(quill.getContents()).toEqual(delta); - }); - - it('json', function () { - const quill = this.initialize(Quill, ''); - const delta = { ops: [{ insert: 'test\n' }] }; - quill.setContents(delta); - expect(quill.getContents()).toEqual(new Delta(delta)); - }); - - it('no trailing newline', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - quill.setContents(new Delta().insert('0123')); - expect(quill.getContents()).toEqual(new Delta().insert('0123\n')); - }); - - it('inline formatting', function () { - const quill = this.initialize( - Quill, - '

          Bold

          Not bold

          ', - ); - const contents = quill.getContents(); - const delta = quill.setContents(contents); - expect(quill.getContents()).toEqual(contents); - expect(delta).toEqual(contents.delete(contents.length())); - }); - - it('block embed', function () { - const quill = this.initialize(Quill, '

          Hello World!

          '); - const contents = new Delta().insert({ video: '#' }); - quill.setContents(contents); - expect(quill.getContents()).toEqual(contents); - }); - }); - - describe('getText()', function () { - it('return all text by default', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - expect(quill.getText()).toEqualHTML('Welcome'); - }); - - it('works when only provide index', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - expect(quill.getText(2)).toEqualHTML('lcome'); - }); - - it('works with range', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - expect(quill.getText({ index: 1, length: 2 })).toEqualHTML('el'); - }); - }); - - describe('setText()', function () { - it('overwrite', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - quill.setText('abc'); - expect(quill.root).toEqualHTML('

          abc

          '); - }); - - it('set to newline', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - quill.setText('\n'); - expect(quill.root).toEqualHTML('


          '); - }); - - it('multiple newlines', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - quill.setText('\n\n'); - expect(quill.root).toEqualHTML('



          '); - }); - - it('content with trailing newline', function () { - const quill = this.initialize(Quill, '

          Welcome

          '); - quill.setText('abc\n'); - expect(quill.root).toEqualHTML('

          abc

          '); - }); - - it('return carriage', function () { - const quill = this.initialize(Quill, '

          Test

          '); - quill.setText('\r'); - expect(quill.root).toEqualHTML('


          '); - }); - - it('return carriage newline', function () { - const quill = this.initialize(Quill, '

          Test

          '); - quill.setText('\r\n'); - expect(quill.root).toEqualHTML('


          '); - }); - }); - - describe('expandConfig', function () { - it('user overwrite quill', function () { - const config = expandConfig('#test-container', { - placeholder: 'Test', - readOnly: true, - }); - expect(config.placeholder).toEqual('Test'); - expect(config.readOnly).toEqual(true); - }); - - it('convert css selectors', function () { - const config = expandConfig('#test-container', { - bounds: '#test-container', - }); - expect(config.bounds).toEqual(document.querySelector('#test-container')); - expect(config.container).toEqual( - document.querySelector('#test-container'), - ); - }); - - xit('convert module true to {}', function () { - Quill.debug(0); - const oldModules = Theme.DEFAULTS.modules; - Theme.DEFAULTS.modules = { - formula: true, - }; - const config = expandConfig('#test-container', { - modules: { - syntax: true, - }, - }); - Quill.debug('error'); - expect(config.modules.formula).toEqual({}); - expect(config.modules.syntax).toEqual({ - highlight: null, - interval: 1000, - }); - Theme.DEFAULTS.modules = oldModules; - }); - - describe('theme defaults', function () { - it('for Snow', function () { - const config = expandConfig('#test-container', { - modules: { - toolbar: true, - }, - theme: 'snow', - }); - expect(config.theme).toEqual(Snow); - expect(config.modules.toolbar.handlers.image).toEqual( - Snow.DEFAULTS.modules.toolbar.handlers.image, - ); - }); - - it('for false', function () { - const config = expandConfig('#test-container', { - theme: false, - }); - expect(config.theme).toEqual(Theme); - }); - - it('for undefined', function () { - const config = expandConfig('#test-container', { - theme: undefined, - }); - expect(config.theme).toEqual(Theme); - }); - - it('for null', function () { - const config = expandConfig('#test-container', { - theme: null, - }); - expect(config.theme).toEqual(Theme); - }); - }); - - it('quill < module < theme < user', function () { - const oldTheme = Theme.DEFAULTS.modules; - const oldToolbar = Toolbar.DEFAULTS; - Toolbar.DEFAULTS = { - option: 2, - module: true, - }; - Theme.DEFAULTS.modules = { - toolbar: { - option: 1, - theme: true, - }, - }; - const config = expandConfig('#test-container', { - modules: { - toolbar: { - option: 0, - user: true, - }, - }, - }); - expect(config.modules.toolbar).toEqual({ - option: 0, - module: true, - theme: true, - user: true, - }); - Theme.DEFAULTS.modules = oldTheme; - Toolbar.DEFAULTS = oldToolbar; - }); - - it('toolbar default', function () { - const config = expandConfig('#test-container', { - modules: { - toolbar: true, - }, - }); - expect(config.modules.toolbar).toEqual(Toolbar.DEFAULTS); - }); - - it('toolbar disabled', function () { - const config = expandConfig('#test-container', { - modules: { - toolbar: false, - }, - theme: 'snow', - }); - expect(config.modules.toolbar).toBe(undefined); - }); - - it('toolbar selector', function () { - const config = expandConfig('#test-container', { - modules: { - toolbar: { - container: '#test-container', - }, - }, - }); - expect(config.modules.toolbar).toEqual({ - container: '#test-container', - handlers: Toolbar.DEFAULTS.handlers, - }); - }); - - it('toolbar container shorthand', function () { - const config = expandConfig('#test-container', { - modules: { - toolbar: document.querySelector('#test-container'), - }, - }); - expect(config.modules.toolbar).toEqual({ - container: document.querySelector('#test-container'), - handlers: Toolbar.DEFAULTS.handlers, - }); - }); - - it('toolbar format array', function () { - const config = expandConfig('#test-container', { - modules: { - toolbar: ['bold'], - }, - }); - expect(config.modules.toolbar).toEqual({ - container: ['bold'], - handlers: Toolbar.DEFAULTS.handlers, - }); - }); - - it('toolbar custom handler, default container', function () { - const handler = function () {}; // eslint-disable-line func-style - const config = expandConfig('#test-container', { - modules: { - toolbar: { - handlers: { - bold: handler, - }, - }, - }, - }); - expect(config.modules.toolbar.container).toEqual(null); - expect(config.modules.toolbar.handlers.bold).toEqual(handler); - expect(config.modules.toolbar.handlers.clean).toEqual( - Toolbar.DEFAULTS.handlers.clean, - ); - }); - }); - - describe('overload', function () { - it('(index:number, length:number)', function () { - const [index, length, formats, source] = overload(0, 1); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({}); - expect(source).toBe(Quill.sources.API); - }); - - it('(index:number, length:number, format:string, value:boolean, source:string)', function () { - const [index, length, formats, source] = overload( - 0, - 1, - 'bold', - true, - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.USER); - }); - - it('(index:number, length:number, format:string, value:string, source:string)', function () { - const [index, length, formats, source] = overload( - 0, - 1, - 'color', - Quill.sources.USER, - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ color: Quill.sources.USER }); - expect(source).toBe(Quill.sources.USER); - }); - - it('(index:number, length:number, format:string, value:string)', function () { - const [index, length, formats, source] = overload( - 0, - 1, - 'color', - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ color: Quill.sources.USER }); - expect(source).toBe(Quill.sources.API); - }); - - it('(index:number, length:number, format:object)', function () { - const [index, length, formats, source] = overload(0, 1, { bold: true }); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.API); - }); - - it('(index:number, length:number, format:object, source:string)', function () { - const [index, length, formats, source] = overload( - 0, - 1, - { bold: true }, - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.USER); - }); - - it('(index:number, length:number, source:string)', function () { - const [index, length, formats, source] = overload( - 0, - 1, - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({}); - expect(source).toBe(Quill.sources.USER); - }); - - it('(index:number, source:string)', function () { - const [index, length, formats, source] = overload(0, Quill.sources.USER); - expect(index).toBe(0); - expect(length).toBe(0); - expect(formats).toEqual({}); - expect(source).toBe(Quill.sources.USER); - }); - - it('(range:range)', function () { - const [index, length, formats, source] = overload(new Range(0, 1)); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({}); - expect(source).toBe(Quill.sources.API); - }); - - it('(range:range, format:string, value:boolean, source:string)', function () { - const [index, length, formats, source] = overload( - new Range(0, 1), - 'bold', - true, - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.USER); - }); - - it('(range:range, format:string, value:string, source:string)', function () { - const [index, length, formats, source] = overload( - new Range(0, 1), - 'color', - Quill.sources.API, - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ color: Quill.sources.API }); - expect(source).toBe(Quill.sources.USER); - }); - - it('(range:range, format:string, value:string)', function () { - const [index, length, formats, source] = overload( - new Range(0, 1), - 'color', - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ color: Quill.sources.USER }); - expect(source).toBe(Quill.sources.API); - }); - - it('(range:range, format:object)', function () { - const [index, length, formats, source] = overload(new Range(0, 1), { - bold: true, - }); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.API); - }); - - it('(range:range, format:object, source:string)', function () { - const [index, length, formats, source] = overload( - new Range(0, 1), - { bold: true }, - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.USER); - }); - - it('(range:range, source:string)', function () { - const [index, length, formats, source] = overload( - new Range(0, 1), - Quill.sources.USER, - ); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({}); - expect(source).toBe(Quill.sources.USER); - }); - - it('(range:range)', function () { - const [index, length, formats, source] = overload(new Range(0, 1)); - expect(index).toBe(0); - expect(length).toBe(1); - expect(formats).toEqual({}); - expect(source).toBe(Quill.sources.API); - }); - - it('(range:range, dummy:number)', function () { - const [index, length, formats, source] = overload(new Range(10, 1), 0); - expect(index).toBe(10); - expect(length).toBe(1); - expect(formats).toEqual({}); - expect(source).toBe(Quill.sources.API); - }); - - it('(range:range, dummy:number, format:string, value:boolean)', function () { - const [index, length, formats, source] = overload( - new Range(10, 1), - 0, - 'bold', - true, - ); - expect(index).toBe(10); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.API); - }); - - it('(range:range, dummy:number, format:object, source:string)', function () { - const [index, length, formats, source] = overload( - new Range(10, 1), - 0, - { bold: true }, - Quill.sources.USER, - ); - expect(index).toBe(10); - expect(length).toBe(1); - expect(formats).toEqual({ bold: true }); - expect(source).toBe(Quill.sources.USER); - }); - }); - - describe('placeholder', function () { - beforeEach(function () { - this.initialize(HTMLElement, '

          '); - this.quill = new Quill(this.container.firstChild, { - placeholder: 'a great day to be a placeholder', - }); - this.original = this.quill.getContents(); - }); - - it('blank editor', function () { - expect(this.quill.root.dataset.placeholder).toEqual( - 'a great day to be a placeholder', - ); - expect(this.quill.root.classList).toContain('ql-blank'); - }); - - it('with text', function () { - this.quill.setText('test'); - expect(this.quill.root.classList).not.toContain('ql-blank'); - }); - - it('formatted line', function () { - this.quill.formatLine(0, 1, 'list', 'ordered'); - expect(this.quill.root.classList).not.toContain('ql-blank'); - }); - }); -}); diff --git a/test/unit/core/quill.spec.ts b/test/unit/core/quill.spec.ts new file mode 100644 index 0000000000..2e0151ba61 --- /dev/null +++ b/test/unit/core/quill.spec.ts @@ -0,0 +1,1000 @@ +import '../../../quill'; +import Delta from 'quill-delta'; +import { + MockedFunction, + beforeEach, + describe, + expect, + test, + vitest, +} from 'vitest'; +import Emitter from '../../../core/emitter'; +import Theme from '../../../core/theme'; +import Toolbar from '../../../modules/toolbar'; +import Quill, { expandConfig, overload } from '../../../core/quill'; +import { Range } from '../../../core/selection'; +import Snow from '../../../themes/snow'; +import { normalizeHTML } from '../__helpers__/utils'; + +const createContainer = (html: string | { html: string } = '') => { + const container = document.createElement('div'); + container.innerHTML = normalizeHTML(html); + document.body.appendChild(container); + return container; +}; + +describe('Quill', () => { + test('imports', () => { + Object.keys(Quill.imports).forEach(path => { + expect(Quill.import(path)).toBeTruthy(); + }); + }); + + describe('construction', () => { + test('empty', () => { + const quill = new Quill(createContainer()); + expect(quill.getContents()).toEqual(new Delta().insert('\n')); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"


          "'); + }); + + test('text', () => { + const quill = new Quill(createContainer('0123')); + expect(quill.getContents()).toEqual(new Delta().insert('0123\n')); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"

          0123

          "'); + }); + + test('newlines', () => { + const quill = new Quill( + createContainer('




          '), + ); + expect(quill.getContents()).toEqual(new Delta().insert('\n\n\n')); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"




          "', + ); + }); + + test('formatted ending', () => { + const quill = new Quill( + createContainer('

          Test

          '), + ); + expect(quill.getContents()).toEqual( + new Delta().insert('Test').insert('\n', { align: 'center' }), + ); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          Test

          "', + ); + }); + }); + + describe('api', () => { + const setup = () => { + const quill = new Quill(createContainer('

          01234567

          ')); + const oldDelta = quill.getContents(); + vitest.spyOn(quill.emitter, 'emit'); + return { quill, oldDelta }; + }; + + test('deleteText()', () => { + const { quill, oldDelta } = setup(); + quill.deleteText(3, 2); + const change = new Delta().retain(3).delete(2); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          012567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + change, + oldDelta, + Emitter.sources.API, + ); + }); + + test('format()', () => { + const { quill, oldDelta } = setup(); + quill.setSelection(3, 2); + quill.format('bold', true); + const change = new Delta().retain(3).retain(2, { bold: true }); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + change, + oldDelta, + Emitter.sources.API, + ); + expect(quill.getSelection()).toEqual(new Range(3, 2)); + }); + + test('formatLine()', () => { + const { quill, oldDelta } = setup(); + quill.formatLine(1, 1, 'header', 2); + const change = new Delta().retain(8).retain(1, { header: 2 }); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + change, + oldDelta, + Emitter.sources.API, + ); + }); + + test('formatText()', () => { + const { quill, oldDelta } = setup(); + // @ts-expect-error + quill.formatText(3, 2, 'bold', true); + const change = new Delta().retain(3).retain(2, { bold: true }); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + change, + oldDelta, + Emitter.sources.API, + ); + }); + + test('insertEmbed()', () => { + const { quill, oldDelta } = setup(); + quill.insertEmbed(5, 'image', '/assets/favicon.png'); + const change = new Delta() + .retain(5) + .insert({ image: '/assets/favicon.png' }, { italic: true }); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + change, + oldDelta, + Emitter.sources.API, + ); + }); + + test('insertText()', () => { + const { quill, oldDelta } = setup(); + // @ts-expect-error + quill.insertText(5, '|', 'bold', true); + const change = new Delta() + .retain(5) + .insert('|', { bold: true, italic: true }); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234|567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + change, + oldDelta, + Emitter.sources.API, + ); + }); + + test('enable/disable', () => { + const { quill } = setup(); + quill.disable(); + expect(quill.root.getAttribute('contenteditable')).toEqual('false'); + quill.enable(); + expect(quill.root.getAttribute('contenteditable')).toBeTruthy(); + }); + + test('getBounds() index', () => { + const { quill } = setup(); + expect(quill.getBounds(1)).toBeTruthy(); + }); + + test('getBounds() range', () => { + const { quill } = setup(); + expect(quill.getBounds(new Range(3, 4))).toBeTruthy(); + }); + + test('getFormat()', () => { + const { quill } = setup(); + const formats = quill.getFormat(5); + expect(formats).toEqual({ italic: true }); + }); + + test('getSelection()', () => { + const { quill } = setup(); + expect(quill.getSelection()).toEqual(null); + const range = new Range(1, 2); + quill.setSelection(range); + expect(quill.getSelection()).toEqual(range); + }); + + test('removeFormat()', () => { + const { quill, oldDelta } = setup(); + // @ts-expect-error + quill.removeFormat(5, 1); + const change = new Delta().retain(5).retain(1, { italic: null }); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + change, + oldDelta, + Emitter.sources.API, + ); + }); + + test('updateContents() delta', () => { + const { quill, oldDelta } = setup(); + const delta = new Delta().retain(5).insert('|'); + quill.updateContents(delta); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234|567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + delta, + oldDelta, + Emitter.sources.API, + ); + }); + + test('updateContents() ops array', () => { + const { quill, oldDelta } = setup(); + const delta = new Delta().retain(5).insert('|'); + quill.updateContents(delta.ops); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          01234|567

          "', + ); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + delta, + oldDelta, + Emitter.sources.API, + ); + }); + }); + + describe('events', () => { + const setup = () => { + const quill = new Quill(createContainer('

          0123

          ')); + quill.update(); + vitest.spyOn(quill.emitter, 'emit'); + const oldDelta = quill.getContents(); + return { quill, oldDelta }; + }; + + test('api text insert', () => { + const { quill, oldDelta } = setup(); + // @ts-expect-error + quill.insertText(2, '!'); + const delta = new Delta().retain(2).insert('!'); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + delta, + oldDelta, + Emitter.sources.API, + ); + }); + + test('user text insert', async () => { + const { quill, oldDelta } = setup(); + (quill.root.firstChild?.firstChild as Text).data = '01!23'; + const delta = new Delta().retain(2).insert('!'); + + await new Promise(r => setTimeout(r, 1)); + expect(quill.emitter.emit).toHaveBeenCalledWith( + Emitter.events.TEXT_CHANGE, + delta, + oldDelta, + Emitter.sources.USER, + ); + }); + + const editTest = ( + oldText: string, + oldSelection: number | Range, + newText: string, + newSelection: number | Range, + expectedDelta: Delta, + ) => { + return async () => { + const { quill } = setup(); + quill.setText(`${oldText}\n`); + // @ts-expect-error + quill.setSelection(oldSelection); + quill.update(); + const oldContents = quill.getContents(); + const textNode = quill.root.firstChild?.firstChild as Text; + textNode.data = newText; + if (typeof newSelection === 'number') { + quill.selection.setNativeRange(textNode, newSelection); + } else { + quill.selection.setNativeRange( + textNode, + newSelection.index, + textNode, + newSelection.index + newSelection.length, + ); + } + await new Promise(r => setTimeout(r, 1)); + const calls = ( + quill.emitter.emit as MockedFunction + ).mock.calls; + if (calls[calls.length - 1][1] === Emitter.events.SELECTION_CHANGE) { + calls.pop(); + } + const args = calls.pop(); + expect(args).toEqual([ + Emitter.events.TEXT_CHANGE, + expectedDelta, + oldContents, + Emitter.sources.USER, + ]); + }; + }; + + describe('insert a in aaaa', () => { + test( + 'at index 0', + editTest('aaaa', 0, 'aaaaa', 1, new Delta().insert('a')), + ); + test( + 'at index 1', + editTest('aaaa', 1, 'aaaaa', 2, new Delta().retain(1).insert('a')), + ); + test( + 'at index 2', + editTest('aaaa', 2, 'aaaaa', 3, new Delta().retain(2).insert('a')), + ); + test( + 'at index 3', + editTest('aaaa', 3, 'aaaaa', 4, new Delta().retain(3).insert('a')), + ); + }); + + describe('insert a in xaa', () => { + test( + 'at index 1', + editTest('xaa', 1, 'xaaa', 2, new Delta().retain(1).insert('a')), + ); + test( + 'at index 2', + editTest('xaa', 2, 'xaaa', 3, new Delta().retain(2).insert('a')), + ); + test( + 'at index 3', + editTest('xaa', 3, 'xaaa', 4, new Delta().retain(3).insert('a')), + ); + }); + + describe('insert aa in ax', () => { + test( + 'at index 0', + editTest('ax', 0, 'aaax', 2, new Delta().insert('aa')), + ); + test( + 'at index 1', + editTest('ax', 1, 'aaax', 3, new Delta().retain(1).insert('aa')), + ); + }); + + describe('delete a in xaa', () => { + test( + 'at index 1', + editTest('xaa', 2, 'xa', 1, new Delta().retain(1).delete(1)), + ); + test( + 'at index 2', + editTest('xaa', 3, 'xa', 2, new Delta().retain(2).delete(1)), + ); + }); + + describe('forward-delete a in xaa', () => { + test( + 'at index 1', + editTest('xaa', 1, 'xa', 1, new Delta().retain(1).delete(1)), + ); + test( + 'at index 2', + editTest('xaa', 2, 'xa', 2, new Delta().retain(2).delete(1)), + ); + }); + + test( + 'replace yay with y', + editTest( + 'yay', + new Range(0, 3), + 'y', + 1, + new Delta().insert('y').delete(3), + ), + ); + }); + + describe('setContents()', () => { + test('empty', () => { + const quill = new Quill(createContainer('')); + const delta = new Delta().insert('\n'); + quill.setContents(delta); + expect(quill.getContents()).toEqual(delta); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"


          "'); + }); + + test('single line', () => { + const quill = new Quill(createContainer('')); + const delta = new Delta().insert('Hello World!\n'); + quill.setContents(delta); + expect(quill.getContents()).toEqual(delta); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          Hello World!

          "', + ); + }); + + test('multiple lines', () => { + const quill = new Quill(createContainer('')); + const delta = new Delta().insert('Hello\n\nWorld!\n'); + quill.setContents(delta); + expect(quill.getContents()).toEqual(delta); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          Hello


          World!

          "', + ); + }); + + test('basic formats', () => { + const quill = new Quill(createContainer('')); + const delta = new Delta() + .insert('Welcome') + .insert('\n', { header: 1 }) + .insert('Hello\n') + .insert('World') + .insert('!', { bold: true }) + .insert('\n'); + quill.setContents(delta); + expect(quill.getContents()).toEqual(delta); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"

          Welcome

          Hello

          World!

          "', + ); + }); + + test('array of operations', () => { + const quill = new Quill(createContainer('')); + const delta = new Delta() + .insert('test') + .insert('123', { bold: true }) + .insert('\n'); + quill.setContents(delta.ops); + expect(quill.getContents()).toEqual(delta); + }); + + test('json', () => { + const quill = new Quill(createContainer('')); + const delta = new Delta().insert('test\n'); + quill.setContents(delta); + expect(quill.getContents()).toEqual(new Delta(delta)); + }); + + test('no trailing newline', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + quill.setContents(new Delta().insert('0123')); + expect(quill.getContents()).toEqual(new Delta().insert('0123\n')); + }); + + test('inline formatting', () => { + const quill = new Quill( + createContainer('

          Bold

          Not bold

          '), + ); + const contents = quill.getContents(); + const delta = quill.setContents(contents); + expect(quill.getContents()).toEqual(contents); + expect(delta).toEqual(contents.delete(contents.length())); + }); + + test('block embed', () => { + const quill = new Quill(createContainer('

          Hello World!

          ')); + const contents = new Delta().insert({ video: '#' }); + quill.setContents(contents); + expect(quill.getContents()).toEqual(contents); + }); + }); + + describe('getText()', () => { + test('return all text by default', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + expect(quill.getText()).toMatchInlineSnapshot(` + "Welcome + " + `); + }); + + test('works when only provide index', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + expect(quill.getText(2)).toMatchInlineSnapshot(` + "lcome + " + `); + }); + + test('works with range', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + expect(quill.getText({ index: 1, length: 2 })).toMatchInlineSnapshot( + '"el"', + ); + }); + }); + + describe('setText()', () => { + test('overwrite', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + quill.setText('abc'); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"

          abc

          "'); + }); + + test('set to newline', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + quill.setText('\n'); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"


          "'); + }); + + test('multiple newlines', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + quill.setText('\n\n'); + expect(quill.root.innerHTML).toMatchInlineSnapshot( + '"



          "', + ); + }); + + test('content with trailing newline', () => { + const quill = new Quill(createContainer('

          Welcome

          ')); + quill.setText('abc\n'); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"

          abc

          "'); + }); + + test('return carriage', () => { + const quill = new Quill(createContainer('

          Test

          ')); + quill.setText('\r'); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"


          "'); + }); + + test('return carriage newline', () => { + const quill = new Quill(createContainer('

          Test

          ')); + quill.setText('\r\n'); + expect(quill.root.innerHTML).toMatchInlineSnapshot('"


          "'); + }); + }); + + describe('expandConfig', () => { + const testContainerId = 'testContainer'; + beforeEach(() => { + const testContainer = document.createElement('div'); + testContainer.id = testContainerId; + document.body.appendChild(testContainer); + }); + + test('user overwrite quill', () => { + const config = expandConfig(`#${testContainerId}`, { + placeholder: 'Test', + readOnly: true, + }); + expect(config.placeholder).toEqual('Test'); + expect(config.readOnly).toEqual(true); + }); + + test('convert css selectors', () => { + const config = expandConfig(`#${testContainerId}`, { + bounds: `#${testContainerId}`, + }); + expect(config.bounds).toEqual( + document.querySelector(`#${testContainerId}`), + ); + expect(config.container).toEqual( + document.querySelector(`#${testContainerId}`), + ); + }); + + test('convert module true to {}', () => { + const config = expandConfig(`#${testContainerId}`, { + modules: { + syntax: true, + }, + }); + expect(config.modules.syntax).toMatchObject({ + interval: 1000, + }); + }); + + describe('theme defaults', () => { + test('for Snow', () => { + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: true, + }, + theme: 'snow', + }); + expect(config.theme).toEqual(Snow); + // @ts-expect-error + expect(config.modules.toolbar.handlers.image).toEqual( + // @ts-expect-error + Snow.DEFAULTS.modules.toolbar.handlers.image, + ); + }); + + test('for false', () => { + const config = expandConfig(`#${testContainerId}`, { + // @ts-expect-error + theme: false, + }); + expect(config.theme).toEqual(Theme); + }); + + test('for undefined', () => { + const config = expandConfig(`#${testContainerId}`, { + theme: undefined, + }); + expect(config.theme).toEqual(Theme); + }); + + test('for null', () => { + const config = expandConfig(`#${testContainerId}`, { + // @ts-expect-error + theme: null, + }); + expect(config.theme).toEqual(Theme); + }); + }); + + test('quill < module < theme < user', () => { + const oldTheme = Theme.DEFAULTS.modules; + const oldToolbar = Toolbar.DEFAULTS; + Toolbar.DEFAULTS = { + // @ts-expect-error + option: 2, + module: true, + }; + Theme.DEFAULTS.modules = { + toolbar: { + option: 1, + theme: true, + }, + }; + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: { + option: 0, + user: true, + }, + }, + }); + expect(config.modules.toolbar).toEqual({ + option: 0, + module: true, + theme: true, + user: true, + }); + Theme.DEFAULTS.modules = oldTheme; + Toolbar.DEFAULTS = oldToolbar; + }); + + test('toolbar default', () => { + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: true, + }, + }); + expect(config.modules.toolbar).toEqual(Toolbar.DEFAULTS); + }); + + test('toolbar disabled', () => { + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: false, + }, + theme: 'snow', + }); + expect(config.modules.toolbar).toBe(undefined); + }); + + test('toolbar selector', () => { + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: { + container: `#${testContainerId}`, + }, + }, + }); + expect(config.modules.toolbar).toEqual({ + container: `#${testContainerId}`, + handlers: Toolbar.DEFAULTS.handlers, + }); + }); + + test('toolbar container shorthand', () => { + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: document.querySelector(`#${testContainerId}`), + }, + }); + expect(config.modules.toolbar).toEqual({ + container: document.querySelector(`#${testContainerId}`), + handlers: Toolbar.DEFAULTS.handlers, + }); + }); + + test('toolbar format array', () => { + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: ['bold'], + }, + }); + expect(config.modules.toolbar).toEqual({ + container: ['bold'], + handlers: Toolbar.DEFAULTS.handlers, + }); + }); + + test('toolbar custom handler, default container', () => { + const handler = () => {}; // eslint-disable-line func-style + const config = expandConfig(`#${testContainerId}`, { + modules: { + toolbar: { + handlers: { + bold: handler, + }, + }, + }, + }); + // @ts-expect-error + expect(config.modules.toolbar.container).toEqual(null); + // @ts-expect-error + expect(config.modules.toolbar.handlers.bold).toEqual(handler); + // @ts-expect-error + expect(config.modules.toolbar.handlers.clean).toEqual( + // @ts-expect-error + Toolbar.DEFAULTS.handlers.clean, + ); + }); + }); + + describe('overload', () => { + test('(index:number, length:number)', () => { + const [index, length, formats, source] = overload(0, 1); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({}); + expect(source).toBe(Quill.sources.API); + }); + + test('(index:number, length:number, format:string, value:boolean, source:string)', () => { + const [index, length, formats, source] = overload( + 0, + 1, + 'bold', + true, + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.USER); + }); + + test('(index:number, length:number, format:string, value:string, source:string)', () => { + const [index, length, formats, source] = overload( + 0, + 1, + 'color', + Quill.sources.USER, + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ color: Quill.sources.USER }); + expect(source).toBe(Quill.sources.USER); + }); + + test('(index:number, length:number, format:string, value:string)', () => { + const [index, length, formats, source] = overload( + 0, + 1, + 'color', + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ color: Quill.sources.USER }); + expect(source).toBe(Quill.sources.API); + }); + + test('(index:number, length:number, format:object)', () => { + const [index, length, formats, source] = overload(0, 1, { bold: true }); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.API); + }); + + test('(index:number, length:number, format:object, source:string)', () => { + const [index, length, formats, source] = overload( + 0, + 1, + { bold: true }, + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.USER); + }); + + test('(index:number, length:number, source:string)', () => { + const [index, length, formats, source] = overload( + 0, + 1, + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({}); + expect(source).toBe(Quill.sources.USER); + }); + + test('(index:number, source:string)', () => { + const [index, length, formats, source] = overload(0, Quill.sources.USER); + expect(index).toBe(0); + expect(length).toBe(0); + expect(formats).toEqual({}); + expect(source).toBe(Quill.sources.USER); + }); + + test('(range:range)', () => { + const [index, length, formats, source] = overload(new Range(0, 1)); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({}); + expect(source).toBe(Quill.sources.API); + }); + + test('(range:range, format:string, value:boolean, source:string)', () => { + const [index, length, formats, source] = overload( + new Range(0, 1), + 'bold', + true, + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.USER); + }); + + test('(range:range, format:string, value:string, source:string)', () => { + const [index, length, formats, source] = overload( + new Range(0, 1), + 'color', + Quill.sources.API, + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ color: Quill.sources.API }); + expect(source).toBe(Quill.sources.USER); + }); + + test('(range:range, format:string, value:string)', () => { + const [index, length, formats, source] = overload( + new Range(0, 1), + 'color', + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ color: Quill.sources.USER }); + expect(source).toBe(Quill.sources.API); + }); + + test('(range:range, format:object)', () => { + const [index, length, formats, source] = overload(new Range(0, 1), { + bold: true, + }); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.API); + }); + + test('(range:range, format:object, source:string)', () => { + const [index, length, formats, source] = overload( + new Range(0, 1), + { bold: true }, + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.USER); + }); + + test('(range:range, source:string)', () => { + const [index, length, formats, source] = overload( + new Range(0, 1), + Quill.sources.USER, + ); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({}); + expect(source).toBe(Quill.sources.USER); + }); + + test('(range:range)', () => { + const [index, length, formats, source] = overload(new Range(0, 1)); + expect(index).toBe(0); + expect(length).toBe(1); + expect(formats).toEqual({}); + expect(source).toBe(Quill.sources.API); + }); + + test('(range:range, dummy:number)', () => { + // @ts-expect-error + const [index, length, formats, source] = overload(new Range(10, 1), 0); + expect(index).toBe(10); + expect(length).toBe(1); + expect(formats).toEqual({}); + expect(source).toBe(Quill.sources.API); + }); + + test('(range:range, dummy:number, format:string, value:boolean)', () => { + // @ts-expect-error + const [index, length, formats, source] = overload( + new Range(10, 1), + 0, + 'bold', + true, + ); + expect(index).toBe(10); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.API); + }); + + test('(range:range, dummy:number, format:object, source:string)', () => { + // @ts-expect-error + const [index, length, formats, source] = overload( + new Range(10, 1), + 0, + { bold: true }, + Quill.sources.USER, + ); + expect(index).toBe(10); + expect(length).toBe(1); + expect(formats).toEqual({ bold: true }); + expect(source).toBe(Quill.sources.USER); + }); + }); + + describe('placeholder', () => { + const setup = () => { + const container = createContainer('

          '); + const quill = new Quill(container, { + placeholder: 'a great day to be a placeholder', + }); + return { quill }; + }; + + test('blank editor', () => { + const { quill } = setup(); + expect(quill.root.dataset.placeholder).toEqual( + 'a great day to be a placeholder', + ); + expect([...quill.root.classList]).toContain('ql-blank'); + }); + + test('with text', () => { + const { quill } = setup(); + quill.setText('test'); + expect([...quill.root.classList]).not.toContain('ql-blank'); + }); + + test('formatted line', () => { + const { quill } = setup(); + quill.formatLine(0, 1, 'list', 'ordered'); + expect([...quill.root.classList]).not.toContain('ql-blank'); + }); + }); +}); diff --git a/test/unit/core/selection.js b/test/unit/core/selection.js deleted file mode 100644 index d09ec459d1..0000000000 --- a/test/unit/core/selection.js +++ /dev/null @@ -1,660 +0,0 @@ -import Selection, { Range } from '../../../core/selection'; -import Cursor from '../../../blots/cursor'; -import Emitter from '../../../core/emitter'; - -describe('Selection', function () { - beforeEach(function () { - this.setup = (html, index) => { - this.selection = this.initialize(Selection, html); - this.selection.setRange(new Range(index)); - }; - }); - - describe('focus()', function () { - beforeEach(function () { - this.initialize(HTMLElement, '
          '); - this.selection = this.initialize( - Selection, - '

          0123

          ', - this.container.lastChild, - ); - this.textarea = this.container.querySelector('textarea'); - this.textarea.focus(); - this.textarea.select(); - }); - - it('initial focus', function () { - expect(this.selection.hasFocus()).toBe(false); - this.selection.focus(); - expect(this.selection.hasFocus()).toBe(true); - }); - - it('restore last range', function () { - const range = new Range(1, 2); - this.selection.setRange(range); - this.textarea.focus(); - this.textarea.select(); - expect(this.selection.hasFocus()).toBe(false); - this.selection.focus(); - expect(this.selection.hasFocus()).toBe(true); - expect(this.selection.getRange()[0]).toEqual(range); - }); - }); - - describe('getRange()', function () { - it('empty document', function () { - const selection = this.initialize(Selection, ''); - selection.setNativeRange(this.container.querySelector('br'), 0); - const [range] = selection.getRange(); - expect(range.index).toEqual(0); - expect(range.length).toEqual(0); - }); - - it('empty line', function () { - const selection = this.initialize( - Selection, - '

          0


          3

          ', - ); - selection.setNativeRange(this.container.querySelector('br'), 0); - const [range] = selection.getRange(); - expect(range.index).toEqual(2); - expect(range.length).toEqual(0); - }); - - it('end of line', function () { - const selection = this.initialize(Selection, '

          0

          '); - selection.setNativeRange(this.container.firstChild.firstChild, 1); - const [range] = selection.getRange(); - expect(range.index).toEqual(1); - expect(range.length).toEqual(0); - }); - - it('text node', function () { - const selection = this.initialize(Selection, '

          0123

          '); - selection.setNativeRange(this.container.firstChild.firstChild, 1); - const [range] = selection.getRange(); - expect(range.index).toEqual(1); - expect(range.length).toEqual(0); - }); - - it('line boundaries', function () { - const selection = this.initialize(Selection, '


          12

          '); - selection.setNativeRange( - this.container.firstChild, - 0, - this.container.lastChild.lastChild, - 2, - ); - const [range] = selection.getRange(); - expect(range.index).toEqual(0); - expect(range.length).toEqual(3); - }); - - it('nested text node', function () { - const selection = this.initialize( - Selection, - ` -

          01

          -
            -
          1. 34
          2. -
          `, - ); - selection.setNativeRange( - this.container.querySelector('em').firstChild, - 1, - this.container.querySelector('u').firstChild, - 1, - ); - const [range] = selection.getRange(); - expect(range.index).toEqual(1); - expect(range.length).toEqual(3); - }); - - it('between embed across lines', function () { - const selection = this.initialize( - Selection, - ` -

          - - -

          -

          - - -

          `, - ); - selection.setNativeRange( - this.container.firstChild, - 1, - this.container.lastChild, - 1, - ); - const [range] = selection.getRange(); - expect(range.index).toEqual(1); - expect(range.length).toEqual(3); - }); - - it('between embed across list', function () { - const selection = this.initialize( - Selection, - ` -

          - - -

          -
            -
          1. - - -
          2. -
          `, - ); - selection.setNativeRange( - this.container.firstChild, - 1, - this.container.lastChild.firstChild, - 2, - ); - const [range] = selection.getRange(); - expect(range.index).toEqual(1); - expect(range.length).toEqual(3); - }); - - it('between inlines', function () { - const selection = this.initialize( - Selection, - '

          012345

          ', - ); - selection.setNativeRange( - this.container.firstChild, - 1, - this.container.firstChild, - 2, - ); - const [range] = selection.getRange(); - expect(range.index).toEqual(2); - expect(range.length).toEqual(2); - }); - - it('between blocks', function () { - const selection = this.initialize( - Selection, - ` -

          01

          -


          -
            -
          1. 45
          2. -
          3. 78
          4. -
          `, - ); - selection.setNativeRange(this.container, 1, this.container.lastChild, 1); - const [range] = selection.getRange(); - expect(range.index).toEqual(3); - expect(range.length).toEqual(4); - }); - - it('wrong input', function () { - const container = this.initialize( - HTMLElement, - ` - -
          `, - ); - const selection = this.initialize( - Selection, - '

          0123

          ', - container.lastChild, - ); - container.firstChild.select(); - const [range] = selection.getRange(); - expect(range).toEqual(null); - }); - }); - - describe('setRange()', function () { - it('empty document', function () { - const selection = this.initialize(Selection, ''); - const expected = new Range(0); - selection.setRange(expected); - const [range] = selection.getRange(); - expect(range).toEqual(expected); - expect(selection.hasFocus()).toBe(true); - }); - - it('empty lines', function () { - const selection = this.initialize( - Selection, - ` -


          -
            -

          1. -
          `, - ); - const expected = new Range(0, 1); - selection.setRange(expected); - const [range] = selection.getRange(); - expect(range).toEqual(range); - expect(selection.hasFocus()).toBe(true); - }); - - it('nested text node', function () { - const selection = this.initialize( - Selection, - ` -

          01

          -
            -
          1. 34
          2. -
          `, - ); - const expected = new Range(1, 3); - selection.setRange(expected); - const [range] = selection.getRange(); - expect(range).toEqual(expected); - expect(selection.hasFocus()).toBe(true); - }); - - it('between inlines', function () { - const selection = this.initialize( - Selection, - '

          012345

          ', - ); - const expected = new Range(2, 2); - selection.setRange(expected); - const [range] = selection.getRange(); - expect(range).toEqual(expected); - expect(selection.hasFocus()).toBe(true); - }); - - it('single embed', function () { - const selection = this.initialize( - Selection, - `

          `, - ); - const expected = new Range(1, 0); - selection.setRange(expected); - const [range] = selection.getRange(); - expect(range).toEqual(expected); - expect(selection.hasFocus()).toBe(true); - }); - - it('between embeds', function () { - const selection = this.initialize( - Selection, - ` -

          - - -

          -
            -
          1. - - -
          2. -
          `, - ); - const expected = new Range(1, 3); - selection.setRange(expected); - const [range] = selection.getRange(); - expect(range).toEqual(expected); - expect(selection.hasFocus()).toBe(true); - }); - - it('null', function () { - const selection = this.initialize(Selection, '

          0123

          '); - selection.setRange(new Range(1)); - let [range] = selection.getRange(); - expect(range).not.toEqual(null); - selection.setRange(null); - [range] = selection.getRange(); - expect(range).toEqual(null); - expect(selection.hasFocus()).toBe(false); - }); - - it('after format', function (done) { - const selection = this.initialize(Selection, '

          0123 567 9012

          '); - selection.setRange(new Range(5)); - selection.format('bold', true); - selection.format('bold', false); - selection.setRange(new Range(8)); - selection.emitter.once(Emitter.events.SCROLL_OPTIMIZE, () => { - const [range] = selection.getRange(); - expect(range.index).toEqual(8); - done(); - }); - }); - }); - - describe('format()', function () { - it('trailing', function () { - this.setup(`

          0123

          `, 4); - this.selection.format('bold', true); - expect(this.selection.getRange()[0].index).toEqual(4); - expect(this.container).toEqualHTML(` -

          0123${Cursor.CONTENTS}

          - `); - }); - - it('split nodes', function () { - this.setup(`

          0123

          `, 2); - this.selection.format('bold', true); - expect(this.selection.getRange()[0].index).toEqual(2); - expect(this.container).toEqualHTML(` -

          - 01 - ${Cursor.CONTENTS} - 23 -

          - `); - }); - - it('between characters', function () { - this.setup(`

          01

          `, 1); - this.selection.format('underline', true); - expect(this.selection.getRange()[0].index).toEqual(1); - expect(this.container).toEqualHTML(` -

          0${Cursor.CONTENTS}1

          - `); - }); - - it('empty line', function () { - this.setup(`


          `, 0); - this.selection.format('bold', true); - expect(this.selection.getRange()[0].index).toEqual(0); - expect(this.container).toEqualHTML(` -

          ${Cursor.CONTENTS}

          - `); - }); - - it('cursor interference', function () { - this.setup(`

          0123

          `, 2); - this.selection.format('underline', true); - this.selection.scroll.update(); - const native = this.selection.getNativeRange(); - expect(native.start.node).toEqual(this.selection.cursor.textNode); - }); - - it('multiple', function () { - this.setup(`

          0123

          `, 2); - this.selection.format('color', 'red'); - this.selection.format('italic', true); - this.selection.format('underline', true); - this.selection.format('background', 'blue'); - expect(this.selection.getRange()[0].index).toEqual(2); - expect(this.container).toEqualHTML(` -

          - 01 - - ${Cursor.CONTENTS} - - 23 -

          - `); - }); - - it('remove format', function () { - this.setup(`

          0123

          `, 2); - this.selection.format('italic', true); - this.selection.format('underline', true); - this.selection.format('italic', false); - expect(this.selection.getRange()[0].index).toEqual(2); - expect(this.container).toEqualHTML(` -

          - - 01${Cursor.CONTENTS}23 - -

          - `); - }); - - it('selection change cleanup', function () { - this.setup(`

          0123

          `, 2); - this.selection.format('italic', true); - this.selection.setRange(new Range(0, 0)); - this.selection.scroll.update(); - expect(this.container).toEqualHTML('

          0123

          '); - }); - - it('text change cleanup', function () { - this.setup(`

          0123

          `, 2); - this.selection.format('italic', true); - this.selection.cursor.textNode.data = `${Cursor.CONTENTS}|`; - this.selection.setNativeRange(this.selection.cursor.textNode, 2); - this.selection.scroll.update(); - expect(this.container).toEqualHTML('

          01|23

          '); - }); - - it('no cleanup', function () { - this.setup('

          0123


          ', 2); - this.selection.format('italic', true); - this.container.removeChild(this.container.lastChild); - this.selection.scroll.update(); - expect(this.selection.getRange()[0].index).toEqual(2); - expect(this.container).toEqualHTML(` -

          01${Cursor.CONTENTS}23

          - `); - }); - - describe('unlink cursor', function () { - const cursorHTML = `${Cursor.CONTENTS}`; - - it('one level', function () { - this.setup( - '

          link


          ', - 4, - ); - this.selection.format('bold', false); - expect(this.container).toEqualHTML(` -

          link${cursorHTML}


          - `); - }); - - it('nested formats', function () { - this.setup( - '

          bold


          ', - 4, - ); - this.selection.format('italic', false); - expect(this.container).toEqualHTML(` -

          bold${cursorHTML}


          - `); - }); - - it('ignore link format', function () { - this.setup('

          bold


          ', 4); - this.selection.format('link', 'https://example.com'); - expect(this.container).toEqualHTML(` -

          bold${cursorHTML}


          - `); - }); - }); - }); - - describe('getBounds()', function () { - beforeEach(function () { - this.container.classList.add('ql-editor'); - this.container.style.fontFamily = 'monospace'; - this.container.style.lineHeight = /Trident/i.test(navigator.userAgent) - ? '18px' - : 'initial'; - this.initialize(HTMLElement, '
           
          '); - this.div = this.container.firstChild; - this.div.style.border = '1px solid #777'; - // this.float is for visually a check, does not affect test itself - this.float = this.container.lastChild; - this.float.style.backgroundColor = 'red'; - this.float.style.position = 'absolute'; - this.float.style.width = '1px'; - if (this.reference != null) return; - this.initialize(HTMLElement, '

          0

          ', this.div); - const span = this.div.firstChild.firstChild; - const bounds = span.getBoundingClientRect(); - this.reference = { - height: bounds.height, - left: bounds.left, - lineHeight: span.parentNode.offsetHeight, - width: bounds.width, - top: bounds.top, - }; - this.initialize(HTMLElement, '', this.div); - }); - - afterEach(function () { - this.float.style.left = `${this.bounds.left}px`; - this.float.style.top = `${this.bounds.top}px`; - this.float.style.height = `${this.bounds.height}px`; - }); - - it('empty document', function () { - const selection = this.initialize(Selection, '


          ', this.div); - this.bounds = selection.getBounds(0); - if (/Android/i.test(navigator.userAgent)) return; // false positive on emulators atm - expect(this.bounds.left).toBeApproximately(this.reference.left, 1); - expect(this.bounds.height).toBeApproximately(this.reference.height, 1); - expect(this.bounds.top).toBeApproximately(this.reference.top, 1); - }); - - it('empty line', function () { - const selection = this.initialize( - Selection, - ` -

          0000

          -


          -

          0000

          `, - this.div, - ); - this.bounds = selection.getBounds(5); - if (/Android/i.test(navigator.userAgent)) return; // false positive on emulators atm - expect(this.bounds.left).toBeApproximately(this.reference.left, 1); - expect(this.bounds.height).toBeApproximately(this.reference.height, 1); - expect(this.bounds.top).toBeApproximately( - this.reference.top + this.reference.lineHeight, - 2, - ); - }); - - it('plain text', function () { - const selection = this.initialize(Selection, '

          0123

          ', this.div); - this.bounds = selection.getBounds(2); - expect(this.bounds.left).toBeApproximately( - this.reference.left + this.reference.width * 2, - 2, - ); - expect(this.bounds.height).toBeApproximately(this.reference.height, 1); - expect(this.bounds.top).toBeApproximately(this.reference.top, 1); - }); - - it('multiple characters', function () { - const selection = this.initialize(Selection, '

          0123

          ', this.div); - this.bounds = selection.getBounds(1, 2); - expect(this.bounds.left).toBeApproximately( - this.reference.left + this.reference.width, - 2, - ); - expect(this.bounds.height).toBeApproximately(this.reference.height, 1); - expect(this.bounds.top).toBeApproximately(this.reference.top, 1); - expect(this.bounds.width).toBeApproximately(this.reference.width * 2, 2); - }); - - it('start of line', function () { - const selection = this.initialize( - Selection, - ` -

          0000

          -

          0000

          `, - this.div, - ); - this.bounds = selection.getBounds(5); - expect(this.bounds.left).toBeApproximately(this.reference.left, 1); - expect(this.bounds.height).toBeApproximately(this.reference.height, 1); - expect(this.bounds.top).toBeApproximately( - this.reference.top + this.reference.lineHeight, - 1, - ); - }); - - it('end of line', function () { - const selection = this.initialize( - Selection, - ` -

          0000

          -

          0000

          -

          0000

          `, - this.div, - ); - this.bounds = selection.getBounds(9); - expect(this.bounds.left).toBeApproximately( - this.reference.left + this.reference.width * 4, - 4, - ); - expect(this.bounds.height).toBeApproximately(this.reference.height, 1); - expect(this.bounds.top).toBeApproximately( - this.reference.top + this.reference.lineHeight, - 1, - ); - }); - - it('multiple lines', function () { - const selection = this.initialize( - Selection, - ` -

          0000

          -

          0000

          -

          0000

          `, - this.div, - ); - this.bounds = selection.getBounds(2, 4); - expect(this.bounds.left).toBeApproximately(this.reference.left, 1); - expect(this.bounds.height).toBeApproximately( - this.reference.height * 2, - 2, - ); - expect(this.bounds.top).toBeApproximately(this.reference.top, 1); - expect(this.bounds.width).toBeGreaterThan(3 * this.reference.width); - }); - - it('large text', function () { - const selection = this.initialize( - Selection, - '

          0000

          ', - this.div, - ); - const span = this.div.querySelector('span'); - if (/Trident/i.test(navigator.userAgent)) { - span.style.lineHeight = '27px'; - } - this.bounds = selection.getBounds(2); - expect(this.bounds.left).toBeApproximately( - this.reference.left + span.offsetWidth / 2, - 1, - ); - expect(this.bounds.height).toBeApproximately(span.offsetHeight, 1); - expect(this.bounds.top).toBeApproximately(this.reference.top, 1); - }); - - it('image', function () { - const selection = this.initialize( - Selection, - ` -

          - - -

          `, - this.div, - ); - this.bounds = selection.getBounds(1); - expect(this.bounds.left).toBeApproximately(this.reference.left + 32, 1); - expect(this.bounds.height).toBeApproximately(32, 1); - expect(this.bounds.top).toBeApproximately(this.reference.top, 1); - }); - - it('beyond document', function () { - const selection = this.initialize(Selection, '

          0123

          '); - expect(() => { - this.bounds = selection.getBounds(10, 0); - }).not.toThrow(); - expect(() => { - this.bounds = selection.getBounds(0, 10); - }).not.toThrow(); - }); - }); -}); diff --git a/test/unit/core/selection.spec.ts b/test/unit/core/selection.spec.ts new file mode 100644 index 0000000000..0d8ead50be --- /dev/null +++ b/test/unit/core/selection.spec.ts @@ -0,0 +1,659 @@ +import Selection, { Range } from '../../../core/selection'; +import Cursor from '../../../blots/cursor'; +import Emitter from '../../../core/emitter'; +import { expect, describe, test } from 'vitest'; +import { createRegistry, createScroll } from '../__helpers__/factory'; +import Bold from '../../../formats/bold'; +import Underline from '../../../formats/underline'; +import Image from '../../../formats/image'; +import Link from '../../../formats/link'; +import Italic from '../../../formats/italic'; +import Strike from '../../../formats/strike'; +import { ColorStyle } from '../../../formats/color'; +import { BackgroundStyle } from '../../../formats/background'; +import { FontClass } from '../../../formats/font'; + +const createSelection = (html: string, container = document.body) => { + const scroll = createScroll( + html, + createRegistry([ + Bold, + Underline, + Italic, + Strike, + Image, + Link, + ColorStyle, + BackgroundStyle, + FontClass, + ]), + container, + ); + return new Selection(scroll, scroll.emitter); +}; + +describe('Selection', () => { + describe('focus()', () => { + const setupTest = () => { + const container = document.createElement('div'); + const textarea = container.appendChild( + document.createElement('textarea'), + ); + const selection = createSelection('

          0123

          ', container); + + document.body.appendChild(container); + textarea.focus(); + textarea.select(); + return { selection, textarea }; + }; + + test('initial focus', () => { + const { selection } = setupTest(); + expect(selection.hasFocus()).toBe(false); + selection.focus(); + expect(selection.hasFocus()).toBe(true); + }); + + test('restore last range', () => { + const { selection, textarea } = setupTest(); + const range = new Range(1, 2); + selection.setRange(range); + textarea.focus(); + textarea.select(); + expect(selection.hasFocus()).toBe(false); + selection.focus(); + expect(selection.hasFocus()).toBe(true); + expect(selection.getRange()[0]).toEqual(range); + }); + }); + + describe('getRange()', () => { + test('empty document', () => { + const selection = createSelection(''); + selection.setNativeRange(selection.root.querySelector('br'), 0); + const [range] = selection.getRange(); + expect(range?.index).toEqual(0); + expect(range?.length).toEqual(0); + }); + + test('empty line', () => { + const selection = createSelection('

          0


          3

          '); + selection.setNativeRange(selection.root.querySelector('br'), 0); + const [range] = selection.getRange(); + expect(range?.index).toEqual(2); + expect(range?.length).toEqual(0); + }); + + test('end of line', () => { + const selection = createSelection('

          0

          '); + selection.setNativeRange( + selection.root.firstChild?.firstChild as Node, + 1, + ); + const [range] = selection.getRange(); + expect(range?.index).toEqual(1); + expect(range?.length).toEqual(0); + }); + + test('text node', () => { + const selection = createSelection('

          0123

          '); + selection.setNativeRange( + selection.root.firstChild?.firstChild as Node, + 1, + ); + const [range] = selection.getRange(); + expect(range?.index).toEqual(1); + expect(range?.length).toEqual(0); + }); + + test('line boundaries', () => { + const selection = createSelection('


          12

          '); + selection.setNativeRange( + selection.root.firstChild, + 0, + selection.root.lastChild?.lastChild as Node, + 2, + ); + const [range] = selection.getRange(); + expect(range?.index).toEqual(0); + expect(range?.length).toEqual(3); + }); + + test('nested text node', () => { + const selection = createSelection( + `

          01

          +
            +
          1. 34
          2. +
          `, + ); + selection.setNativeRange( + selection.root.querySelector('em')?.firstChild as Node, + 1, + selection.root.querySelector('u')?.firstChild as Node, + 1, + ); + const [range] = selection.getRange(); + expect(range?.index).toEqual(1); + expect(range?.length).toEqual(3); + }); + + test('between embed across lines', () => { + const selection = createSelection( + ` +

          + + +

          +

          + + +

          `, + ); + selection.setNativeRange( + selection.root.firstChild, + 1, + selection.root.lastChild, + 1, + ); + const [range] = selection.getRange(); + expect(range?.index).toEqual(1); + expect(range?.length).toEqual(3); + }); + + test('between embed across list', () => { + const selection = createSelection( + ` +

          + + +

          +
            +
          1. + + +
          2. +
          `, + ); + selection.setNativeRange( + selection.root.firstChild, + 1, + selection.root.lastChild?.firstChild, + 2, + ); + const [range] = selection.getRange(); + expect(range?.index).toEqual(1); + expect(range?.length).toEqual(3); + }); + + test('between inlines', () => { + const selection = createSelection('

          012345

          '); + selection.setNativeRange( + selection.root.firstChild, + 1, + selection.root.firstChild, + 2, + ); + const [range] = selection.getRange(); + expect(range?.index).toEqual(2); + expect(range?.length).toEqual(2); + }); + + test('between blocks', () => { + const selection = createSelection( + ` +

          01

          +


          +
            +
          1. 45
          2. +
          3. 78
          4. +
          `, + ); + selection.setNativeRange(selection.root, 1, selection.root.lastChild, 1); + const [range] = selection.getRange(); + expect(range?.index).toEqual(3); + expect(range?.length).toEqual(4); + }); + + test('wrong input', () => { + const container = document.body.appendChild( + document.createElement('div'), + ); + const textarea = container.appendChild( + document.createElement('textarea'), + ); + const selection = createSelection('

          0123

          ', container); + textarea.select(); + const [range] = selection.getRange(); + expect(range).toEqual(null); + }); + }); + + describe('setRange()', () => { + test('empty document', () => { + const selection = createSelection(''); + const expected = new Range(0); + selection.setRange(expected); + const [range] = selection.getRange(); + expect(range).toEqual(expected); + expect(selection.hasFocus()).toBe(true); + }); + + test('empty lines', () => { + const selection = createSelection( + ` +


          +
            +

          1. +
          `, + ); + const expected = new Range(0, 1); + selection.setRange(expected); + const [range] = selection.getRange(); + expect(range).toEqual(range); + expect(selection.hasFocus()).toBe(true); + }); + + test('nested text node', () => { + const selection = createSelection( + ` +

          01

          +
            +
          1. 34
          2. +
          `, + ); + const expected = new Range(1, 3); + selection.setRange(expected); + const [range] = selection.getRange(); + expect(range).toEqual(expected); + expect(selection.hasFocus()).toBe(true); + }); + + test('between inlines', () => { + const selection = createSelection('

          012345

          '); + const expected = new Range(2, 2); + selection.setRange(expected); + const [range] = selection.getRange(); + expect(range).toEqual(expected); + expect(selection.hasFocus()).toBe(true); + }); + + test('single embed', () => { + const selection = createSelection( + `

          `, + ); + const expected = new Range(1, 0); + selection.setRange(expected); + const [range] = selection.getRange(); + expect(range).toEqual(expected); + expect(selection.hasFocus()).toBe(true); + }); + + test('between embeds', () => { + const selection = createSelection( + ` +

          + + +

          +
            +
          1. + + +
          2. +
          `, + ); + const expected = new Range(1, 3); + selection.setRange(expected); + const [range] = selection.getRange(); + expect(range).toEqual(expected); + expect(selection.hasFocus()).toBe(true); + }); + + test('null', () => { + const selection = createSelection('

          0123

          '); + selection.setRange(new Range(1)); + let [range] = selection.getRange(); + expect(range).not.toEqual(null); + selection.setRange(null); + [range] = selection.getRange(); + expect(range).toEqual(null); + expect(selection.hasFocus()).toBe(false); + }); + + test('after format', async () => { + const selection = createSelection('

          0123 567 9012

          '); + selection.setRange(new Range(5)); + selection.format('bold', true); + selection.format('bold', false); + selection.setRange(new Range(8)); + + await new Promise(resolve => { + selection.emitter.once(Emitter.events.SCROLL_OPTIMIZE, () => { + resolve(); + }); + }); + const [range] = selection.getRange(); + expect(range?.index).toEqual(8); + }); + }); + + describe('format()', () => { + test('trailing', () => { + const selection = createSelection(`

          0123

          `); + selection.setRange(new Range(4)); + selection.format('bold', true); + expect(selection.getRange()[0]?.index).toEqual(4); + expect(selection.scroll).toMatchInlineSnapshot(` +

          0123{Cursor.CONTENTS}

          + `); + }); + + test('split nodes', () => { + const selection = createSelection(`

          0123

          `); + selection.setRange(new Range(2)); + + selection.format('bold', true); + expect(selection.getRange()[0]?.index).toEqual(2); + expect(selection.scroll).toMatchInlineSnapshot(` +

          01{Cursor.CONTENTS}23

          + `); + }); + + test('between characters', () => { + const selection = createSelection(`

          01

          `); + selection.setRange(new Range(1)); + selection.format('underline', true); + expect(selection.getRange()[0]?.index).toEqual(1); + expect(selection.scroll).toMatchInlineSnapshot(` +

          0{Cursor.CONTENTS}1

          + `); + }); + + test('empty line', () => { + const selection = createSelection(`


          `); + selection.setRange(new Range(0)); + selection.format('bold', true); + expect(selection.getRange()[0]?.index).toEqual(0); + expect(selection.scroll).toMatchInlineSnapshot(` +

          {Cursor.CONTENTS}

          + `); + }); + + test('cursor interference', () => { + const selection = createSelection(`

          0123

          `); + selection.setRange(new Range(2)); + selection.format('underline', true); + selection.scroll.update(); + const native = selection.getNativeRange(); + expect(native?.start.node).toEqual(selection.cursor.textNode); + }); + + test('multiple', () => { + const selection = createSelection(`

          0123

          `); + selection.setRange(new Range(2)); + selection.format('color', 'red'); + selection.format('italic', true); + selection.format('underline', true); + selection.format('background', 'blue'); + expect(selection.getRange()[0]?.index).toEqual(2); + expect(selection.scroll).toMatchInlineSnapshot(` +

          01{Cursor.CONTENTS}23

          + `); + }); + + test('remove format', () => { + const selection = createSelection(`

          0123

          `); + selection.setRange(new Range(2)); + selection.format('italic', true); + selection.format('underline', true); + selection.format('italic', false); + expect(selection.getRange()[0]?.index).toEqual(2); + expect(selection.scroll).toMatchInlineSnapshot(` +

          01{Cursor.CONTENTS}23

          + `); + }); + + test('selection change cleanup', () => { + const selection = createSelection(`

          0123

          `); + selection.setRange(new Range(2)); + selection.format('italic', true); + selection.setRange(new Range(0, 0)); + selection.scroll.update(); + expect(selection.scroll).toMatchInlineSnapshot('

          0123

          '); + }); + + test('text change cleanup', () => { + const selection = createSelection(`

          0123

          `); + selection.setRange(new Range(2)); + selection.format('italic', true); + selection.cursor.textNode.data = `${Cursor.CONTENTS}|`; + selection.setNativeRange(selection.cursor.textNode, 2); + selection.scroll.update(); + expect(selection.scroll).toMatchInlineSnapshot('

          01|23

          '); + }); + + test('no cleanup', () => { + const selection = createSelection('

          0123


          '); + selection.setRange(new Range(2)); + selection.format('italic', true); + selection.root.removeChild(selection.root.lastChild as Node); + selection.scroll.update(); + expect(selection.getRange()[0]?.index).toEqual(2); + expect(selection.scroll).toMatchInlineSnapshot(` +

          01{Cursor.CONTENTS}23

          + `); + }); + + describe('unlink cursor', () => { + test('one level', () => { + const selection = createSelection( + '

          link


          ', + ); + selection.setRange(new Range(4)); + selection.format('bold', false); + expect(selection.scroll).toMatchInlineSnapshot(` +

          link{Cursor.CONTENTS}

          +


          + `); + }); + + test('nested formats', () => { + const selection = createSelection( + '

          bold


          ', + ); + selection.setRange(new Range(4)); + selection.format('italic', false); + expect(selection.scroll).toMatchInlineSnapshot(` +

          bold{Cursor.CONTENTS}

          +


          + `); + }); + + test('ignore link format', () => { + const selection = createSelection( + '

          bold


          ', + ); + selection.setRange(new Range(4)); + selection.format('link', 'https://example.com'); + expect(selection.scroll).toMatchInlineSnapshot(` +

          bold{Cursor.CONTENTS}

          +


          + `); + }); + }); + }); + + describe('getBounds()', () => { + const setup = () => { + const container = document.body.appendChild( + document.createElement('div'), + ); + container.classList.add('ql-editor'); + const style = document.body.appendChild(document.createElement('style')); + style.innerText = + '.ql-editor p, .ql-editor img { margin: 0; padding: 0; border: 0; }'; + container.style.fontFamily = 'monospace'; + container.style.lineHeight = '18px'; + const div = container.appendChild(document.createElement('div')); + div.style.border = '1px solid #777'; + div.innerHTML = '

          0

          '; + const span = div.firstChild?.firstChild as HTMLSpanElement; + const bounds = span.getBoundingClientRect(); + const reference = { + height: bounds.height, + left: bounds.left, + lineHeight: span.parentElement?.offsetHeight as number, + width: bounds.width, + top: bounds.top, + }; + div.remove(); + + return { reference, container }; + }; + + test('empty document', () => { + const { reference, container } = setup(); + const selection = createSelection('


          ', container); + const bounds = selection.getBounds(0); + expect(bounds?.left).approximately(reference.left, 3); + expect(bounds?.height).approximately(reference.height, 3); + expect(bounds?.top).approximately(reference.top, 3); + }); + + test('empty line', () => { + const { reference, container } = setup(); + const selection = createSelection( + ` +

          0000

          +


          +

          0000

          `, + container, + ); + const bounds = selection.getBounds(5); + expect(bounds?.left).approximately(reference.left, 3); + expect(bounds?.height).approximately(reference.height, 3); + expect(bounds?.top).approximately( + reference.top + reference.lineHeight, + 3, + ); + }); + + test('plain text', () => { + const { reference, container } = setup(); + const selection = createSelection('

          0123

          ', container); + const bounds = selection.getBounds(2); + expect(bounds?.left).approximately( + reference.left + reference.width * 2, + 2, + ); + expect(bounds?.height).approximately(reference.height, 1); + expect(bounds?.top).approximately(reference.top, 1); + }); + + test('multiple characters', () => { + const { reference, container } = setup(); + const selection = createSelection('

          0123

          ', container); + const bounds = selection.getBounds(1, 2); + expect(bounds?.left).approximately(reference.left + reference.width, 2); + expect(bounds?.height).approximately(reference.height, 1); + expect(bounds?.top).approximately(reference.top, 1); + expect(bounds?.width).approximately(reference.width * 2, 2); + }); + + test('start of line', () => { + const { reference, container } = setup(); + const selection = createSelection( + ` +

          0000

          +

          0000

          `, + container, + ); + const bounds = selection.getBounds(5); + expect(bounds?.left).approximately(reference.left, 1); + expect(bounds?.height).approximately(reference.height, 1); + expect(bounds?.top).approximately( + reference.top + reference.lineHeight, + 1, + ); + }); + + test('end of line', () => { + const { reference, container } = setup(); + const selection = createSelection( + ` +

          0000

          +

          0000

          +

          0000

          `, + container, + ); + const bounds = selection.getBounds(9); + expect(bounds?.left).approximately( + reference.left + reference.width * 4, + 4, + ); + expect(bounds?.height).approximately(reference.height, 1); + expect(bounds?.top).approximately( + reference.top + reference.lineHeight, + 1, + ); + }); + + test('multiple lines', () => { + const { reference, container } = setup(); + const selection = createSelection( + ` +

          0000

          +

          0000

          +

          0000

          `, + container, + ); + const bounds = selection.getBounds(2, 4); + expect(bounds?.left).approximately(reference.left, 1); + expect(bounds?.height).approximately(reference.height * 2, 3); + expect(bounds?.top).approximately(reference.top, 1); + expect(bounds?.width).toBeGreaterThan(3 * reference.width); + }); + + test('large text', () => { + const { reference, container } = setup(); + const selection = createSelection( + '

          0000

          ', + container, + ); + const span = container.querySelector('span') as HTMLSpanElement; + const bounds = selection.getBounds(2); + expect(bounds?.left).approximately( + reference.left + span.offsetWidth / 2, + 3, + ); + expect(bounds?.height).approximately(span.offsetHeight, 3); + expect(bounds?.top).approximately(reference.top, 3); + }); + + test('image', () => { + const { reference, container } = setup(); + const selection = createSelection( + ` +

          + + +

          `, + container, + ); + const bounds = selection.getBounds(1); + expect(bounds?.left).approximately(reference.left + 32, 1); + expect(bounds?.height).approximately(32, 1); + expect(bounds?.top).approximately(reference.top, 3); + }); + + test('beyond document', () => { + const selection = createSelection('

          0123

          '); + expect(() => { + selection.getBounds(10, 0); + }).not.toThrow(); + expect(() => { + selection.getBounds(0, 10); + }).not.toThrow(); + }); + }); +}); From 27a8c03d11813d57f61b3d2ebd56336844def605 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:28:38 +0800 Subject: [PATCH 10/18] Migrate blots to Vitest --- .../{block-embed.js => block-embed.spec.ts} | 75 ++++++------ test/unit/blots/block.js | 90 -------------- test/unit/blots/block.spec.ts | 103 ++++++++++++++++ test/unit/blots/{inline.js => inline.spec.ts} | 23 ++-- test/unit/blots/scroll.js | 102 ---------------- test/unit/blots/scroll.spec.ts | 113 ++++++++++++++++++ 6 files changed, 269 insertions(+), 237 deletions(-) rename test/unit/blots/{block-embed.js => block-embed.spec.ts} (74%) delete mode 100644 test/unit/blots/block.js create mode 100644 test/unit/blots/block.spec.ts rename test/unit/blots/{inline.js => inline.spec.ts} (56%) delete mode 100644 test/unit/blots/scroll.js create mode 100644 test/unit/blots/scroll.spec.ts diff --git a/test/unit/blots/block-embed.js b/test/unit/blots/block-embed.spec.ts similarity index 74% rename from test/unit/blots/block-embed.js rename to test/unit/blots/block-embed.spec.ts index 5ebeaddfe4..67a3349b04 100644 --- a/test/unit/blots/block-embed.js +++ b/test/unit/blots/block-embed.spec.ts @@ -1,8 +1,17 @@ -import Scroll from '../../../blots/scroll'; +import { describe, expect, test } from 'vitest'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import Video from '../../../formats/video'; +import Image from '../../../formats/image'; -describe('Block Embed', function () { - it('insert', function () { - const scroll = this.initialize(Scroll, '

          0123

          '); +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([Video, Image])); + +describe('Block Embed', () => { + test('insert', () => { + const scroll = createScroll('

          0123

          '); scroll.insertAt(2, 'video', '#'); expect(scroll.domNode).toEqualHTML(`

          01

          @@ -11,8 +20,8 @@ describe('Block Embed', function () { `); }); - it('split newline', function () { - const scroll = this.initialize(Scroll, '

          0123

          '); + test('split newline', () => { + const scroll = createScroll('

          0123

          '); scroll.insertAt(4, 'video', '#'); expect(scroll.domNode).toEqualHTML(`

          0123

          @@ -21,8 +30,8 @@ describe('Block Embed', function () { `); }); - it('insert end of document', function () { - const scroll = this.initialize(Scroll, '

          0123

          '); + test('insert end of document', () => { + const scroll = createScroll('

          0123

          '); scroll.insertAt(5, 'video', '#'); expect(scroll.domNode).toEqualHTML(`

          0123

          @@ -30,9 +39,8 @@ describe('Block Embed', function () { `); }); - it('insert text before', function () { - const scroll = this.initialize( - Scroll, + test('insert text before', () => { + const scroll = createScroll( '', ); scroll.insertAt(0, 'Test'); @@ -42,9 +50,8 @@ describe('Block Embed', function () { `); }); - it('insert text after', function () { - const scroll = this.initialize( - Scroll, + test('insert text after', () => { + const scroll = createScroll( '', ); scroll.insertAt(1, 'Test'); @@ -54,9 +61,8 @@ describe('Block Embed', function () { `); }); - it('insert inline embed before', function () { - const scroll = this.initialize( - Scroll, + test('insert inline embed before', () => { + const scroll = createScroll( '', ); scroll.insertAt(0, 'image', '/assets/favicon.png'); @@ -66,9 +72,8 @@ describe('Block Embed', function () { `); }); - it('insert inline embed after', function () { - const scroll = this.initialize( - Scroll, + test('insert inline embed after', () => { + const scroll = createScroll( '', ); scroll.insertAt(1, 'image', '/assets/favicon.png'); @@ -78,9 +83,8 @@ describe('Block Embed', function () { `); }); - it('insert block embed before', function () { - const scroll = this.initialize( - Scroll, + test('insert block embed before', () => { + const scroll = createScroll( '', ); scroll.insertAt(0, 'video', '#1'); @@ -90,9 +94,8 @@ describe('Block Embed', function () { `); }); - it('insert block embed after', function () { - const scroll = this.initialize( - Scroll, + test('insert block embed after', () => { + const scroll = createScroll( '', ); scroll.insertAt(1, 'video', '#1'); @@ -102,9 +105,8 @@ describe('Block Embed', function () { `); }); - it('insert newline before', function () { - const scroll = this.initialize( - Scroll, + test('insert newline before', () => { + const scroll = createScroll( '', ); scroll.insertAt(0, '\n'); @@ -115,9 +117,8 @@ describe('Block Embed', function () { `); }); - it('insert multiple newlines before', function () { - const scroll = this.initialize( - Scroll, + test('insert multiple newlines before', () => { + const scroll = createScroll( '', ); scroll.insertAt(0, '\n\n\n'); @@ -130,9 +131,8 @@ describe('Block Embed', function () { `); }); - it('insert newline after', function () { - const scroll = this.initialize( - Scroll, + test('insert newline after', () => { + const scroll = createScroll( '', ); scroll.insertAt(1, '\n'); @@ -143,9 +143,8 @@ describe('Block Embed', function () { `); }); - it('delete preceding newline', function () { - const scroll = this.initialize( - Scroll, + test('delete preceding newline', () => { + const scroll = createScroll( '

          0123

          ', ); scroll.deleteAt(4, 1); diff --git a/test/unit/blots/block.js b/test/unit/blots/block.js deleted file mode 100644 index 240c1a23b0..0000000000 --- a/test/unit/blots/block.js +++ /dev/null @@ -1,90 +0,0 @@ -import Scroll from '../../../blots/scroll'; - -describe('Block', function () { - it('childless', function () { - const scroll = this.initialize(Scroll, ''); - const block = scroll.create('block'); - block.optimize(); - expect(block.domNode).toEqualHTML('
          '); - }); - - it('insert into empty', function () { - const scroll = this.initialize(Scroll, ''); - const block = scroll.create('block'); - block.insertAt(0, 'Test'); - expect(block.domNode).toEqualHTML('Test'); - }); - - it('insert newlines', function () { - const scroll = this.initialize(Scroll, '


          '); - scroll.insertAt(0, '\n\n\n'); - expect(scroll.domNode).toEqualHTML( - '





          ', - ); - }); - - it('insert multiline', function () { - const scroll = this.initialize(Scroll, '

          Hello World!

          '); - scroll.insertAt(6, 'pardon\nthis\n\ninterruption\n'); - expect(scroll.domNode).toEqualHTML(` -

          Hello pardon

          -

          this

          -


          -

          interruption

          -

          World!

          - `); - }); - - it('insert into formatted', function () { - const scroll = this.initialize(Scroll, '

          Welcome

          '); - scroll.insertAt(3, 'l\n'); - expect(scroll.domNode.firstChild.outerHTML).toEqualHTML('

          Well

          '); - expect(scroll.domNode.childNodes[1].outerHTML).toEqualHTML('

          come

          '); - }); - - it('delete line contents', function () { - const scroll = this.initialize(Scroll, '

          Hello

          World!

          '); - scroll.deleteAt(0, 5); - expect(scroll.domNode).toEqualHTML('


          World!

          '); - }); - - it('join lines', function () { - const scroll = this.initialize(Scroll, '

          Hello

          World!

          '); - scroll.deleteAt(5, 1); - expect(scroll.domNode).toEqualHTML('

          HelloWorld!

          '); - }); - - it('join line with empty', function () { - const scroll = this.initialize( - Scroll, - '

          HelloWorld


          ', - ); - scroll.deleteAt(10, 1); - expect(scroll.domNode).toEqualHTML('

          HelloWorld

          '); - }); - - it('join empty lines', function () { - const scroll = this.initialize(Scroll, '



          '); - scroll.deleteAt(1, 1); - expect(scroll.domNode).toEqualHTML('


          '); - }); - - it('format empty', function () { - const scroll = this.initialize(Scroll, '


          '); - scroll.formatAt(0, 1, 'header', 1); - expect(scroll.domNode).toEqualHTML('


          '); - }); - - it('format newline', function () { - const scroll = this.initialize(Scroll, '

          Hello

          '); - scroll.formatAt(5, 1, 'header', 2); - expect(scroll.domNode).toEqualHTML('

          Hello

          '); - }); - - it('remove unnecessary break', function () { - const scroll = this.initialize(Scroll, '

          Test

          '); - scroll.children.head.domNode.appendChild(document.createElement('br')); - scroll.update(); - expect(scroll.domNode).toEqualHTML('

          Test

          '); - }); -}); diff --git a/test/unit/blots/block.spec.ts b/test/unit/blots/block.spec.ts new file mode 100644 index 0000000000..0150dc521b --- /dev/null +++ b/test/unit/blots/block.spec.ts @@ -0,0 +1,103 @@ +import { describe, expect, test } from 'vitest'; +import { + createScroll as baseCreateScroll, + createRegistry, +} from '../__helpers__/factory'; +import Header from '../../../formats/header'; +import Bold from '../../../formats/bold'; + +const createScroll = (html: string) => + baseCreateScroll(html, createRegistry([Header, Bold])); + +describe('Block', () => { + test('childless', () => { + const scroll = createScroll(''); + const block = scroll.create('block'); + // @ts-expect-error + block.optimize(); + expect(block.domNode).toEqualHTML('
          '); + }); + + test('insert into empty', () => { + const scroll = createScroll(''); + const block = scroll.create('block'); + block.insertAt(0, 'Test'); + expect(block.domNode).toEqualHTML('Test'); + }); + + test('insert newlines', () => { + const scroll = createScroll('


          '); + scroll.insertAt(0, '\n\n\n'); + expect(scroll.domNode).toEqualHTML( + '





          ', + ); + }); + + test('insert multiline', () => { + const scroll = createScroll('

          Hello World!

          '); + scroll.insertAt(6, 'pardon\nthis\n\ninterruption\n'); + expect(scroll.domNode).toEqualHTML(` +

          Hello pardon

          +

          this

          +


          +

          interruption

          +

          World!

          + `); + }); + + test('insert into formatted', () => { + const scroll = createScroll('

          Welcome

          '); + scroll.insertAt(3, 'l\n'); + // @ts-expect-error + expect(scroll.domNode.firstChild?.outerHTML).toEqualHTML('

          Well

          '); + // @ts-expect-error + expect(scroll.domNode.childNodes[1]?.outerHTML).toEqualHTML( + '

          come

          ', + ); + }); + + test('delete line contents', () => { + const scroll = createScroll('

          Hello

          World!

          '); + scroll.deleteAt(0, 5); + expect(scroll.domNode).toEqualHTML('


          World!

          '); + }); + + test('join lines', () => { + const scroll = createScroll('

          Hello

          World!

          '); + scroll.deleteAt(5, 1); + expect(scroll.domNode).toEqualHTML('

          HelloWorld!

          '); + }); + + test('join line with empty', () => { + const scroll = createScroll( + '

          HelloWorld


          ', + ); + scroll.deleteAt(10, 1); + expect(scroll.domNode).toEqualHTML('

          HelloWorld

          '); + }); + + test('join empty lines', () => { + const scroll = createScroll('



          '); + scroll.deleteAt(1, 1); + expect(scroll.domNode).toEqualHTML('


          '); + }); + + test('format empty', () => { + const scroll = createScroll('


          '); + scroll.formatAt(0, 1, 'header', 1); + expect(scroll.domNode).toEqualHTML('


          '); + }); + + test('format newline', () => { + const scroll = createScroll('

          Hello

          '); + scroll.formatAt(5, 1, 'header', 2); + expect(scroll.domNode).toEqualHTML('

          Hello

          '); + }); + + test('remove unnecessary break', () => { + const scroll = createScroll('

          Test

          '); + scroll.children.head?.domNode.appendChild(document.createElement('br')); + scroll.update(); + expect(scroll.domNode).toEqualHTML('

          Test

          '); + }); +}); diff --git a/test/unit/blots/inline.js b/test/unit/blots/inline.spec.ts similarity index 56% rename from test/unit/blots/inline.js rename to test/unit/blots/inline.spec.ts index 1ea2e0ca11..c70b74fb2a 100644 --- a/test/unit/blots/inline.js +++ b/test/unit/blots/inline.spec.ts @@ -1,8 +1,14 @@ -import Scroll from '../../../blots/scroll'; +import { describe, expect, test } from 'vitest'; +import { createRegistry, createScroll } from '../__helpers__/factory'; +import Bold from '../../../formats/bold'; +import Italic from '../../../formats/italic'; -describe('Inline', function () { - it('format order', function () { - const scroll = this.initialize(Scroll, '

          Hello World!

          '); +describe('Inline', () => { + test('format order', () => { + const scroll = createScroll( + '

          Hello World!

          ', + createRegistry([Bold, Italic]), + ); scroll.formatAt(0, 1, 'bold', true); scroll.formatAt(0, 1, 'italic', true); scroll.formatAt(2, 1, 'italic', true); @@ -12,9 +18,12 @@ describe('Inline', function () { ); }); - it('reorder', function () { - const scroll = this.initialize(Scroll, '

          0123

          '); - const p = scroll.domNode.firstChild; + test('reorder', () => { + const scroll = createScroll( + '

          0123

          ', + createRegistry([Bold, Italic]), + ); + const p = scroll.domNode.firstChild as HTMLParagraphElement; const em = document.createElement('em'); Array.from(p.childNodes).forEach(function (node) { em.appendChild(node); diff --git a/test/unit/blots/scroll.js b/test/unit/blots/scroll.js deleted file mode 100644 index e09f60d9eb..0000000000 --- a/test/unit/blots/scroll.js +++ /dev/null @@ -1,102 +0,0 @@ -import Emitter from '../../../core/emitter'; -import Selection, { Range } from '../../../core/selection'; -import Cursor from '../../../blots/cursor'; -import Scroll from '../../../blots/scroll'; -import Delta from 'quill-delta'; - -describe('Scroll', function () { - it('initialize empty document', function () { - const scroll = this.initialize(Scroll, ''); - expect(scroll.domNode).toEqualHTML('


          '); - }); - - it('api change', function () { - const scroll = this.initialize(Scroll, '

          Hello World!

          '); - spyOn(scroll.emitter, 'emit').and.callThrough(); - scroll.insertAt(5, '!'); - expect(scroll.emitter.emit).toHaveBeenCalledWith( - Emitter.events.SCROLL_OPTIMIZE, - jasmine.any(Array), - jasmine.any(Object), - ); - }); - - it('user change', function (done) { - const scroll = this.initialize(Scroll, '

          Hello World!

          '); - spyOn(scroll.emitter, 'emit').and.callThrough(); - scroll.domNode.firstChild.appendChild(document.createTextNode('!')); - setTimeout(function () { - expect(scroll.emitter.emit).toHaveBeenCalledWith( - Emitter.events.SCROLL_OPTIMIZE, - jasmine.any(Array), - jasmine.any(Object), - ); - expect(scroll.emitter.emit).toHaveBeenCalledWith( - Emitter.events.SCROLL_UPDATE, - Emitter.sources.USER, - jasmine.any(Array), - ); - done(); - }, 1); - }); - - it('prevent dragstart', function () { - const scroll = this.initialize(Scroll, '

          Hello World!

          '); - const dragstart = new Event('dragstart'); - spyOn(dragstart, 'preventDefault'); - scroll.domNode.dispatchEvent(dragstart); - expect(dragstart.preventDefault).toHaveBeenCalled(); - }); - - describe('leaf()', function () { - it('text', function () { - const scroll = this.initialize(Scroll, '

          Tests

          '); - const [leaf, offset] = scroll.leaf(2); - expect(leaf.value()).toEqual('Tests'); - expect(offset).toEqual(2); - }); - - it('precise', function () { - const scroll = this.initialize( - Scroll, - '

          01234

          ', - ); - const [leaf, offset] = scroll.leaf(3); - expect(leaf.value()).toEqual('2'); - expect(offset).toEqual(1); - }); - - it('newline', function () { - const scroll = this.initialize(Scroll, '

          0123

          5678

          '); - const [leaf, offset] = scroll.leaf(4); - expect(leaf.value()).toEqual('0123'); - expect(offset).toEqual(4); - }); - - it('cursor', function () { - const selection = this.initialize(Selection, '

          012

          '); - selection.setRange(new Range(2)); - selection.format('strike', true); - const [leaf, offset] = selection.scroll.leaf(2); - expect(leaf instanceof Cursor).toBe(true); - expect(offset).toEqual(0); - }); - - it('beyond document', function () { - const scroll = this.initialize(Scroll, '

          Test

          '); - const [leaf, offset] = scroll.leaf(10); - expect(leaf).toEqual(null); - expect(offset).toEqual(-1); - }); - }); - - describe('insertContents()', function () { - it('does not mutate the input', function () { - const scroll = this.initialize(Scroll, '

          Test

          '); - const delta = new Delta().insert('\n'); - const clonedDelta = new Delta(structuredClone(delta.ops)); - scroll.insertContents(0, delta); - expect(delta.ops).toEqual(clonedDelta.ops); - }); - }); -}); diff --git a/test/unit/blots/scroll.spec.ts b/test/unit/blots/scroll.spec.ts new file mode 100644 index 0000000000..3f3c7b819f --- /dev/null +++ b/test/unit/blots/scroll.spec.ts @@ -0,0 +1,113 @@ +import { describe, expect, test, vitest } from 'vitest'; +import Emitter from '../../../core/emitter'; +import Selection, { Range } from '../../../core/selection'; +import Cursor from '../../../blots/cursor'; +import Scroll from '../../../blots/scroll'; +import Delta from 'quill-delta'; +import { createRegistry } from '../__helpers__/factory'; +import { normalizeHTML, sleep } from '../__helpers__/utils'; +import Underline from '../../../formats/underline'; +import Strike from '../../../formats/strike'; + +const createScroll = (html: string) => { + const emitter = new Emitter(); + const registry = createRegistry([Underline, Strike]); + const container = document.body.appendChild(document.createElement('div')); + container.innerHTML = normalizeHTML(html); + return new Scroll(registry, container, { emitter }); +}; + +describe('Scroll', () => { + test('initialize empty document', () => { + const scroll = createScroll(''); + expect(scroll.domNode).toEqualHTML('


          '); + }); + + test('api change', () => { + const scroll = createScroll('

          Hello World!

          '); + vitest.spyOn(scroll.emitter, 'emit'); + scroll.insertAt(5, '!'); + expect(scroll.emitter.emit).toHaveBeenCalledWith( + Emitter.events.SCROLL_OPTIMIZE, + expect.any(Array), + expect.any(Object), + ); + }); + + test('user change', async () => { + const scroll = createScroll('

          Hello World!

          '); + vitest.spyOn(scroll.emitter, 'emit'); + scroll.domNode.firstChild?.appendChild(document.createTextNode('!')); + await sleep(1); + expect(scroll.emitter.emit).toHaveBeenCalledWith( + Emitter.events.SCROLL_OPTIMIZE, + expect.any(Array), + expect.any(Object), + ); + expect(scroll.emitter.emit).toHaveBeenCalledWith( + Emitter.events.SCROLL_UPDATE, + Emitter.sources.USER, + expect.any(Array), + ); + }); + + test('prevent dragstart', () => { + const scroll = createScroll('

          Hello World!

          '); + const dragstart = new Event('dragstart'); + vitest.spyOn(dragstart, 'preventDefault'); + scroll.domNode.dispatchEvent(dragstart); + expect(dragstart.preventDefault).toHaveBeenCalled(); + }); + + describe('leaf()', () => { + test('text', () => { + const scroll = createScroll('

          Tests

          '); + const [leaf, offset] = scroll.leaf(2); + expect(leaf?.value()).toEqual('Tests'); + expect(offset).toEqual(2); + }); + + test('precise', () => { + const scroll = createScroll( + '

          01234

          ', + ); + const [leaf, offset] = scroll.leaf(3); + expect(leaf?.value()).toEqual('2'); + expect(offset).toEqual(1); + }); + + test('newline', () => { + const scroll = createScroll('

          0123

          5678

          '); + const [leaf, offset] = scroll.leaf(4); + expect(leaf?.value()).toEqual('0123'); + expect(offset).toEqual(4); + }); + + test('cursor', () => { + const scroll = createScroll('

          012

          '); + const selection = new Selection(scroll, scroll.emitter); + selection.setRange(new Range(2)); + selection.format('strike', true); + const [leaf, offset] = selection.scroll.leaf(2); + expect(leaf instanceof Cursor).toBe(true); + expect(offset).toEqual(0); + }); + + test('beyond document', () => { + const scroll = createScroll('

          Test

          '); + const [leaf, offset] = scroll.leaf(10); + expect(leaf).toEqual(null); + expect(offset).toEqual(-1); + }); + }); + + describe('insertContents()', () => { + test('does not mutate the input', () => { + const scroll = createScroll('

          Test

          '); + const delta = new Delta().insert('\n'); + const clonedDelta = new Delta(structuredClone(delta.ops)); + scroll.insertContents(0, delta); + expect(delta.ops).toEqual(clonedDelta.ops); + }); + }); +}); From 16ded8f4456a623c488e82b4f29edd20bc8805e3 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:29:00 +0800 Subject: [PATCH 11/18] Remove unit.js from webpack --- _develop/webpack.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/_develop/webpack.config.js b/_develop/webpack.config.js index f8b02c75dd..23784b1f77 100644 --- a/_develop/webpack.config.js +++ b/_develop/webpack.config.js @@ -64,7 +64,6 @@ const baseConfig = { 'quill.core': './assets/core.styl', 'quill.bubble': './assets/bubble.styl', 'quill.snow': './assets/snow.styl', - 'unit.js': './test/unit.js', }, output: { filename: '[name]', From a6811fd7d766bf43ea24d56a87e3c3fe2acd8a2e Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:29:39 +0800 Subject: [PATCH 12/18] Remove Karma from project --- _develop/browsers.js | 49 - _develop/karma.fuzz.config.js | 19 - _develop/karma.unit.config.js | 67 - _develop/proxy.js | 11 +- _develop/sauce.js | 15 - package-lock.json | 5886 +++++++++++++++------------------ package.json | 25 +- 7 files changed, 2746 insertions(+), 3326 deletions(-) delete mode 100644 _develop/browsers.js delete mode 100644 _develop/karma.fuzz.config.js delete mode 100644 _develop/karma.unit.config.js delete mode 100644 _develop/sauce.js diff --git a/_develop/browsers.js b/_develop/browsers.js deleted file mode 100644 index cb23d86302..0000000000 --- a/_develop/browsers.js +++ /dev/null @@ -1,49 +0,0 @@ -const desktop = { - 'mac-chrome-latest': ['macOS 12', 'chrome', 'latest'], - 'mac-firefox-latest': ['macOS 12', 'firefox', 'latest'], - 'mac-safari-latest': ['macOS 12', 'safari', '16'], - 'mac-chrome-previous': ['macOS 11', 'chrome', 'latest-1'], - 'mac-firefox-previous': ['macOS 11', 'firefox', 'latest-1'], - 'mac-safari-previous': ['macOS 11', 'safari', '14'], - - 'windows-chrome-latest': ['Windows 11', 'chrome', 'latest'], - 'windows-firefox-latest': ['Windows 11', 'firefox', 'latest'], - 'windows-edge-latest': ['Windows 11', 'microsoftedge', 'latest'], - 'windows-chrome-previous': ['Windows 10', 'chrome', 'latest-1'], - 'windows-firefox-previous': ['Windows 10', 'firefox', 'latest-1'], - 'windows-edge-previous': ['Windows 10', 'microsoftedge', 'latest-1'], -}; - -const mobile = { - 'ios-latest': ['iPhone 11 Simulator', 'iOS', '15.5', 'Safari'], - 'ios-previous': ['iPhone X Simulator', 'iOS', '14.5', 'Safari'], - - 'android-latest': ['Android GoogleAPI Emulator', 'Android', '13.0', 'Chrome'], - 'android-previous': [ - 'Android GoogleAPI Emulator', - 'Android', - '12.0', - 'Chrome', - ], -}; - -Object.keys(desktop).forEach(key => { - module.exports[key] = { - base: 'SauceLabs', - browserName: desktop[key][1], - version: desktop[key][2], - platform: desktop[key][0], - }; -}); - -Object.keys(mobile).forEach(key => { - module.exports[key] = { - base: 'SauceLabs', - browserName: mobile[key][3], - appiumVersion: '1.22.3', - deviceName: mobile[key][0], - deviceOrientation: 'portrait', - platformVersion: mobile[key][2], - platformName: mobile[key][1], - }; -}); diff --git a/_develop/karma.fuzz.config.js b/_develop/karma.fuzz.config.js deleted file mode 100644 index 04f705dfc4..0000000000 --- a/_develop/karma.fuzz.config.js +++ /dev/null @@ -1,19 +0,0 @@ -const dns = require('node:dns'); -dns.setDefaultResultOrder('ipv4first'); - -module.exports = config => { - config.set({ - basePath: '../', - urlRoot: '/karma/', - files: [{ pattern: 'dist/fuzz.js', nocache: true }], - frameworks: ['jasmine'], - reporters: ['progress'], - browsers: ['jsdom'], - singleRun: true, - browserNoActivityTimeout: 120000, - browserDisconnectTimeout: 120000, - browserDisconnectTolerance: 3, - browserSocketTimeout: 120000, - captureTimeout: 120000, - }); -}; diff --git a/_develop/karma.unit.config.js b/_develop/karma.unit.config.js deleted file mode 100644 index 5dd0525ea8..0000000000 --- a/_develop/karma.unit.config.js +++ /dev/null @@ -1,67 +0,0 @@ -const browsers = require('./browsers'); -const sauce = require('./sauce'); - -module.exports = config => { - config.set({ - basePath: '../', - urlRoot: '/karma/', - port: process.env.npm_package_config_ports_karma, - - files: [ - { - pattern: - 'http://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js', - served: true, - }, - { pattern: 'dist/quill.snow.css', nocache: true }, - { pattern: 'dist/unit.js', nocache: true }, - { pattern: 'dist/*.map', included: false, served: true, nocache: true }, - { pattern: 'assets/favicon.png', included: false, served: true }, - ], - proxies: { - '/assets/': '/karma/base/assets/', - }, - - frameworks: ['jasmine'], - reporters: ['progress'], - colors: true, - autoWatch: false, - singleRun: true, - browsers: ['Chrome'], - - client: { - useIframe: true, - }, - - coverageReporter: { - dir: '.coverage', - reporters: [{ type: 'text' }, { type: 'html' }], - }, - sauceLabs: { - testName: 'quill-unit', - options: { - public: 'public', - 'record-screenshots': false, - }, - build: sauce.build, - // There is no way to securely allow community PRs to be built and tested - // by Travis and SauceLabs. Please do not abuse. - username: 'quill', - accessKey: 'ced60aed-80ad-436b-9ba8-690ed1205180', - tunnelIdentifier: sauce.tunnel, - }, - customLaunchers: browsers, - }); - - /* eslint-disable no-param-reassign */ - if (process.env.GITHUB_ACTION) { - config.reporters = ['dots', 'saucelabs']; - config.transports = ['polling']; - config.browsers = [process.env.BROWSER]; - config.browserDisconnectTimeout = 10000; - config.browserDisconnectTolerance = 3; - config.browserNoActivityTimeout = 60000; - config.browserSocketTimeout = 40000; - config.captureTimeout = 120000; - } -}; diff --git a/_develop/proxy.js b/_develop/proxy.js index 50df14fd8c..2635cd392a 100644 --- a/_develop/proxy.js +++ b/_develop/proxy.js @@ -5,15 +5,11 @@ const proxy = httpProxy.createProxyServer({}); const ports = { proxy: parseInt(process.env.npm_package_config_ports_proxy, 10), jekyll: parseInt(process.env.npm_package_config_ports_gatsby, 10), - karma: parseInt(process.env.npm_package_config_ports_karma, 10), webpack: parseInt(process.env.npm_package_config_ports_webpack, 10), }; const server = http.createServer((req, res) => { - if ( - /\/\d+\.\d+\.\d+/.test(req.url) || - req.url.startsWith('/karma/base/dist') - ) { + if (/\/\d+\.\d+\.\d+/.test(req.url)) { const target = `http://localhost:${ports.webpack}/${req.url .split('/') .pop()}`; @@ -21,11 +17,6 @@ const server = http.createServer((req, res) => { ignorePath: true, target, }); - } else if ( - req.url.startsWith('/karma') || - req.url === '/assets/favicon.png' - ) { - proxy.web(req, res, { ignorePath: false, target: { port: ports.karma } }); } else { proxy.web(req, res, { ignorePath: false, target: { port: ports.jekyll } }); } diff --git a/_develop/sauce.js b/_develop/sauce.js deleted file mode 100644 index f8448d5ead..0000000000 --- a/_develop/sauce.js +++ /dev/null @@ -1,15 +0,0 @@ -const _ = require('lodash'); -const os = require('os'); - -if (process.env.TRAVIS) { - module.exports = { - build: process.env.TRAVIS_BUILD_ID, - tunnel: process.env.TRAVIS_JOB_NUMBER, - }; -} else { - const id = _.random(16 * 16 * 16 * 16).toString(16); - module.exports = { - build: `${os.hostname()}-${id}`, - tunnel: `${os.hostname()}-tunnel-${id}`, - }; -} diff --git a/package-lock.json b/package-lock.json index f86dddd82c..38e7326d69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,10 +24,10 @@ "@babel/preset-env": "^7.22.5", "@babel/preset-typescript": "^7.22.5", "@playwright/test": "^1.34.3", - "@types/jasmine": "^4.3.0", "@types/lodash.clonedeep": "^4.5.7", "@typescript-eslint/eslint-plugin": "^5.59.8", "@typescript-eslint/parser": "^5.59.8", + "@vitest/browser": "^0.33.0", "babel-loader": "^9.1.2", "babel-plugin-istanbul": "^6.1.1", "css-loader": "^6.8.1", @@ -40,17 +40,11 @@ "highlight.js": "^9.18.1", "html-loader": "^4.2.0", "http-proxy": "^1.18.0", - "jasmine": "^4.4.0", - "jasmine-core": "^4.4.0", - "karma": "^6.4.2", - "karma-chrome-launcher": "^3.2.0", - "karma-coverage": "^2.2.0", - "karma-jasmine": "^5.1.0", - "karma-jsdom-launcher": "^14.0.0", - "karma-sauce-launcher": "^4.3.6", + "jsdom": "^22.1.0", "lodash": "^4.17.15", "mini-css-extract-plugin": "^2.7.6", "npm-run-all": "^4.1.5", + "playwright": "^1.36.0", "prettier": "^2.7.1", "style-loader": "^3.3.3", "stylus": "^0.59.0", @@ -58,6 +52,7 @@ "ts-loader": "^9.4.3", "ts-node": "^10.9.1", "typescript": "^5.0.4", + "vitest": "^0.33.0", "webpack": "^5.87.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1" @@ -2113,15 +2108,6 @@ "partytown": "bin/partytown.cjs" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2153,6 +2139,358 @@ "node": ">=10.0.0" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.12.tgz", + "integrity": "sha512-LIxaNIQfkFZbTLb4+cX7dozHlAbAshhFE5PKdro0l+FnCpx1GDJaQ2WMcqm+ToXKMt8p8Uojk/MFRuGyz3V5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.12.tgz", + "integrity": "sha512-BMAlczRqC/LUt2P97E4apTBbkvS9JTJnp2DKFbCwpZ8vBvXVbNdqmvzW/OsdtI/+mGr+apkkpqGM8WecLkPgrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.12.tgz", + "integrity": "sha512-zU5MyluNsykf5cOJ0LZZZjgAHbhPJ1cWfdH1ZXVMXxVMhEV0VZiZXQdwBBVvmvbF28EizeK7obG9fs+fpmS0eQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.12.tgz", + "integrity": "sha512-zUZMep7YONnp6954QOOwEBwFX9svlKd3ov6PkxKd53LGTHsp/gy7vHaPGhhjBmEpqXEXShi6dddjIkmd+NgMsA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.12.tgz", + "integrity": "sha512-ohqLPc7i67yunArPj1+/FeeJ7AgwAjHqKZ512ADk3WsE3FHU9l+m5aa7NdxXr0HmN1bjDlUslBjWNbFlD9y12Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.12.tgz", + "integrity": "sha512-GIIHtQXqgeOOqdG16a/A9N28GpkvjJnjYMhOnXVbn3EDJcoItdR58v/pGN31CHjyXDc8uCcRnFWmqaJt24AYJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.12.tgz", + "integrity": "sha512-zK0b9a1/0wZY+6FdOS3BpZcPc1kcx2G5yxxfEJtEUzVxI6n/FrC2Phsxj/YblPuBchhBZ/1wwn7AyEBUyNSa6g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.12.tgz", + "integrity": "sha512-y75OijvrBE/1XRrXq1jtrJfG26eHeMoqLJ2dwQNwviwTuTtHGCojsDO6BJNF8gU+3jTn1KzJEMETytwsFSvc+Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.12.tgz", + "integrity": "sha512-JKgG8Q/LL/9sw/iHHxQyVMoQYu3rU3+a5Z87DxC+wAu3engz+EmctIrV+FGOgI6gWG1z1+5nDDbXiRMGQZXqiw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.12.tgz", + "integrity": "sha512-yoRIAqc0B4lDIAAEFEIu9ttTRFV84iuAl0KNCN6MhKLxNPfzwCBvEMgwco2f71GxmpBcTtn7KdErueZaM2rEvw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.12.tgz", + "integrity": "sha512-qYgt3dHPVvf/MgbIBpJ4Sup/yb9DAopZ3a2JgMpNKIHUpOdnJ2eHBo/aQdnd8dJ21X/+sS58wxHtA9lEazYtXQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.12.tgz", + "integrity": "sha512-wHphlMLK4ufNOONqukELfVIbnGQJrHJ/mxZMMrP2jYrPgCRZhOtf0kC4yAXBwnfmULimV1qt5UJJOw4Kh13Yfg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.12.tgz", + "integrity": "sha512-TeN//1Ft20ZZW41+zDSdOI/Os1bEq5dbvBvYkberB7PHABbRcsteeoNVZFlI0YLpGdlBqohEpjrn06kv8heCJg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.12.tgz", + "integrity": "sha512-AgUebVS4DoAblBgiB2ACQ/8l4eGE5aWBb8ZXtkXHiET9mbj7GuWt3OnsIW/zX+XHJt2RYJZctbQ2S/mDjbp0UA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.12.tgz", + "integrity": "sha512-dJ3Rb3Ei2u/ysSXd6pzleGtfDdc2MuzKt8qc6ls8vreP1G3B7HInX3i7gXS4BGeVd24pp0yqyS7bJ5NHaI9ing==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.12.tgz", + "integrity": "sha512-OrNJMGQbPaVyHHcDF8ybNSwu7TDOfX8NGpXCbetwOSP6txOJiWlgQnRymfC9ocR1S0Y5PW0Wb1mV6pUddqmvmQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.12.tgz", + "integrity": "sha512-55FzVCAiwE9FK8wWeCRuvjazNRJ1QqLCYGZVB6E8RuQuTeStSwotpSW4xoRGwp3a1wUsaVCdYcj5LGCASVJmMg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.12.tgz", + "integrity": "sha512-qnluf8rfb6Y5Lw2tirfK2quZOBbVqmwxut7GPCIJsM8lc4AEUj9L8y0YPdLaPK0TECt4IdyBdBD/KRFKorlK3g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.12.tgz", + "integrity": "sha512-+RkKpVQR7bICjTOPUpkTBTaJ4TFqQBX5Ywyd/HSdDkQGn65VPkTsR/pL4AMvuMWy+wnXgIl4EY6q4mVpJal8Kg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.12.tgz", + "integrity": "sha512-GNHuciv0mFM7ouzsU0+AwY+7eV4Mgo5WnbhfDCQGtpvOtD1vbOiRjPYG6dhmMoFyBjj+pNqQu2X+7DKn0KQ/Gw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.12.tgz", + "integrity": "sha512-kR8cezhYipbbypGkaqCTWIeu4zID17gamC8YTPXYtcN3E5BhhtTnwKBn9I0PJur/T6UVwIEGYzkffNL0lFvxEw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.12.tgz", + "integrity": "sha512-O0UYQVkvfM/jO8a4OwoV0mAKSJw+mjWTAd1MJd/1FCX6uiMdLmMRPK/w6e9OQ0ob2WGxzIm9va/KG0Ja4zIOgg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2596,6 +2934,18 @@ "node": ">=8" } }, + "node_modules/@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -2660,6 +3010,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@jspm/core": { + "version": "2.0.0-beta.24", + "resolved": "https://registry.npmjs.org/@jspm/core/-/core-2.0.0-beta.24.tgz", + "integrity": "sha512-a4Bo/80Z6CoJNor5ldgs6002utmmbttP4JYd/FJ0Ob2fVdf6O6ha5SORBCqrnDnBvMc1TlrHY7dCfat5+H0a6A==", + "dev": true + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -3951,6 +4307,12 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, "node_modules/@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -3969,6 +4331,12 @@ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -4063,7 +4431,6 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true, - "peer": true, "engines": { "node": ">= 10" } @@ -4129,7 +4496,9 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@types/body-parser": { "version": "1.19.2", @@ -4161,6 +4530,21 @@ "@types/responselike": "*" } }, + "node_modules/@types/chai": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", + "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "dev": true + }, + "node_modules/@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, "node_modules/@types/common-tags": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.1.tgz", @@ -4311,12 +4695,6 @@ "@types/node": "*" } }, - "node_modules/@types/jasmine": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.3.0.tgz", - "integrity": "sha512-u1jWakf8CWvLfSEZyxmzkgBzOEvXH/szpT0e6G8BTkx5Eu0BhDn7sbc5dz0JBN/6Wwm9rBe+JAsk9tJRyH9ZkA==", - "dev": true - }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -4522,7 +4900,9 @@ "version": "0.7.36", "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@types/unist": { "version": "2.0.6", @@ -4534,7 +4914,9 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@types/ws": { "version": "8.5.5", @@ -4551,6 +4933,7 @@ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", "dev": true, "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } @@ -4986,11 +5369,124 @@ "resolve": "^1.10.0" } }, + "node_modules/@vitest/browser": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-0.33.0.tgz", + "integrity": "sha512-lY7iEFqTAYsd2Dv8ej/my2ySomv38leWxudFnqI8McYFoF74U5r3vnw0+ke1JXk2NJOtMSQiGlV8yyIc7gON+w==", + "dev": true, + "dependencies": { + "modern-node-polyfills": "^0.1.3", + "sirv": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": ">=0.32.3" + } + }, + "node_modules/@vitest/expect": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.33.0.tgz", + "integrity": "sha512-sVNf+Gla3mhTCxNJx+wJLDPp/WcstOe0Ksqz4Vec51MmgMth/ia0MGFEkIZmVGeTL5HtjYR4Wl/ZxBxBXZJTzQ==", + "dev": true, + "dependencies": { + "@vitest/spy": "0.33.0", + "@vitest/utils": "0.33.0", + "chai": "^4.3.7" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.33.0.tgz", + "integrity": "sha512-UPfACnmCB6HKRHTlcgCoBh6ppl6fDn+J/xR8dTufWiKt/74Y9bHci5CKB8tESSV82zKYtkBJo9whU3mNvfaisg==", + "dev": true, + "dependencies": { + "@vitest/utils": "0.33.0", + "p-limit": "^4.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.33.0.tgz", + "integrity": "sha512-tJjrl//qAHbyHajpFvr8Wsk8DIOODEebTu7pgBrP07iOepR5jYkLFiqLq2Ltxv+r0uptUb4izv1J8XBOwKkVYA==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "pretty-format": "^29.5.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.33.0.tgz", + "integrity": "sha512-Kv+yZ4hnH1WdiAkPUQTpRxW8kGtH8VRTnus7ZTGovFYM1ZezJpvGtb9nPIjPnptHbsyIAxYZsEpVPYgtpjGnrg==", + "dev": true, + "dependencies": { + "tinyspy": "^2.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.33.0.tgz", + "integrity": "sha512-pF1w22ic965sv+EN6uoePkAOTkAPWM03Ri/jXNyMIKBb/XHLDPfhLvf/Fa9g0YECevAIz56oVYXhodLvLQ/awA==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.4.3", + "loupe": "^2.3.6", + "pretty-format": "^29.5.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@wdio/config": { "version": "7.31.1", "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.31.1.tgz", "integrity": "sha512-WAfswbCatwiaDVqy6kfF/5T8/WS/US/SRhBGUFrfBuGMIe+RRoHgy7jURFWSvUIE7CNHj8yvs46fLUcxhXjzcQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/glob": "^8.1.0", "@wdio/logger": "7.26.0", @@ -5008,6 +5504,8 @@ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/minimatch": "^5.1.2", "@types/node": "*" @@ -5018,6 +5516,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -5039,6 +5539,8 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -5048,6 +5550,8 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5067,6 +5571,8 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5094,6 +5600,8 @@ "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "chalk": "^4.0.0", "loglevel": "^1.6.0", @@ -5109,6 +5617,8 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -5124,6 +5634,8 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5140,6 +5652,8 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -5151,13 +5665,17 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/@wdio/logger/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=8" } @@ -5167,6 +5685,8 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -5179,6 +5699,8 @@ "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=12.0.0" } @@ -5188,6 +5710,8 @@ "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.30.2.tgz", "integrity": "sha512-aW4nuMI+gbRmxmL4jMarBjuiQ+cFscr/8jHDt5hGx/gc/f7ifrZa4t6M5H8vFIKsvjUwl9lZRiVO4NVvvp6+cg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@wdio/utils": "7.30.2" }, @@ -5200,6 +5724,8 @@ "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.30.2.tgz", "integrity": "sha512-np7I+smszFUennbQKdzbMN/zUL3s3EZq9pCCUcTRjjs9TE4tnn0wfmGdoz2o7REYu6kn9NfFFJyVIM2VtBbKEA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "7.26.0", "@wdio/types": "7.30.2", @@ -5214,6 +5740,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -5434,8 +5962,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/abortcontroller-polyfill": { "version": "1.7.5", @@ -5455,9 +5982,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "bin": { "acorn": "bin/acorn" }, @@ -5465,17 +5992,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", - "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", - "dev": true, - "peer": true, - "dependencies": { - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2" - } - }, "node_modules/acorn-import-assertions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", @@ -5706,32 +6222,13 @@ } ] }, - "node_modules/archive-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", - "dev": true, - "dependencies": { - "file-type": "^4.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/archive-type/node_modules/file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/archiver": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^2.1.0", "async": "^3.2.3", @@ -5750,6 +6247,8 @@ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -5770,13 +6269,17 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/archiver/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -5791,6 +6294,8 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -5926,6 +6431,15 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -6484,12 +6998,6 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true - }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -6668,37 +7176,17 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "*" } }, - "node_modules/buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -6723,6 +7211,15 @@ "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/cache-manager": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.11.1.tgz", @@ -6859,6 +7356,24 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/chai": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -6953,6 +7468,15 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -7000,6 +7524,8 @@ "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", @@ -7018,6 +7544,8 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -7428,6 +7956,8 @@ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -7443,6 +7973,8 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -7538,21 +8070,6 @@ "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -7562,60 +8079,6 @@ "node": ">=0.8" } }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/connect/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/connect/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/constant-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", @@ -7740,6 +8203,8 @@ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true, + "optional": true, + "peer": true, "bin": { "crc32": "bin/crc32.njs" }, @@ -7752,6 +8217,8 @@ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -7765,6 +8232,8 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -7984,7 +8453,9 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/css-tree": { "version": "1.1.3", @@ -8010,7 +8481,9 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/css-what": { "version": "6.1.0", @@ -8142,7 +8615,6 @@ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dev": true, - "peer": true, "dependencies": { "rrweb-cssom": "^0.6.0" }, @@ -8155,12 +8627,6 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, - "node_modules/custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, "node_modules/d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -8180,7 +8646,6 @@ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", "dev": true, - "peer": true, "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", @@ -8195,7 +8660,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dev": true, - "peer": true, "dependencies": { "punycode": "^2.3.0" }, @@ -8208,7 +8672,6 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -8218,7 +8681,6 @@ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, - "peer": true, "dependencies": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" @@ -8239,15 +8701,6 @@ "url": "https://opencollective.com/date-fns" } }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -8276,8 +8729,7 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/decode-named-character-reference": { "version": "1.0.2", @@ -8300,25 +8752,6 @@ "node": ">=0.10" } }, - "node_modules/decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "dev": true, - "dependencies": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", @@ -8344,178 +8777,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "dev": true, - "dependencies": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-tar/node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-tar/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "dev": true, - "dependencies": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-tarbz2/node_modules/file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-tarbz2/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "dependencies": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-targz/node_modules/file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-targz/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", - "dev": true, - "dependencies": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress-unzip/node_modules/file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-unzip/node_modules/get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", - "dev": true, - "dependencies": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-unzip/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress/node_modules/make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "dependencies": { - "pify": "^3.0.0" + "type-detect": "^4.0.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/decompress/node_modules/make-dir/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/decompress/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/deep-equal": { @@ -8791,6 +9062,8 @@ "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.31.1.tgz", "integrity": "sha512-QU8rMSspKk3c/mX0uawIlRslwH7F+sdTGBZseXgAA5XIgqWbanCQdfHLvxcEzJJHRE5Gq6vGPJIAjq/z9Z4j/Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^18.0.0", "@types/ua-parser-js": "^0.7.33", @@ -8814,13 +9087,17 @@ "version": "0.0.1130274", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1130274.tgz", "integrity": "sha512-kIozBWajgsi1g0W8yzALI4ZdCp6KG1yWaq8NN1ehQM3zX6JRegLSzfexz7XT5eFjmq1RkpMYgeKmfi3GsHrCLw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/devtools/node_modules/@wdio/types": { "version": "7.30.2", "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -8867,6 +9144,8 @@ "url": "https://paypal.me/faisalman" } ], + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -8876,16 +9155,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "dev": true, + "optional": true, + "peer": true, "bin": { "uuid": "dist/bin/uuid" } }, - "node_modules/di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -8895,6 +9170,15 @@ "node": ">=0.3.1" } }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8956,18 +9240,6 @@ "utila": "~0.4" } }, - "node_modules/dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -9005,7 +9277,6 @@ "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", "dev": true, - "peer": true, "dependencies": { "webidl-conversions": "^7.0.0" }, @@ -9018,7 +9289,6 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -9083,286 +9353,6 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, - "node_modules/download": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz", - "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==", - "dev": true, - "dependencies": { - "archive-type": "^4.0.0", - "content-disposition": "^0.5.2", - "decompress": "^4.2.1", - "ext-name": "^5.0.0", - "file-type": "^11.1.0", - "filenamify": "^3.0.0", - "get-stream": "^4.1.0", - "got": "^8.3.1", - "make-dir": "^2.1.0", - "p-event": "^2.1.0", - "pify": "^4.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/download/node_modules/@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==", - "dev": true, - "dependencies": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" - } - }, - "node_modules/download/node_modules/cacheable-request/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/download/node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/download/node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/file-type": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", - "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/download/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/download/node_modules/got": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", - "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/got/node_modules/get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/got/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", - "dev": true - }, - "node_modules/download/node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "node_modules/download/node_modules/keyv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", - "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/download/node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/download/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/download/node_modules/normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/download/node_modules/query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "dependencies": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/download/node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/download/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/download/node_modules/sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", - "dev": true, - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/download/node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -9378,6 +9368,8 @@ "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/which": "^1.3.2", "which": "^2.0.2" @@ -9527,12 +9519,6 @@ "node": ">=8.6" } }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, "node_modules/entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", @@ -9681,12 +9667,6 @@ "node": ">=0.10" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, "node_modules/es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", @@ -9722,6 +9702,363 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/esbuild": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.12.tgz", + "integrity": "sha512-XuOVLDdtsDslXStStduT41op21Ytmf4/BDS46aa3xPJ7X5h2eMWBF1oAe3QjUH3bDksocNXgzGUZ7XHIBya6Tg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.12", + "@esbuild/android-arm64": "0.18.12", + "@esbuild/android-x64": "0.18.12", + "@esbuild/darwin-arm64": "0.18.12", + "@esbuild/darwin-x64": "0.18.12", + "@esbuild/freebsd-arm64": "0.18.12", + "@esbuild/freebsd-x64": "0.18.12", + "@esbuild/linux-arm": "0.18.12", + "@esbuild/linux-arm64": "0.18.12", + "@esbuild/linux-ia32": "0.18.12", + "@esbuild/linux-loong64": "0.18.12", + "@esbuild/linux-mips64el": "0.18.12", + "@esbuild/linux-ppc64": "0.18.12", + "@esbuild/linux-riscv64": "0.18.12", + "@esbuild/linux-s390x": "0.18.12", + "@esbuild/linux-x64": "0.18.12", + "@esbuild/netbsd-x64": "0.18.12", + "@esbuild/openbsd-x64": "0.18.12", + "@esbuild/sunos-x64": "0.18.12", + "@esbuild/win32-arm64": "0.18.12", + "@esbuild/win32-ia32": "0.18.12", + "@esbuild/win32-x64": "0.18.12" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -9751,49 +10088,6 @@ "node": ">=0.8.0" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "peer": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eslint": { "version": "8.42.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", @@ -10779,31 +11073,6 @@ "type": "^2.7.2" } }, - "node_modules/ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "dependencies": { - "mime-db": "^1.28.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, - "dependencies": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/ext/node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", @@ -10856,6 +11125,8 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -10876,6 +11147,8 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -10997,6 +11270,8 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "pend": "~1.2.0" } @@ -11078,29 +11353,6 @@ "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz", - "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==", - "dev": true, - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/filesize": { "version": "8.0.7", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", @@ -11463,16 +11715,6 @@ "node": ">= 0.6" } }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -13399,6 +13641,15 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", @@ -13511,57 +13762,6 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "node_modules/global-agent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz", - "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==", - "dev": true, - "dependencies": { - "boolean": "^3.0.1", - "core-js": "^3.6.5", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/global-agent/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/global-agent/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/global-agent/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", @@ -13627,21 +13827,6 @@ "node": ">=4" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -13856,15 +14041,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -13876,18 +14052,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "dependencies": { - "has-symbol-support-x": "^1.4.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", @@ -13910,16 +14074,6 @@ "node": ">=8" } }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "node_modules/hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", @@ -14160,7 +14314,6 @@ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", "dev": true, - "peer": true, "dependencies": { "whatwg-encoding": "^2.0.0" }, @@ -14173,12 +14326,6 @@ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "node_modules/html-loader": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-4.2.0.tgz", @@ -14297,7 +14444,6 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, - "peer": true, "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -14662,19 +14808,6 @@ "node": ">= 0.10" } }, - "node_modules/into-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==", - "dev": true, - "dependencies": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -15006,12 +15139,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", - "dev": true - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -15064,15 +15191,6 @@ "node": ">=8" } }, - "node_modules/is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -15081,15 +15199,6 @@ "node": ">=8" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -15105,8 +15214,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/is-promise": { "version": "2.2.2", @@ -15159,15 +15267,6 @@ "node": ">=8" } }, - "node_modules/is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-root": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", @@ -15363,18 +15462,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -15413,109 +15500,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "dependencies": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/jasmine": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.4.0.tgz", - "integrity": "sha512-xrbOyYkkCvgduNw7CKktDtNb+BwwBv/zvQeHpTkbxqQ37AJL5V4sY3jHoMIJPP/hTc3QxLVwOyxc87AqA+kw5g==", - "dev": true, - "dependencies": { - "glob": "^7.1.6", - "jasmine-core": "^4.4.0" - }, - "bin": { - "jasmine": "bin/jasmine.js" - } - }, - "node_modules/jasmine-core": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.4.0.tgz", - "integrity": "sha512-+l482uImx5BVd6brJYlaHe2UwfKoZBqQfNp20ZmdNfsjGFTemGfqHLsXjKEW23w9R/m8WYeFc9JmIgjj6dUtAA==", - "dev": true - }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -15583,20 +15567,16 @@ } }, "node_modules/jsdom": { - "version": "21.1.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.2.tgz", - "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dev": true, - "peer": true, "dependencies": { "abab": "^2.0.6", - "acorn": "^8.8.2", - "acorn-globals": "^7.0.0", "cssstyle": "^3.0.0", "data-urls": "^4.0.0", "decimal.js": "^10.4.3", "domexception": "^4.0.0", - "escodegen": "^2.0.0", "form-data": "^4.0.0", "html-encoding-sniffer": "^3.0.0", "http-proxy-agent": "^5.0.0", @@ -15617,7 +15597,7 @@ "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=16" }, "peerDependencies": { "canvas": "^2.5.0" @@ -15633,7 +15613,6 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, - "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -15648,7 +15627,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dev": true, - "peer": true, "dependencies": { "punycode": "^2.3.0" }, @@ -15661,7 +15639,6 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -15671,7 +15648,6 @@ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, - "peer": true, "dependencies": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" @@ -15722,12 +15698,6 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -15739,6 +15709,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -15762,177 +15738,6 @@ "node": ">=4.0" } }, - "node_modules/karma": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", - "integrity": "sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==", - "dev": true, - "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.4.1", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/karma-chrome-launcher": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", - "dev": true, - "dependencies": { - "which": "^1.2.1" - } - }, - "node_modules/karma-chrome-launcher/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/karma-coverage": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.0.tgz", - "integrity": "sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.1", - "istanbul-reports": "^3.0.5", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/karma-jasmine": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", - "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", - "dev": true, - "dependencies": { - "jasmine-core": "^4.1.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "karma": "^6.0.0" - } - }, - "node_modules/karma-jsdom-launcher": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/karma-jsdom-launcher/-/karma-jsdom-launcher-14.0.0.tgz", - "integrity": "sha512-GrZpJK9cdBo0C6YXZh0Sbq8D5NvdoTvRE9R/nhJzl0Tyfg7GI6iCU73ww264eqAZzy1mjCk/vj8sVA6ECacLlQ==", - "dev": true, - "peerDependencies": { - "jsdom": ">=14 <=21", - "karma": ">=2 <=6" - } - }, - "node_modules/karma-sauce-launcher": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/karma-sauce-launcher/-/karma-sauce-launcher-4.3.6.tgz", - "integrity": "sha512-Ej62q4mUPFktyAm8g0g8J5qhwEkXwdHrwtiV4pZjKNHNnSs+4qgDyzs3VkpOy3AmNTsTqQXUN/lpiy0tZpDJZQ==", - "dev": true, - "dependencies": { - "global-agent": "^2.1.12", - "saucelabs": "^4.6.3", - "webdriverio": "^6.7.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/karma/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/karma/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/karma/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/karma/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/karma/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/keyv": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", @@ -15970,6 +15775,8 @@ "resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz", "integrity": "sha512-X/u76z4JtDVq10u1JA5UQfatPxgPaVDMYTrgHyiTpGN2z4TMEJkIHsoSBBSg9SWZEIXTKsi9kHgiQ9o3Y/4yog==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -16016,6 +15823,8 @@ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -16040,6 +15849,8 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" @@ -16050,6 +15861,8 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -16058,7 +15871,9 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lilconfig": { "version": "2.0.6", @@ -16148,6 +15963,18 @@ "node": ">=8.9.0" } }, + "node_modules/local-pkg": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", + "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -16188,13 +16015,17 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lodash.difference": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lodash.every": { "version": "4.6.0", @@ -16205,7 +16036,9 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lodash.flattendeep": { "version": "4.4.0", @@ -16226,13 +16059,17 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", "integrity": "sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lodash.map": { "version": "4.6.0", @@ -16263,7 +16100,9 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lodash.uniq": { "version": "4.5.0", @@ -16274,29 +16113,17 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true - }, - "node_modules/log4js": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", - "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", "dev": true, - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.3" - }, - "engines": { - "node": ">=8.0" - } + "optional": true, + "peer": true }, "node_modules/loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.6.0" }, @@ -16309,7 +16136,9 @@ "version": "0.8.4", "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/longest-streak": { "version": "3.0.1", @@ -16332,6 +16161,15 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -16373,6 +16211,24 @@ "es5-ext": "~0.10.2" } }, + "node_modules/magic-string": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -16433,31 +16289,9 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", - "dev": true - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/matcher/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true, + "peer": true }, "node_modules/md5-file": { "version": "5.0.0", @@ -17518,6 +17352,127 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, + "node_modules/mlly": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz", + "integrity": "sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "pathe": "^1.1.1", + "pkg-types": "^1.0.3", + "ufo": "^1.1.2" + } + }, + "node_modules/modern-node-polyfills": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/modern-node-polyfills/-/modern-node-polyfills-0.1.3.tgz", + "integrity": "sha512-/4dB85Sdkt9MjWwtpKnsNTYhh0+fqjFC4ZEgDP4B0e6kyzbGUnX4NDxTUCaVwRLVF9gcEDcRQjol8pn05B3TUQ==", + "dev": true, + "dependencies": { + "@jspm/core": "2.0.0-beta.24", + "@rollup/pluginutils": "^3.1.0", + "esbuild": "^0.14.54", + "local-pkg": "^0.4.3" + } + }, + "node_modules/modern-node-polyfills/node_modules/@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/modern-node-polyfills/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/modern-node-polyfills/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/modern-node-polyfills/node_modules/esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "node_modules/modern-node-polyfills/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/modern-node-polyfills/node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "peer": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -17535,6 +17490,15 @@ "node": ">=4" } }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -18009,8 +17973,7 @@ "version": "2.2.5", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.5.tgz", "integrity": "sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/object-assign": { "version": "4.1.1", @@ -18240,18 +18203,6 @@ "node": ">=8" } }, - "node_modules/p-event": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", - "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", - "dev": true, - "dependencies": { - "p-timeout": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -18260,20 +18211,13 @@ "node": ">=4" } }, - "node_modules/p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/p-iteration": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz", "integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=8.0.0" } @@ -18339,18 +18283,6 @@ "node": ">= 4" } }, - "node_modules/p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -18790,6 +18722,21 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", + "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", @@ -18806,7 +18753,9 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/periscopic": { "version": "3.0.4", @@ -18860,27 +18809,6 @@ "node": ">=4" } }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -18892,6 +18820,17 @@ "node": ">=8" } }, + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -18964,6 +18903,22 @@ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" }, + "node_modules/playwright": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.36.0.tgz", + "integrity": "sha512-ODVOTp5WoRMxDJY3liMmC+wVNicc0cQB17gASvQ+zLBggVK9a2x3gdT5mbl7av+zomvtdirWOqqfD+O6qIrFgw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "playwright-core": "1.36.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/playwright-core": { "version": "1.34.3", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.34.3.tgz", @@ -18976,10 +18931,22 @@ "node": ">=14" } }, + "node_modules/playwright/node_modules/playwright-core": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.36.0.tgz", + "integrity": "sha512-7RTr8P6YJPAqB+8j5ATGHqD6LvLLM39sYVNsslh78g8QeLcBs5750c6+msjrHUwwGt+kEbczBj1XB22WMwn+WA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", + "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", "funding": [ { "type": "opencollective", @@ -19609,6 +19576,38 @@ "renderkid": "^2.0.4" } }, + "node_modules/pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/prism-react-renderer": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz", @@ -19711,7 +19710,9 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/pseudomap": { "version": "1.0.2", @@ -19722,8 +19723,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/pump": { "version": "3.0.0", @@ -19758,6 +19758,8 @@ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.7.0.tgz", "integrity": "sha512-rXja4vcnAzFAP1OVLq/5dWNfwBGuzcOARJ6qGV7oAZhnLmVRU8G5MsdeQEAOy332ZhkIOnn9jp15R89LKHyp2Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "cross-fetch": "3.1.5", "debug": "4.3.4", @@ -19780,13 +19782,17 @@ "version": "0.0.981744", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.981744.tgz", "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/puppeteer-core/node_modules/ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -19803,15 +19809,6 @@ } } }, - "node_modules/qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true, - "engines": { - "node": ">=0.9" - } - }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -19830,7 +19827,9 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/query-string": { "version": "6.14.1", @@ -19853,8 +19852,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -20371,6 +20369,8 @@ "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.2.tgz", "integrity": "sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -20380,6 +20380,8 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -20389,6 +20391,8 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -20880,6 +20884,8 @@ "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.2.tgz", "integrity": "sha512-HmgVS3j+FLrEDBTDYysPdPVF9/hioDMJ/otOiQDKqk77YfZeeLOj0qi34yObumcud1gBpk+wpBTEg4kMicD++A==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "fast-deep-equal": "^2.0.1" } @@ -20888,7 +20894,9 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/restore-cursor": { "version": "3.1.0", @@ -20941,17 +20949,13 @@ "integrity": "sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg==", "dev": true }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, "node_modules/rgb2hex": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/rimraf": { "version": "3.0.2", @@ -20967,35 +20971,27 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "node_modules/rollup": { + "version": "3.26.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.2.tgz", + "integrity": "sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==", "dev": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=8.0" + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/roarr/node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "node_modules/rrweb-cssom": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/rss": { "version": "1.2.2", @@ -21240,107 +21236,6 @@ "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", "dev": true }, - "node_modules/saucelabs": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-7.2.2.tgz", - "integrity": "sha512-rxbazYeKw0RDoXnGCfTeY6or9QM42Nn/LcZyO4Wi11h1d5k7EkoXU58g6FrYZgC7+UtI1t4CZu5Z1a2F/YQzvg==", - "dev": true, - "dependencies": { - "change-case": "^4.1.2", - "download": "^8.0.0", - "form-data": "^4.0.0", - "got": "^11.8.2", - "hash.js": "^1.1.7", - "query-string": "^7.0.1", - "tunnel": "^0.0.6", - "yargs": "^17.2.1" - }, - "bin": { - "sl": "bin/sl" - } - }, - "node_modules/saucelabs/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/saucelabs/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/saucelabs/node_modules/query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "dev": true, - "dependencies": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/saucelabs/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/saucelabs/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/saucelabs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -21352,7 +21247,6 @@ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, - "peer": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -21434,25 +21328,6 @@ "node": ">=4" } }, - "node_modules/seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", - "dev": true, - "dependencies": { - "commander": "^2.8.1" - }, - "bin": { - "seek-bunzip": "bin/seek-bunzip", - "seek-table": "bin/seek-bzip-table" - } - }, - "node_modules/seek-bzip/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -21479,12 +21354,6 @@ "semver": "bin/semver.js" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true - }, "node_modules/semver-diff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", @@ -21558,33 +21427,6 @@ "upper-case-first": "^2.0.2" } }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -21821,6 +21663,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -21887,6 +21735,20 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, + "node_modules/sirv": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", + "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -22021,30 +21883,6 @@ "websocket-driver": "^0.7.4" } }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", - "dev": true, - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", - "dev": true, - "dependencies": { - "sort-keys": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -22243,6 +22081,12 @@ "node": "*" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, "node_modules/stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", @@ -22256,6 +22100,12 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz", + "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==", + "dev": true + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -22267,52 +22117,6 @@ "node": ">= 0.4" } }, - "node_modules/streamroller": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", - "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", - "dev": true, - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/streamroller/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/streamroller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/streamroller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -22480,15 +22284,6 @@ "node": ">=0.10.0" } }, - "node_modules/strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "dev": true, - "dependencies": { - "is-natural-number": "^4.0.1" - } - }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -22516,16 +22311,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-outer": { + "node_modules/strip-literal": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.1.tgz", + "integrity": "sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==", "dev": true, "dependencies": { - "escape-string-regexp": "^1.0.2" + "acorn": "^8.8.2" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/antfu" } }, "node_modules/strtok3": { @@ -22750,8 +22545,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/table": { "version": "6.8.0", @@ -22836,34 +22630,6 @@ "node": ">=6" } }, - "node_modules/tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "dependencies": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/tar-stream/node_modules/bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "dev": true, - "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, "node_modules/term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", @@ -23020,15 +22786,6 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "devOptional": true }, - "node_modules/timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -23038,6 +22795,30 @@ "next-tick": "1" } }, + "node_modules/tinybench": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", + "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.6.0.tgz", + "integrity": "sha512-FdswUUo5SxRizcBc6b1GSuLpLjisa8N8qMyYoP3rl+bym+QauhtJP5bvZY1ytt8krKGmMLYIRl36HBZfeAoqhQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz", + "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/title-case": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", @@ -23057,12 +22838,6 @@ "node": ">=8.17.0" } }, - "node_modules/to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -23114,12 +22889,20 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, - "peer": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -23135,7 +22918,6 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, - "peer": true, "engines": { "node": ">= 4.0.0" } @@ -23161,18 +22943,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/trough": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", @@ -23421,15 +23191,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true, - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -23457,6 +23218,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -23528,6 +23298,12 @@ "node": "*" } }, + "node_modules/ufo": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.1.2.tgz", + "integrity": "sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==", + "dev": true + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -23547,6 +23323,8 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -24042,7 +23820,6 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, - "peer": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -24059,15 +23836,6 @@ "node": ">=4" } }, - "node_modules/url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -24225,13 +23993,159 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "node_modules/vite": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.3.tgz", + "integrity": "sha512-IMnXQXXWgLi5brBQx/4WzDxdzW0X3pjO4nqFJAuNvwKtxzAmPzFE1wszW3VDpAGQJm3RZkm/brzRdyGsnwgJIA==", "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.25", + "rollup": "^3.25.2" + }, + "bin": { + "vite": "bin/vite.js" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.33.0.tgz", + "integrity": "sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "mlly": "^1.4.0", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^3.0.0 || ^4.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.33.0.tgz", + "integrity": "sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==", + "dev": true, + "dependencies": { + "@types/chai": "^4.3.5", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "@vitest/expect": "0.33.0", + "@vitest/runner": "0.33.0", + "@vitest/snapshot": "0.33.0", + "@vitest/spy": "0.33.0", + "@vitest/utils": "0.33.0", + "acorn": "^8.9.0", + "acorn-walk": "^8.2.0", + "cac": "^6.7.14", + "chai": "^4.3.7", + "debug": "^4.3.4", + "local-pkg": "^0.4.3", + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.3.3", + "strip-literal": "^1.0.1", + "tinybench": "^2.5.0", + "tinypool": "^0.6.0", + "vite": "^3.0.0 || ^4.0.0", + "vite-node": "0.33.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*", + "playwright": "*", + "safaridriver": "*", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } } }, "node_modules/w3c-xmlserializer": { @@ -24239,7 +24153,6 @@ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, - "peer": true, "dependencies": { "xml-name-validator": "^4.0.0" }, @@ -24283,6 +24196,8 @@ "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.31.1.tgz", "integrity": "sha512-nCdJLxRnYvOMFqTEX7sqQtF/hV/Jgov0Y6ICeOm1DMTlZSRRDaUsBMlEAPkEwif9uBJYdM0znv8qzfX358AGqQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^18.0.0", "@wdio/config": "7.31.1", @@ -24303,6 +24218,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -24339,6 +24256,8 @@ "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.31.1.tgz", "integrity": "sha512-ri8L7A8VbJ2lZyndu0sG56d2zBot7SXdeI95Kni43e0pd/5Xm4IMAPdWB60yS8vqrP8goJU2iuQ8/ltry4IDbQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/aria-query": "^5.0.0", "@types/node": "^18.0.0", @@ -24377,6 +24296,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -24398,6 +24319,8 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -24407,6 +24330,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -24421,6 +24346,8 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -24436,6 +24363,8 @@ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -24834,7 +24763,6 @@ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", "dev": true, - "peer": true, "dependencies": { "iconv-lite": "0.6.3" }, @@ -24847,7 +24775,6 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -24860,7 +24787,6 @@ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -24941,6 +24867,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", @@ -25067,7 +25009,6 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -25098,8 +25039,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/xmlhttprequest-ssl": { "version": "2.0.0", @@ -25228,6 +25168,8 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -25303,6 +25245,8 @@ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^2.1.0", "compress-commons": "^4.1.0", @@ -25317,6 +25261,8 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -26750,12 +26696,6 @@ "resolved": "https://registry.npmjs.org/@builder.io/partytown/-/partytown-0.5.4.tgz", "integrity": "sha512-qnikpQgi30AS01aFlNQV6l8/qdZIcP76mp90ti+u4rucXHsn4afSKivQXApqxvrQG9+Ibv45STyvHizvxef/7A==" }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true - }, "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -26783,6 +26723,160 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@esbuild/android-arm": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.12.tgz", + "integrity": "sha512-LIxaNIQfkFZbTLb4+cX7dozHlAbAshhFE5PKdro0l+FnCpx1GDJaQ2WMcqm+ToXKMt8p8Uojk/MFRuGyz3V5Sw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.12.tgz", + "integrity": "sha512-BMAlczRqC/LUt2P97E4apTBbkvS9JTJnp2DKFbCwpZ8vBvXVbNdqmvzW/OsdtI/+mGr+apkkpqGM8WecLkPgrA==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.12.tgz", + "integrity": "sha512-zU5MyluNsykf5cOJ0LZZZjgAHbhPJ1cWfdH1ZXVMXxVMhEV0VZiZXQdwBBVvmvbF28EizeK7obG9fs+fpmS0eQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.12.tgz", + "integrity": "sha512-zUZMep7YONnp6954QOOwEBwFX9svlKd3ov6PkxKd53LGTHsp/gy7vHaPGhhjBmEpqXEXShi6dddjIkmd+NgMsA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.12.tgz", + "integrity": "sha512-ohqLPc7i67yunArPj1+/FeeJ7AgwAjHqKZ512ADk3WsE3FHU9l+m5aa7NdxXr0HmN1bjDlUslBjWNbFlD9y12Q==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.12.tgz", + "integrity": "sha512-GIIHtQXqgeOOqdG16a/A9N28GpkvjJnjYMhOnXVbn3EDJcoItdR58v/pGN31CHjyXDc8uCcRnFWmqaJt24AYJg==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.12.tgz", + "integrity": "sha512-zK0b9a1/0wZY+6FdOS3BpZcPc1kcx2G5yxxfEJtEUzVxI6n/FrC2Phsxj/YblPuBchhBZ/1wwn7AyEBUyNSa6g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.12.tgz", + "integrity": "sha512-y75OijvrBE/1XRrXq1jtrJfG26eHeMoqLJ2dwQNwviwTuTtHGCojsDO6BJNF8gU+3jTn1KzJEMETytwsFSvc+Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.12.tgz", + "integrity": "sha512-JKgG8Q/LL/9sw/iHHxQyVMoQYu3rU3+a5Z87DxC+wAu3engz+EmctIrV+FGOgI6gWG1z1+5nDDbXiRMGQZXqiw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.12.tgz", + "integrity": "sha512-yoRIAqc0B4lDIAAEFEIu9ttTRFV84iuAl0KNCN6MhKLxNPfzwCBvEMgwco2f71GxmpBcTtn7KdErueZaM2rEvw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.12.tgz", + "integrity": "sha512-qYgt3dHPVvf/MgbIBpJ4Sup/yb9DAopZ3a2JgMpNKIHUpOdnJ2eHBo/aQdnd8dJ21X/+sS58wxHtA9lEazYtXQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.12.tgz", + "integrity": "sha512-wHphlMLK4ufNOONqukELfVIbnGQJrHJ/mxZMMrP2jYrPgCRZhOtf0kC4yAXBwnfmULimV1qt5UJJOw4Kh13Yfg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.12.tgz", + "integrity": "sha512-TeN//1Ft20ZZW41+zDSdOI/Os1bEq5dbvBvYkberB7PHABbRcsteeoNVZFlI0YLpGdlBqohEpjrn06kv8heCJg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.12.tgz", + "integrity": "sha512-AgUebVS4DoAblBgiB2ACQ/8l4eGE5aWBb8ZXtkXHiET9mbj7GuWt3OnsIW/zX+XHJt2RYJZctbQ2S/mDjbp0UA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.12.tgz", + "integrity": "sha512-dJ3Rb3Ei2u/ysSXd6pzleGtfDdc2MuzKt8qc6ls8vreP1G3B7HInX3i7gXS4BGeVd24pp0yqyS7bJ5NHaI9ing==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.12.tgz", + "integrity": "sha512-OrNJMGQbPaVyHHcDF8ybNSwu7TDOfX8NGpXCbetwOSP6txOJiWlgQnRymfC9ocR1S0Y5PW0Wb1mV6pUddqmvmQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.12.tgz", + "integrity": "sha512-55FzVCAiwE9FK8wWeCRuvjazNRJ1QqLCYGZVB6E8RuQuTeStSwotpSW4xoRGwp3a1wUsaVCdYcj5LGCASVJmMg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.12.tgz", + "integrity": "sha512-qnluf8rfb6Y5Lw2tirfK2quZOBbVqmwxut7GPCIJsM8lc4AEUj9L8y0YPdLaPK0TECt4IdyBdBD/KRFKorlK3g==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.12.tgz", + "integrity": "sha512-+RkKpVQR7bICjTOPUpkTBTaJ4TFqQBX5Ywyd/HSdDkQGn65VPkTsR/pL4AMvuMWy+wnXgIl4EY6q4mVpJal8Kg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.12.tgz", + "integrity": "sha512-GNHuciv0mFM7ouzsU0+AwY+7eV4Mgo5WnbhfDCQGtpvOtD1vbOiRjPYG6dhmMoFyBjj+pNqQu2X+7DKn0KQ/Gw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.12.tgz", + "integrity": "sha512-kR8cezhYipbbypGkaqCTWIeu4zID17gamC8YTPXYtcN3E5BhhtTnwKBn9I0PJur/T6UVwIEGYzkffNL0lFvxEw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.12.tgz", + "integrity": "sha512-O0UYQVkvfM/jO8a4OwoV0mAKSJw+mjWTAd1MJd/1FCX6uiMdLmMRPK/w6e9OQ0ob2WGxzIm9va/KG0Ja4zIOgg==", + "dev": true, + "optional": true + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -27129,6 +27223,15 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, + "@jest/schemas": { + "version": "29.6.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", + "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -27183,6 +27286,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@jspm/core": { + "version": "2.0.0-beta.24", + "resolved": "https://registry.npmjs.org/@jspm/core/-/core-2.0.0-beta.24.tgz", + "integrity": "sha512-a4Bo/80Z6CoJNor5ldgs6002utmmbttP4JYd/FJ0Ob2fVdf6O6ha5SORBCqrnDnBvMc1TlrHY7dCfat5+H0a6A==", + "dev": true + }, "@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -27984,6 +28093,12 @@ } } }, + "@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, "@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -28002,6 +28117,12 @@ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, + "@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, "@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -28069,8 +28190,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "peer": true + "dev": true }, "@trysound/sax": { "version": "0.2.0", @@ -28127,7 +28247,9 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@types/body-parser": { "version": "1.19.2", @@ -28159,6 +28281,21 @@ "@types/responselike": "*" } }, + "@types/chai": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", + "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "dev": true + }, + "@types/chai-subset": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", + "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, "@types/common-tags": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.1.tgz", @@ -28309,12 +28446,6 @@ "@types/node": "*" } }, - "@types/jasmine": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.3.0.tgz", - "integrity": "sha512-u1jWakf8CWvLfSEZyxmzkgBzOEvXH/szpT0e6G8BTkx5Eu0BhDn7sbc5dz0JBN/6Wwm9rBe+JAsk9tJRyH9ZkA==", - "dev": true - }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -28519,7 +28650,9 @@ "version": "0.7.36", "resolved": "https://registry.npmjs.org/@types/ua-parser-js/-/ua-parser-js-0.7.36.tgz", "integrity": "sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@types/unist": { "version": "2.0.6", @@ -28531,7 +28664,9 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@types/ws": { "version": "8.5.5", @@ -28548,6 +28683,7 @@ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", "dev": true, "optional": true, + "peer": true, "requires": { "@types/node": "*" } @@ -28820,11 +28956,93 @@ "resolve": "^1.10.0" } }, + "@vitest/browser": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-0.33.0.tgz", + "integrity": "sha512-lY7iEFqTAYsd2Dv8ej/my2ySomv38leWxudFnqI8McYFoF74U5r3vnw0+ke1JXk2NJOtMSQiGlV8yyIc7gON+w==", + "dev": true, + "requires": { + "modern-node-polyfills": "^0.1.3", + "sirv": "^2.0.3" + } + }, + "@vitest/expect": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.33.0.tgz", + "integrity": "sha512-sVNf+Gla3mhTCxNJx+wJLDPp/WcstOe0Ksqz4Vec51MmgMth/ia0MGFEkIZmVGeTL5HtjYR4Wl/ZxBxBXZJTzQ==", + "dev": true, + "requires": { + "@vitest/spy": "0.33.0", + "@vitest/utils": "0.33.0", + "chai": "^4.3.7" + } + }, + "@vitest/runner": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.33.0.tgz", + "integrity": "sha512-UPfACnmCB6HKRHTlcgCoBh6ppl6fDn+J/xR8dTufWiKt/74Y9bHci5CKB8tESSV82zKYtkBJo9whU3mNvfaisg==", + "dev": true, + "requires": { + "@vitest/utils": "0.33.0", + "p-limit": "^4.0.0", + "pathe": "^1.1.1" + }, + "dependencies": { + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } + } + }, + "@vitest/snapshot": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.33.0.tgz", + "integrity": "sha512-tJjrl//qAHbyHajpFvr8Wsk8DIOODEebTu7pgBrP07iOepR5jYkLFiqLq2Ltxv+r0uptUb4izv1J8XBOwKkVYA==", + "dev": true, + "requires": { + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "pretty-format": "^29.5.0" + } + }, + "@vitest/spy": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.33.0.tgz", + "integrity": "sha512-Kv+yZ4hnH1WdiAkPUQTpRxW8kGtH8VRTnus7ZTGovFYM1ZezJpvGtb9nPIjPnptHbsyIAxYZsEpVPYgtpjGnrg==", + "dev": true, + "requires": { + "tinyspy": "^2.1.1" + } + }, + "@vitest/utils": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.33.0.tgz", + "integrity": "sha512-pF1w22ic965sv+EN6uoePkAOTkAPWM03Ri/jXNyMIKBb/XHLDPfhLvf/Fa9g0YECevAIz56oVYXhodLvLQ/awA==", + "dev": true, + "requires": { + "diff-sequences": "^29.4.3", + "loupe": "^2.3.6", + "pretty-format": "^29.5.0" + } + }, "@wdio/config": { "version": "7.31.1", "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.31.1.tgz", "integrity": "sha512-WAfswbCatwiaDVqy6kfF/5T8/WS/US/SRhBGUFrfBuGMIe+RRoHgy7jURFWSvUIE7CNHj8yvs46fLUcxhXjzcQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/glob": "^8.1.0", "@wdio/logger": "7.26.0", @@ -28839,6 +29057,8 @@ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/minimatch": "^5.1.2", "@types/node": "*" @@ -28849,6 +29069,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -28859,6 +29081,8 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "optional": true, + "peer": true, "requires": { "balanced-match": "^1.0.0" } @@ -28868,6 +29092,8 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -28881,6 +29107,8 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "optional": true, + "peer": true, "requires": { "brace-expansion": "^2.0.1" } @@ -28900,6 +29128,8 @@ "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.26.0.tgz", "integrity": "sha512-kQj9s5JudAG9qB+zAAcYGPHVfATl2oqKgqj47yjehOQ1zzG33xmtL1ArFbQKWhDG32y1A8sN6b0pIqBEIwgg8Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "chalk": "^4.0.0", "loglevel": "^1.6.0", @@ -28912,6 +29142,8 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "optional": true, + "peer": true, "requires": { "color-convert": "^2.0.1" } @@ -28921,6 +29153,8 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "optional": true, + "peer": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -28931,6 +29165,8 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "color-name": "~1.1.4" } @@ -28939,19 +29175,25 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "optional": true, + "peer": true, "requires": { "has-flag": "^4.0.0" } @@ -28962,13 +29204,17 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.27.0.tgz", "integrity": "sha512-hT/U22R5i3HhwPjkaKAG0yd59eaOaZB0eibRj2+esCImkb5Y6rg8FirrlYRxIGFVBl0+xZV0jKHzR5+o097nvg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@wdio/repl": { "version": "7.30.2", "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.30.2.tgz", "integrity": "sha512-aW4nuMI+gbRmxmL4jMarBjuiQ+cFscr/8jHDt5hGx/gc/f7ifrZa4t6M5H8vFIKsvjUwl9lZRiVO4NVvvp6+cg==", "dev": true, + "optional": true, + "peer": true, "requires": { "@wdio/utils": "7.30.2" } @@ -28978,6 +29224,8 @@ "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.30.2.tgz", "integrity": "sha512-np7I+smszFUennbQKdzbMN/zUL3s3EZq9pCCUcTRjjs9TE4tnn0wfmGdoz2o7REYu6kn9NfFFJyVIM2VtBbKEA==", "dev": true, + "optional": true, + "peer": true, "requires": { "@wdio/logger": "7.26.0", "@wdio/types": "7.30.2", @@ -28989,6 +29237,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -29170,8 +29420,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true, - "peer": true + "dev": true }, "abortcontroller-polyfill": { "version": "1.7.5", @@ -29188,20 +29437,9 @@ } }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" - }, - "acorn-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", - "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", - "dev": true, - "peer": true, - "requires": { - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2" - } + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" }, "acorn-import-assertions": { "version": "1.9.0", @@ -29363,28 +29601,13 @@ "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==" }, - "archive-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", - "dev": true, - "requires": { - "file-type": "^4.2.0" - }, - "dependencies": { - "file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", - "dev": true - } - } - }, "archiver": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz", "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==", "dev": true, + "optional": true, + "peer": true, "requires": { "archiver-utils": "^2.1.0", "async": "^3.2.3", @@ -29399,13 +29622,17 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -29417,6 +29644,8 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -29432,6 +29661,8 @@ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", "dev": true, + "optional": true, + "peer": true, "requires": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -29542,6 +29773,12 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -29964,12 +30201,6 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, - "boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true - }, "boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", @@ -30080,33 +30311,13 @@ "ieee754": "^1.1.13" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "buffer-from": { "version": "1.1.2", @@ -30126,6 +30337,12 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" }, + "cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true + }, "cache-manager": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.11.1.tgz", @@ -30225,6 +30442,21 @@ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "dev": true }, + "chai": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -30300,6 +30532,12 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -30335,6 +30573,8 @@ "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "*", "escape-string-regexp": "^4.0.0", @@ -30346,7 +30586,9 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true + "dev": true, + "optional": true, + "peer": true } } }, @@ -30667,6 +30909,8 @@ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -30679,6 +30923,8 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -30763,65 +31009,6 @@ "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true - } - } - }, "connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -30919,13 +31106,17 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "crc32-stream": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", "dev": true, + "optional": true, + "peer": true, "requires": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -30936,6 +31127,8 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -31102,7 +31295,9 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "css-tree": { "version": "1.1.3", @@ -31124,7 +31319,9 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "css-what": { "version": "6.1.0", @@ -31211,7 +31408,6 @@ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", "dev": true, - "peer": true, "requires": { "rrweb-cssom": "^0.6.0" } @@ -31221,12 +31417,6 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", @@ -31246,7 +31436,6 @@ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", "dev": true, - "peer": true, "requires": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", @@ -31258,7 +31447,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dev": true, - "peer": true, "requires": { "punycode": "^2.3.0" } @@ -31267,15 +31455,13 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "peer": true + "dev": true }, "whatwg-url": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, - "peer": true, "requires": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" @@ -31288,12 +31474,6 @@ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" }, - "date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true - }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -31311,8 +31491,7 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true, - "peer": true + "dev": true }, "decode-named-character-reference": { "version": "1.0.2", @@ -31328,47 +31507,6 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, - "decompress": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", - "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", - "dev": true, - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "dependencies": { - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - } - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - } - } - }, "decompress-response": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", @@ -31384,117 +31522,13 @@ } } }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "dev": true, - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, - "dependencies": { - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - } - } - }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, - "dependencies": { - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true - } - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", - "dev": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - } + "type-detect": "^4.0.0" } }, "deep-equal": { @@ -31713,6 +31747,8 @@ "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.31.1.tgz", "integrity": "sha512-QU8rMSspKk3c/mX0uawIlRslwH7F+sdTGBZseXgAA5XIgqWbanCQdfHLvxcEzJJHRE5Gq6vGPJIAjq/z9Z4j/Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "^18.0.0", "@types/ua-parser-js": "^0.7.33", @@ -31734,6 +31770,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -31751,13 +31789,17 @@ "version": "1.0.35", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true + "dev": true, + "optional": true, + "peer": true } } }, @@ -31765,13 +31807,9 @@ "version": "0.0.1130274", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1130274.tgz", "integrity": "sha512-kIozBWajgsi1g0W8yzALI4ZdCp6KG1yWaq8NN1ehQM3zX6JRegLSzfexz7XT5eFjmq1RkpMYgeKmfi3GsHrCLw==", - "dev": true - }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "diff": { "version": "4.0.2", @@ -31779,6 +31817,12 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -31824,18 +31868,6 @@ "utila": "~0.4" } }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, "dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -31863,7 +31895,6 @@ "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", "dev": true, - "peer": true, "requires": { "webidl-conversions": "^7.0.0" }, @@ -31872,8 +31903,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "peer": true + "dev": true } } }, @@ -31922,235 +31952,6 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" }, - "download": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz", - "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==", - "dev": true, - "requires": { - "archive-type": "^4.0.0", - "content-disposition": "^0.5.2", - "decompress": "^4.2.1", - "ext-name": "^5.0.0", - "file-type": "^11.1.0", - "filenamify": "^3.0.0", - "get-stream": "^4.1.0", - "got": "^8.3.1", - "make-dir": "^2.1.0", - "p-event": "^2.1.0", - "pify": "^4.0.1" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", - "dev": true - }, - "cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==", - "dev": true, - "requires": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==", - "dev": true - } - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "file-type": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", - "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", - "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - } - } - }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", - "dev": true - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "keyv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", - "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - } - }, - "p-cancelable": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", - "dev": true - } - } - }, "duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -32166,6 +31967,8 @@ "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/which": "^1.3.2", "which": "^2.0.2" @@ -32273,12 +32076,6 @@ "ansi-colors": "^4.1.1" } }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, "entities": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", @@ -32398,12 +32195,6 @@ "next-tick": "^1.1.0" } }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", @@ -32439,6 +32230,176 @@ "es6-symbol": "^3.1.1" } }, + "esbuild": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.12.tgz", + "integrity": "sha512-XuOVLDdtsDslXStStduT41op21Ytmf4/BDS46aa3xPJ7X5h2eMWBF1oAe3QjUH3bDksocNXgzGUZ7XHIBya6Tg==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.18.12", + "@esbuild/android-arm64": "0.18.12", + "@esbuild/android-x64": "0.18.12", + "@esbuild/darwin-arm64": "0.18.12", + "@esbuild/darwin-x64": "0.18.12", + "@esbuild/freebsd-arm64": "0.18.12", + "@esbuild/freebsd-x64": "0.18.12", + "@esbuild/linux-arm": "0.18.12", + "@esbuild/linux-arm64": "0.18.12", + "@esbuild/linux-ia32": "0.18.12", + "@esbuild/linux-loong64": "0.18.12", + "@esbuild/linux-mips64el": "0.18.12", + "@esbuild/linux-ppc64": "0.18.12", + "@esbuild/linux-riscv64": "0.18.12", + "@esbuild/linux-s390x": "0.18.12", + "@esbuild/linux-x64": "0.18.12", + "@esbuild/netbsd-x64": "0.18.12", + "@esbuild/openbsd-x64": "0.18.12", + "@esbuild/sunos-x64": "0.18.12", + "@esbuild/win32-arm64": "0.18.12", + "@esbuild/win32-ia32": "0.18.12", + "@esbuild/win32-x64": "0.18.12" + } + }, + "esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "dev": true, + "optional": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -32459,36 +32420,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, - "escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "peer": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "peer": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "peer": true - } - } - }, "eslint": { "version": "8.42.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", @@ -33218,25 +33149,6 @@ } } }, - "ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "requires": { - "mime-db": "^1.28.0" - } - }, - "ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, - "requires": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" - } - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -33277,6 +33189,8 @@ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/yauzl": "^2.9.1", "debug": "^4.1.1", @@ -33289,6 +33203,8 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "optional": true, + "peer": true, "requires": { "pump": "^3.0.0" } @@ -33396,6 +33312,8 @@ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "optional": true, + "peer": true, "requires": { "pend": "~1.2.0" } @@ -33447,23 +33365,6 @@ "token-types": "^4.1.1" } }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true - }, - "filenamify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz", - "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==", - "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, "filesize": { "version": "8.0.7", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", @@ -33712,16 +33613,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -35096,6 +34987,12 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, "get-intrinsic": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", @@ -35178,47 +35075,6 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "global-agent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz", - "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==", - "dev": true, - "requires": { - "boolean": "^3.0.1", - "core-js": "^3.6.5", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, "global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", @@ -35267,15 +35123,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3" - } - }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -35431,26 +35278,11 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true - }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, "has-tostringtag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", @@ -35464,16 +35296,6 @@ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", @@ -35659,7 +35481,6 @@ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", "dev": true, - "peer": true, "requires": { "whatwg-encoding": "^2.0.0" } @@ -35669,12 +35490,6 @@ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, "html-loader": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-4.2.0.tgz", @@ -35763,7 +35578,6 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, - "peer": true, "requires": { "@tootallnate/once": "2", "agent-base": "6", @@ -36004,16 +35818,6 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "into-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==", - "dev": true, - "requires": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - } - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -36227,12 +36031,6 @@ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==" }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", - "dev": true - }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -36261,23 +36059,11 @@ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", - "dev": true - }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -36290,8 +36076,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "peer": true + "dev": true }, "is-promise": { "version": "2.2.2", @@ -36332,12 +36117,6 @@ "is-absolute-url": "^3.0.0" } }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true - }, "is-root": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", @@ -36479,12 +36258,6 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, - "isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -36514,89 +36287,6 @@ "semver": "^6.3.0" } }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "jasmine": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-4.4.0.tgz", - "integrity": "sha512-xrbOyYkkCvgduNw7CKktDtNb+BwwBv/zvQeHpTkbxqQ37AJL5V4sY3jHoMIJPP/hTc3QxLVwOyxc87AqA+kw5g==", - "dev": true, - "requires": { - "glob": "^7.1.6", - "jasmine-core": "^4.4.0" - } - }, - "jasmine-core": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.4.0.tgz", - "integrity": "sha512-+l482uImx5BVd6brJYlaHe2UwfKoZBqQfNp20ZmdNfsjGFTemGfqHLsXjKEW23w9R/m8WYeFc9JmIgjj6dUtAA==", - "dev": true - }, "javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -36654,20 +36344,16 @@ } }, "jsdom": { - "version": "21.1.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.2.tgz", - "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", + "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dev": true, - "peer": true, "requires": { "abab": "^2.0.6", - "acorn": "^8.8.2", - "acorn-globals": "^7.0.0", "cssstyle": "^3.0.0", "data-urls": "^4.0.0", "decimal.js": "^10.4.3", "domexception": "^4.0.0", - "escodegen": "^2.0.0", "form-data": "^4.0.0", "html-encoding-sniffer": "^3.0.0", "http-proxy-agent": "^5.0.0", @@ -36693,7 +36379,6 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, - "peer": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -36705,7 +36390,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", "dev": true, - "peer": true, "requires": { "punycode": "^2.3.0" } @@ -36714,15 +36398,13 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "peer": true + "dev": true }, "whatwg-url": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, - "peer": true, "requires": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" @@ -36766,17 +36448,17 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -36795,145 +36477,6 @@ "object.assign": "^4.1.3" } }, - "karma": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", - "integrity": "sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==", - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.4.1", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "karma-chrome-launcher": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", - "dev": true, - "requires": { - "which": "^1.2.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "karma-coverage": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.0.tgz", - "integrity": "sha512-gPVdoZBNDZ08UCzdMHHhEImKrw1+PAOQOIiffv1YsvxFhBjqvo/SVXNk4tqn1SYqX0BJZT6S/59zgxiBe+9OuA==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.1", - "istanbul-reports": "^3.0.5", - "minimatch": "^3.0.4" - } - }, - "karma-jasmine": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", - "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", - "dev": true, - "requires": { - "jasmine-core": "^4.1.0" - } - }, - "karma-jsdom-launcher": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/karma-jsdom-launcher/-/karma-jsdom-launcher-14.0.0.tgz", - "integrity": "sha512-GrZpJK9cdBo0C6YXZh0Sbq8D5NvdoTvRE9R/nhJzl0Tyfg7GI6iCU73ww264eqAZzy1mjCk/vj8sVA6ECacLlQ==", - "dev": true, - "requires": {} - }, - "karma-sauce-launcher": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/karma-sauce-launcher/-/karma-sauce-launcher-4.3.6.tgz", - "integrity": "sha512-Ej62q4mUPFktyAm8g0g8J5qhwEkXwdHrwtiV4pZjKNHNnSs+4qgDyzs3VkpOy3AmNTsTqQXUN/lpiy0tZpDJZQ==", - "dev": true, - "requires": { - "global-agent": "^2.1.12", - "saucelabs": "^7.2.2", - "webdriverio": "^7.31.1" - } - }, "keyv": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", @@ -36961,7 +36504,9 @@ "version": "0.30.0", "resolved": "https://registry.npmjs.org/ky/-/ky-0.30.0.tgz", "integrity": "sha512-X/u76z4JtDVq10u1JA5UQfatPxgPaVDMYTrgHyiTpGN2z4TMEJkIHsoSBBSg9SWZEIXTKsi9kHgiQ9o3Y/4yog==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "language-subtag-registry": { "version": "0.3.22", @@ -36999,6 +36544,8 @@ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, + "optional": true, + "peer": true, "requires": { "readable-stream": "^2.0.5" } @@ -37017,6 +36564,8 @@ "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", "dev": true, + "optional": true, + "peer": true, "requires": { "debug": "^2.6.9", "marky": "^1.2.2" @@ -37027,6 +36576,8 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "optional": true, + "peer": true, "requires": { "ms": "2.0.0" } @@ -37035,7 +36586,9 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "optional": true, + "peer": true } } }, @@ -37113,6 +36666,12 @@ "json5": "^2.1.2" } }, + "local-pkg": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", + "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "dev": true + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -37150,13 +36709,17 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "lodash.difference": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "lodash.every": { "version": "4.6.0", @@ -37167,7 +36730,9 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "lodash.flattendeep": { "version": "4.4.0", @@ -37188,13 +36753,17 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", "integrity": "sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "lodash.map": { "version": "4.6.0", @@ -37225,7 +36794,9 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "lodash.uniq": { "version": "4.5.0", @@ -37236,32 +36807,25 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true - }, - "log4js": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", - "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", "dev": true, - "requires": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.3" - } + "optional": true, + "peer": true }, "loglevel": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.1.tgz", "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "loglevel-plugin-prefix": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "longest-streak": { "version": "3.0.1", @@ -37277,6 +36841,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -37315,6 +36888,23 @@ "es5-ext": "~0.10.2" } }, + "magic-string": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + } + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -37359,24 +36949,9 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", - "dev": true - }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, - "requires": { - "escape-string-regexp": "^4.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - } - } + "optional": true, + "peer": true }, "md5-file": { "version": "5.0.0", @@ -38069,6 +37644,101 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, + "mlly": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz", + "integrity": "sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "pathe": "^1.1.1", + "pkg-types": "^1.0.3", + "ufo": "^1.1.2" + } + }, + "modern-node-polyfills": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/modern-node-polyfills/-/modern-node-polyfills-0.1.3.tgz", + "integrity": "sha512-/4dB85Sdkt9MjWwtpKnsNTYhh0+fqjFC4ZEgDP4B0e6kyzbGUnX4NDxTUCaVwRLVF9gcEDcRQjol8pn05B3TUQ==", + "dev": true, + "requires": { + "@jspm/core": "2.0.0-beta.24", + "@rollup/pluginutils": "^3.1.0", + "esbuild": "^0.14.54", + "local-pkg": "^0.4.3" + }, + "dependencies": { + "@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "dev": true, + "optional": true + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "dev": true, + "requires": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "peer": true, + "requires": { + "fsevents": "~2.3.2" + } + } + } + }, "moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -38080,6 +37750,12 @@ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true }, + "mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -38432,8 +38108,7 @@ "version": "2.2.5", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.5.tgz", "integrity": "sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==", - "dev": true, - "peer": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -38591,31 +38266,18 @@ "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz", "integrity": "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==" }, - "p-event": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", - "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", - "dev": true, - "requires": { - "p-timeout": "^2.0.1" - } - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" }, - "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==", - "dev": true - }, "p-iteration": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz", "integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "p-limit": { "version": "3.1.0", @@ -38661,15 +38323,6 @@ } } }, - "p-timeout": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", - "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -39019,6 +38672,18 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, + "pathe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", + "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, "peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", @@ -39028,7 +38693,9 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "periscopic": { "version": "3.0.4", @@ -39067,21 +38734,6 @@ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -39090,6 +38742,17 @@ "find-up": "^4.0.0" } }, + "pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "requires": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, "pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -39143,6 +38806,23 @@ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" }, + "playwright": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.36.0.tgz", + "integrity": "sha512-ODVOTp5WoRMxDJY3liMmC+wVNicc0cQB17gASvQ+zLBggVK9a2x3gdT5mbl7av+zomvtdirWOqqfD+O6qIrFgw==", + "dev": true, + "requires": { + "playwright-core": "1.36.0" + }, + "dependencies": { + "playwright-core": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.36.0.tgz", + "integrity": "sha512-7RTr8P6YJPAqB+8j5ATGHqD6LvLLM39sYVNsslh78g8QeLcBs5750c6+msjrHUwwGt+kEbczBj1XB22WMwn+WA==", + "dev": true + } + } + }, "playwright-core": { "version": "1.34.3", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.34.3.tgz", @@ -39150,9 +38830,9 @@ "dev": true }, "postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", + "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", "requires": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -39534,6 +39214,31 @@ "renderkid": "^2.0.4" } }, + "pretty-format": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", + "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } + } + }, "prism-react-renderer": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz", @@ -39618,7 +39323,9 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "pseudomap": { "version": "1.0.2", @@ -39629,8 +39336,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "peer": true + "dev": true }, "pump": { "version": "3.0.0", @@ -39659,6 +39365,8 @@ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.7.0.tgz", "integrity": "sha512-rXja4vcnAzFAP1OVLq/5dWNfwBGuzcOARJ6qGV7oAZhnLmVRU8G5MsdeQEAOy332ZhkIOnn9jp15R89LKHyp2Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "cross-fetch": "3.1.5", "debug": "4.3.4", @@ -39678,23 +39386,21 @@ "version": "0.0.981744", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.981744.tgz", "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", "dev": true, + "optional": true, + "peer": true, "requires": {} } } }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, "qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -39707,7 +39413,9 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "query-string": { "version": "6.14.1", @@ -39724,8 +39432,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true, - "peer": true + "dev": true }, "queue-microtask": { "version": "1.2.3", @@ -40120,6 +39827,8 @@ "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.2.tgz", "integrity": "sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==", "dev": true, + "optional": true, + "peer": true, "requires": { "minimatch": "^5.1.0" }, @@ -40129,6 +39838,8 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "optional": true, + "peer": true, "requires": { "balanced-match": "^1.0.0" } @@ -40138,6 +39849,8 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "dev": true, + "optional": true, + "peer": true, "requires": { "brace-expansion": "^2.0.1" } @@ -40524,6 +40237,8 @@ "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.2.tgz", "integrity": "sha512-HmgVS3j+FLrEDBTDYysPdPVF9/hioDMJ/otOiQDKqk77YfZeeLOj0qi34yObumcud1gBpk+wpBTEg4kMicD++A==", "dev": true, + "optional": true, + "peer": true, "requires": { "fast-deep-equal": "^2.0.1" }, @@ -40532,7 +40247,9 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "dev": true + "dev": true, + "optional": true, + "peer": true } } }, @@ -40579,17 +40296,13 @@ "integrity": "sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ==", "dev": true }, - "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, "rgb2hex": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "rimraf": { "version": "3.0.2", @@ -40599,34 +40312,20 @@ "glob": "^7.1.3" } }, - "roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "rollup": { + "version": "3.26.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.2.tgz", + "integrity": "sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==", "dev": true, "requires": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - } + "fsevents": "~2.3.2" } }, "rrweb-cssom": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true, - "peer": true + "dev": true }, "rss": { "version": "1.2.2", @@ -40787,85 +40486,6 @@ } } }, - "saucelabs": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-7.2.2.tgz", - "integrity": "sha512-rxbazYeKw0RDoXnGCfTeY6or9QM42Nn/LcZyO4Wi11h1d5k7EkoXU58g6FrYZgC7+UtI1t4CZu5Z1a2F/YQzvg==", - "dev": true, - "requires": { - "change-case": "^4.1.2", - "download": "^8.0.0", - "form-data": "^4.0.0", - "got": "^11.8.2", - "hash.js": "^1.1.7", - "query-string": "^7.0.1", - "tunnel": "^0.0.6", - "yargs": "^17.2.1" - }, - "dependencies": { - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } - } - }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -40877,7 +40497,6 @@ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, - "peer": true, "requires": { "xmlchars": "^2.2.0" } @@ -40941,23 +40560,6 @@ "kind-of": "^6.0.0" } }, - "seek-bzip": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", - "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", - "dev": true, - "requires": { - "commander": "^2.8.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -40978,12 +40580,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true - }, "semver-diff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", @@ -41049,23 +40645,6 @@ "upper-case-first": "^2.0.2" } }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "requires": { - "type-fest": "^0.13.1" - }, - "dependencies": { - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true - } - } - }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -41257,6 +40836,12 @@ "object-inspect": "^1.9.0" } }, + "siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -41297,6 +40882,17 @@ } } }, + "sirv": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", + "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", + "dev": true, + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -41403,24 +40999,6 @@ "websocket-driver": "^0.7.4" } }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", - "dev": true, - "requires": { - "sort-keys": "^1.0.0" - } - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -41590,6 +41168,12 @@ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" }, + "stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, "stackframe": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", @@ -41600,6 +41184,12 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "std-env": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz", + "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==", + "dev": true + }, "stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -41608,45 +41198,6 @@ "internal-slot": "^1.0.4" } }, - "streamroller": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", - "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", - "dev": true, - "requires": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, "streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -41781,15 +41332,6 @@ "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", "dev": true }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "dev": true, - "requires": { - "is-natural-number": "^4.0.1" - } - }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -41805,13 +41347,13 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, - "strip-outer": { + "strip-literal": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.0.1.tgz", + "integrity": "sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.2" + "acorn": "^8.8.2" } }, "strtok3": { @@ -41968,8 +41510,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "peer": true + "dev": true }, "table": { "version": "6.8.0", @@ -42042,33 +41583,6 @@ } } }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - }, - "dependencies": { - "bl": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", - "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - } - } - }, "term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", @@ -42174,12 +41688,6 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "devOptional": true }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", - "dev": true - }, "timers-ext": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", @@ -42189,6 +41697,24 @@ "next-tick": "1" } }, + "tinybench": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", + "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", + "dev": true + }, + "tinypool": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.6.0.tgz", + "integrity": "sha512-FdswUUo5SxRizcBc6b1GSuLpLjisa8N8qMyYoP3rl+bym+QauhtJP5bvZY1ytt8krKGmMLYIRl36HBZfeAoqhQ==", + "dev": true + }, + "tinyspy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz", + "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==", + "dev": true + }, "title-case": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", @@ -42205,12 +41731,6 @@ "rimraf": "^3.0.0" } }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -42243,12 +41763,17 @@ "ieee754": "^1.2.1" } }, + "totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true + }, "tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", "dev": true, - "peer": true, "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -42260,8 +41785,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "peer": true + "dev": true } } }, @@ -42282,15 +41806,6 @@ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "dev": true }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.2" - } - }, "trough": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", @@ -42467,12 +41982,6 @@ } } }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -42494,6 +42003,12 @@ "prelude-ls": "^1.2.1" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -42536,6 +42051,12 @@ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==" }, + "ufo": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.1.2.tgz", + "integrity": "sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==", + "dev": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -42552,6 +42073,8 @@ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", "dev": true, + "optional": true, + "peer": true, "requires": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -42892,7 +42415,6 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, - "peer": true, "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -42906,12 +42428,6 @@ "prepend-http": "^2.0.0" } }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", - "dev": true - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -43032,18 +42548,69 @@ "unist-util-stringify-position": "^3.0.0" } }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true + "vite": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.3.tgz", + "integrity": "sha512-IMnXQXXWgLi5brBQx/4WzDxdzW0X3pjO4nqFJAuNvwKtxzAmPzFE1wszW3VDpAGQJm3RZkm/brzRdyGsnwgJIA==", + "dev": true, + "requires": { + "esbuild": "^0.18.10", + "fsevents": "~2.3.2", + "postcss": "^8.4.25", + "rollup": "^3.25.2" + } + }, + "vite-node": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.33.0.tgz", + "integrity": "sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==", + "dev": true, + "requires": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "mlly": "^1.4.0", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^3.0.0 || ^4.0.0" + } + }, + "vitest": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.33.0.tgz", + "integrity": "sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==", + "dev": true, + "requires": { + "@types/chai": "^4.3.5", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "@vitest/expect": "0.33.0", + "@vitest/runner": "0.33.0", + "@vitest/snapshot": "0.33.0", + "@vitest/spy": "0.33.0", + "@vitest/utils": "0.33.0", + "acorn": "^8.9.0", + "acorn-walk": "^8.2.0", + "cac": "^6.7.14", + "chai": "^4.3.7", + "debug": "^4.3.4", + "local-pkg": "^0.4.3", + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.3.3", + "strip-literal": "^1.0.1", + "tinybench": "^2.5.0", + "tinypool": "^0.6.0", + "vite": "^3.0.0 || ^4.0.0", + "vite-node": "0.33.0", + "why-is-node-running": "^2.2.2" + } }, "w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, - "peer": true, "requires": { "xml-name-validator": "^4.0.0" } @@ -43081,6 +42648,8 @@ "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.31.1.tgz", "integrity": "sha512-nCdJLxRnYvOMFqTEX7sqQtF/hV/Jgov0Y6ICeOm1DMTlZSRRDaUsBMlEAPkEwif9uBJYdM0znv8qzfX358AGqQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "^18.0.0", "@wdio/config": "7.31.1", @@ -43098,6 +42667,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -43118,6 +42689,8 @@ "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.31.1.tgz", "integrity": "sha512-ri8L7A8VbJ2lZyndu0sG56d2zBot7SXdeI95Kni43e0pd/5Xm4IMAPdWB60yS8vqrP8goJU2iuQ8/ltry4IDbQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/aria-query": "^5.0.0", "@types/node": "^18.0.0", @@ -43153,6 +42726,8 @@ "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.30.2.tgz", "integrity": "sha512-uZ8o7FX8RyBsaXiOWa59UKTCHTtADNvOArYTcHNEIzt+rh4JdB/uwqfc8y4TCNA2kYm7PWaQpUFwpStLeg0H1Q==", "dev": true, + "optional": true, + "peer": true, "requires": { "@types/node": "^18.0.0", "got": "^11.8.1" @@ -43163,6 +42738,8 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "optional": true, + "peer": true, "requires": { "balanced-match": "^1.0.0" } @@ -43172,6 +42749,8 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -43183,6 +42762,8 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", "dev": true, + "optional": true, + "peer": true, "requires": { "brace-expansion": "^2.0.1" } @@ -43192,6 +42773,8 @@ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "type-fest": "^0.20.2" } @@ -43462,7 +43045,6 @@ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", "dev": true, - "peer": true, "requires": { "iconv-lite": "0.6.3" }, @@ -43472,7 +43054,6 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "peer": true, "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } @@ -43483,8 +43064,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, - "peer": true + "dev": true }, "whatwg-url": { "version": "5.0.0", @@ -43544,6 +43124,16 @@ "is-typed-array": "^1.1.10" } }, + "why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "requires": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + } + }, "widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", @@ -43633,8 +43223,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, - "peer": true + "dev": true }, "xml2js": { "version": "0.4.17", @@ -43659,8 +43248,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "peer": true + "dev": true }, "xmlhttprequest-ssl": { "version": "2.0.0", @@ -43762,6 +43350,8 @@ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "optional": true, + "peer": true, "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" @@ -43818,6 +43408,8 @@ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", "dev": true, + "optional": true, + "peer": true, "requires": { "archiver-utils": "^2.1.0", "compress-commons": "^4.1.0", @@ -43829,6 +43421,8 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, + "optional": true, + "peer": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", diff --git a/package.json b/package.json index 3fc095653e..1a599f2ecf 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "ports": { "proxy": "9000", "gatsby": "4000", - "karma": "9876", "webpack": "9080" } }, @@ -29,7 +28,6 @@ "@babel/preset-env": "^7.22.5", "@babel/preset-typescript": "^7.22.5", "@playwright/test": "^1.34.3", - "@types/jasmine": "^4.3.0", "@types/lodash.clonedeep": "^4.5.7", "@typescript-eslint/eslint-plugin": "^5.59.8", "@typescript-eslint/parser": "^5.59.8", @@ -46,14 +44,7 @@ "highlight.js": "^9.18.1", "html-loader": "^4.2.0", "http-proxy": "^1.18.0", - "jasmine": "^4.4.0", - "jasmine-core": "^4.4.0", - "karma": "^6.4.2", - "karma-chrome-launcher": "^3.2.0", - "karma-coverage": "^2.2.0", - "karma-jasmine": "^5.1.0", - "karma-jsdom-launcher": "^14.0.0", - "karma-sauce-launcher": "^4.3.6", + "jsdom": "^22.1.0", "lodash": "^4.17.15", "mini-css-extract-plugin": "^2.7.6", "npm-run-all": "^4.1.5", @@ -99,20 +90,14 @@ "start": "USE_LOCAL_FILE=true run-p start:*", "start:webpack": "webpack-dev-server --config _develop/webpack.config.js", "start:website": "run-s website:build website:serve", - "start:karma": "karma start _develop/karma.unit.config.js --no-single-run --no-browsers", "start:proxy": "node _develop/proxy.js", "website:build": "npm run build -w website", "website:serve": "npm run serve -w website -- --port $npm_package_config_ports_gatsby", "website:develop": "npm run develop -w website -- --port $npm_package_config_ports_gatsby", - "test": "npm run test:unit; npm run test:fuzz; npm run test:e2e", - "test:unit": "npm run build; karma start _develop/karma.unit.config.js", - "test:fuzz": "npm run build; karma start _develop/karma.fuzz.config.js", - "test:e2e": "npx playwright test", - "test:coverage": "webpack --env.coverage --config _develop/webpack.config.js; karma start _develop/karma.unit.config.js --reporters coverage" - }, - "overrides": { - "saucelabs": "^7.2.2", - "webdriverio": "^7.31.1" + "test": "run-s test:*", + "test:unit": "vitest --config test/unit/vitest.config.ts", + "test:fuzz": "vitest --config test/fuzz/vitest.config.ts", + "test:e2e": "playwright test" }, "keywords": [ "editor", From 9913126e18c3cd4ee420508790ae1fde12bcd652 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:29:55 +0800 Subject: [PATCH 13/18] Update development document --- .github/DEVELOPMENT.md | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/DEVELOPMENT.md b/.github/DEVELOPMENT.md index f5de8de5fc..7eb6a298ee 100644 --- a/.github/DEVELOPMENT.md +++ b/.github/DEVELOPMENT.md @@ -1,27 +1,25 @@ # Development -Quill's source is in [ES6](http://www.ecma-international.org/ecma-262/6.0/index.html) and utilizes [Webpack](https://webpack.github.io/) to organize its files. The documentation site (hosted at [quilljs.com](https://quilljs.com/)) is built with [Jekyll](http://jekyllrb.com/). [Karma](https://karma-runner.github.io/) and [Protractor](https://angular.github.io/protractor/) are used for testing. +Quill's source is in [ES6](http://www.ecma-international.org/ecma-262/6.0/index.html) and utilizes [Webpack](https://webpack.github.io/) to organize its files. The documentation site (hosted at [quilljs.com](https://quilljs.com/)) is built with [Gatsby](https://www.gatsbyjs.com/). [Vitest](https://vitest.dev/) and [Playwright](https://playwright.dev/) are used for testing. To develop Quill locally, you will want a copy of Quill's codebase, with the build pipeline and documentation site running locally. The documentation site lives in `doc/` but will use your local build instead of the CDN that the public site uses. This allows you to test changes on a local copy of all of the quilljs.com demos, such as the [standalone examples](https://github.com/quilljs/quill/blob/develop/docs/docs/standalone). - ### Setup -The local development environment requires both Node.js and Ruby, along with their respective package managers. RVM and NVM are good solutions for installing and keeping Node.js and Ruby up to date. Mac users may need to also `xcode-select --install` to build nokogiri. +The local development environment requires Node.js. -After installing Node.js, npm, Ruby, and bundler: +After installing Node.js: npm install - bundle install npm run build You can now try out the unit test suite by running: npm run test:unit -Karma also provides a local server so you can just visit a url from any browser to run the test suite, instead of launching one from the command line. Webpack also provides a server to dynamically build and serve the latest copy of the source code. Jekyll does the same for the documentation site. +Webpack provides a server to dynamically build and serve the latest copy of the source code. Gatsby does the same for the documentation site. -With three independent servers, it is useful to have a proxy to as a front end single point of access to jekyll, karma and webpack. The documentation site is normally set up to fetch Quill from Quill's CDN, but the local proxy will serve a local build from webpack dev server instead. +With two independent servers, it is useful to have a proxy to as a front end single point of access to Gatsby and Webpack. The documentation site is normally set up to fetch Quill from Quill's CDN, but the local proxy will serve a local build from webpack dev server instead. All four services can be run with a single command thanks to [foreman](http://ddollar.github.io/foreman/): @@ -35,10 +33,8 @@ Once the terminal settles (with messages indicating success from `jekyll`, `karm | Standalone Editor (Full) | [localhost:9000/standalone/full](http://localhost:9000/standalone/full/) | | Standalone Editor (Snow) | [localhost:9000/standalone/snow](http://localhost:9000/standalone/snow/) | | Standalone Editor (Bubble) | [localhost:9000/standalone/bubble](http://localhost:9000/standalone/bubble/) | -| Karma Test Runner | [localhost:9000/karma](http://localhost:9000/karma) | | Webpack Locally Hosted Build | [localhost:9080](http://localhost:9080) | - ### Testing While Quill features an extensive javascript test suite, which you can run with: @@ -53,12 +49,11 @@ Once webdriver is installed, you can run the test suite with npm run test:functional - ### Workflow A standard development workflow involves: 1. `npm start` - to run development services 2. [localhost:9000/standalone/snow](http://localhost:9000/standalone/snow/) - to interactively develop and test an isolated example -3. [localhost:9000/karma/debug.html](http://localhost:9000/karma/debug.html) - to run unit tests +3. `npm run test:unit` - to run unit tests 4. If everything is working, run the webdriver tests. From b83e57243c165024f1b8105eef8baa21c8276ac4 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:39:08 +0800 Subject: [PATCH 14/18] Style fixes --- test/fuzz/tableEmbed.spec.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/fuzz/tableEmbed.spec.ts b/test/fuzz/tableEmbed.spec.ts index 1411311864..6e3091fac7 100644 --- a/test/fuzz/tableEmbed.spec.ts +++ b/test/fuzz/tableEmbed.spec.ts @@ -5,8 +5,7 @@ import TableEmbed, { TableRowColumnOp, } from '../../modules/tableEmbed'; import { choose, randomInt } from './__helpers__/utils'; -import { describe, expect, test } from 'vitest'; -import { beforeAll } from 'vitest'; +import { beforeAll, describe, expect, test } from 'vitest'; const getRandomRowColumnId = () => { const characters = 'abcdefghijklmnopqrstuvwxyz0123456789'; From e3a89ba6660506674429db07d8c7d7484a99c7fd Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:48:03 +0800 Subject: [PATCH 15/18] Add retries for unit tests --- test/unit/vitest.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/vitest.config.ts b/test/unit/vitest.config.ts index 02bd8f543a..440ba72d40 100644 --- a/test/unit/vitest.config.ts +++ b/test/unit/vitest.config.ts @@ -10,6 +10,7 @@ export default defineConfig({ 'test/unit/__helpers__/expect.ts', 'test/unit/__helpers__/cleanup.ts', ], + retry: 3, browser: { enabled: true, provider: 'playwright', From 245c4522238de38d0bd9205c2f0ff8289f13fc43 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 15:56:22 +0800 Subject: [PATCH 16/18] Fix syntax imports --- test/unit/modules/syntax.spec.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/unit/modules/syntax.spec.ts b/test/unit/modules/syntax.spec.ts index db5f07ac36..cb05a0730b 100644 --- a/test/unit/modules/syntax.spec.ts +++ b/test/unit/modules/syntax.spec.ts @@ -1,12 +1,11 @@ import hljs from 'highlight.js'; import Delta from 'quill-delta'; -import Quill from '../../../core'; -import BoldBlot from '../../../formats/bold'; -import Syntax, { CodeToken, CodeBlock } from '../../../modules/syntax'; import { afterAll, beforeAll, describe, expect, test } from 'vitest'; -import { normalizeHTML, sleep } from '../__helpers__/utils'; -import { createRegistry } from '../__helpers__/factory'; +import Quill from '../../../core'; import Bold from '../../../formats/bold'; +import Syntax, { CodeBlock, CodeToken } from '../../../modules/syntax'; +import { createRegistry } from '../__helpers__/factory'; +import { normalizeHTML, sleep } from '../__helpers__/utils'; const HIGHLIGHT_INTERVAL = 10; @@ -221,7 +220,7 @@ describe('Syntax', () => { describe('allowedChildren', () => { beforeAll(() => { - CodeBlock.allowedChildren.push(BoldBlot); + CodeBlock.allowedChildren.push(Bold); }); afterAll(() => { From 26d42e7c353b9a60c8f85ceee23a0f93e0074f4d Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 16:16:18 +0800 Subject: [PATCH 17/18] Move retries to GitHub actions --- .github/workflows/_unit.yml | 2 +- test/unit/vitest.config.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/_unit.yml b/.github/workflows/_unit.yml index 091d733db9..f0c377aea5 100644 --- a/.github/workflows/_unit.yml +++ b/.github/workflows/_unit.yml @@ -22,6 +22,6 @@ jobs: - run: npm ci - run: npx playwright install --with-deps - run: npm run lint - - run: npm run test:unit + - run: npm run test:unit || npm run test:unit || npm run test:unit env: BROWSER: ${{ matrix.browser }} diff --git a/test/unit/vitest.config.ts b/test/unit/vitest.config.ts index 440ba72d40..02bd8f543a 100644 --- a/test/unit/vitest.config.ts +++ b/test/unit/vitest.config.ts @@ -10,7 +10,6 @@ export default defineConfig({ 'test/unit/__helpers__/expect.ts', 'test/unit/__helpers__/cleanup.ts', ], - retry: 3, browser: { enabled: true, provider: 'playwright', From 1dea4bdde212733495170ddb86cf250f95879744 Mon Sep 17 00:00:00 2001 From: Zihua Li Date: Sat, 15 Jul 2023 17:42:22 +0800 Subject: [PATCH 18/18] Use custom matcher instead of snapshot --- test/unit/__helpers__/expect.ts | 103 ++-------------------------- test/unit/core/selection.spec.ts | 44 ++++++------ test/unit/formats/align.spec.ts | 8 +-- test/unit/formats/bold.spec.ts | 2 +- test/unit/formats/code.spec.ts | 32 ++++----- test/unit/formats/color.spec.ts | 8 +-- test/unit/formats/header.spec.ts | 6 +- test/unit/formats/indent.spec.ts | 4 +- test/unit/formats/link.spec.ts | 8 +-- test/unit/formats/list.spec.ts | 44 ++++++------ test/unit/formats/script.spec.ts | 6 +- test/unit/formats/table.spec.ts | 28 ++++---- test/unit/modules/clipboard.spec.ts | 12 ++-- 13 files changed, 104 insertions(+), 201 deletions(-) diff --git a/test/unit/__helpers__/expect.ts b/test/unit/__helpers__/expect.ts index d9303c176e..60df803b4e 100644 --- a/test/unit/__helpers__/expect.ts +++ b/test/unit/__helpers__/expect.ts @@ -1,104 +1,6 @@ import { expect } from 'vitest'; -import Cursor from '../../../blots/cursor'; -import { Blot, ContainerBlot, ScrollBlot } from 'parchment'; import { normalizeHTML } from './utils'; -expect.addSnapshotSerializer({ - serialize(val) { - return val.outerHTML.replace(Cursor.CONTENTS, '{Cursor.CONTENTS}'); - }, - test(val) { - return val instanceof HTMLElement && val.classList.contains('ql-cursor'); - }, -}); - -expect.addSnapshotSerializer({ - serialize() { - return ''; - }, - test(val) { - return val instanceof HTMLElement && val.classList.contains('ql-ui'); - }, -}); - -interface Config { - indent: string; - min: boolean; - spacingOuter: string; - spacingInner: string; -} - -const printBlot = ( - blot: Blot, - config: Config, - indentation: string, - depth: number, - refs: unknown, - printer: ( - value: unknown, - config: Config, - indentation: string, - depth: number, - refs: unknown, - ) => string, -) => { - const isScroll = blot instanceof ScrollBlot; - if (isScroll || blot instanceof ContainerBlot) { - const html = printer( - blot.domNode, - { - ...config, - min: true, - indent: '', - spacingOuter: '', - spacingInner: ' ', - }, - '', - depth, - refs, - ); - const childNodes = blot.children - .map(child => { - return ( - indentation + - printBlot( - child, - config, - indentation + config.indent, - depth, - refs, - printer, - ) - ); - }) - .join('\n'); - - if (isScroll) return childNodes; - const openTag = html.slice(0, html.indexOf('>') + 1); - const endTag = html.slice(html.lastIndexOf('<')); - - return `${openTag}\n${childNodes}\n${indentation.slice( - config.indent.length, - )}${endTag}`; - } - return printer( - blot.domNode, - { ...config, min: true, indent: '', spacingInner: ' ', spacingOuter: '' }, - '', - depth, - refs, - ); -}; - -expect.addSnapshotSerializer({ - serialize(val, config, indentation, depth, refs, printer) { - return printBlot(val, config, indentation, depth, refs, printer); - }, - test(blot) { - return typeof blot === 'object' && 'statics' in blot; - }, -}); - const sortAttributes = (element: HTMLElement) => { const attributes = Array.from(element.attributes); const sortedAttributes = attributes.sort((a, b) => @@ -152,7 +54,10 @@ expect.extend({ return { pass: false, message: () => - `expected ${receivedDOM.innerHTML} to match html ${expectedDOM.innerHTML}`, + `HTMLs don't match.\n${this.utils.diff( + this.utils.stringify(receivedDOM), + this.utils.stringify(expectedDOM), + )}`, }; }, }); diff --git a/test/unit/core/selection.spec.ts b/test/unit/core/selection.spec.ts index 0d8ead50be..2b9fb5cdee 100644 --- a/test/unit/core/selection.spec.ts +++ b/test/unit/core/selection.spec.ts @@ -343,8 +343,8 @@ describe('Selection', () => { selection.setRange(new Range(4)); selection.format('bold', true); expect(selection.getRange()[0]?.index).toEqual(4); - expect(selection.scroll).toMatchInlineSnapshot(` -

          0123{Cursor.CONTENTS}

          + expect(selection.root).toEqualHTML(` +

          0123${Cursor.CONTENTS}

          `); }); @@ -354,8 +354,8 @@ describe('Selection', () => { selection.format('bold', true); expect(selection.getRange()[0]?.index).toEqual(2); - expect(selection.scroll).toMatchInlineSnapshot(` -

          01{Cursor.CONTENTS}23

          + expect(selection.root).toEqualHTML(` +

          01${Cursor.CONTENTS}23

          `); }); @@ -364,8 +364,8 @@ describe('Selection', () => { selection.setRange(new Range(1)); selection.format('underline', true); expect(selection.getRange()[0]?.index).toEqual(1); - expect(selection.scroll).toMatchInlineSnapshot(` -

          0{Cursor.CONTENTS}1

          + expect(selection.root).toEqualHTML(` +

          0${Cursor.CONTENTS}1

          `); }); @@ -374,8 +374,8 @@ describe('Selection', () => { selection.setRange(new Range(0)); selection.format('bold', true); expect(selection.getRange()[0]?.index).toEqual(0); - expect(selection.scroll).toMatchInlineSnapshot(` -

          {Cursor.CONTENTS}

          + expect(selection.root).toEqualHTML(` +

          ${Cursor.CONTENTS}

          `); }); @@ -396,8 +396,8 @@ describe('Selection', () => { selection.format('underline', true); selection.format('background', 'blue'); expect(selection.getRange()[0]?.index).toEqual(2); - expect(selection.scroll).toMatchInlineSnapshot(` -

          01{Cursor.CONTENTS}23

          + expect(selection.root).toEqualHTML(` +

          01${Cursor.CONTENTS}23

          `); }); @@ -408,8 +408,8 @@ describe('Selection', () => { selection.format('underline', true); selection.format('italic', false); expect(selection.getRange()[0]?.index).toEqual(2); - expect(selection.scroll).toMatchInlineSnapshot(` -

          01{Cursor.CONTENTS}23

          + expect(selection.root).toEqualHTML(` +

          01${Cursor.CONTENTS}23

          `); }); @@ -419,7 +419,7 @@ describe('Selection', () => { selection.format('italic', true); selection.setRange(new Range(0, 0)); selection.scroll.update(); - expect(selection.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(selection.root).toEqualHTML('

          0123

          '); }); test('text change cleanup', () => { @@ -429,7 +429,7 @@ describe('Selection', () => { selection.cursor.textNode.data = `${Cursor.CONTENTS}|`; selection.setNativeRange(selection.cursor.textNode, 2); selection.scroll.update(); - expect(selection.scroll).toMatchInlineSnapshot('

          01|23

          '); + expect(selection.root).toEqualHTML('

          01|23

          '); }); test('no cleanup', () => { @@ -439,8 +439,8 @@ describe('Selection', () => { selection.root.removeChild(selection.root.lastChild as Node); selection.scroll.update(); expect(selection.getRange()[0]?.index).toEqual(2); - expect(selection.scroll).toMatchInlineSnapshot(` -

          01{Cursor.CONTENTS}23

          + expect(selection.root).toEqualHTML(` +

          01${Cursor.CONTENTS}23

          `); }); @@ -451,8 +451,8 @@ describe('Selection', () => { ); selection.setRange(new Range(4)); selection.format('bold', false); - expect(selection.scroll).toMatchInlineSnapshot(` -

          link{Cursor.CONTENTS}

          + expect(selection.root).toEqualHTML(` +

          link${Cursor.CONTENTS}


          `); }); @@ -463,8 +463,8 @@ describe('Selection', () => { ); selection.setRange(new Range(4)); selection.format('italic', false); - expect(selection.scroll).toMatchInlineSnapshot(` -

          bold{Cursor.CONTENTS}

          + expect(selection.root).toEqualHTML(` +

          bold${Cursor.CONTENTS}


          `); }); @@ -475,8 +475,8 @@ describe('Selection', () => { ); selection.setRange(new Range(4)); selection.format('link', 'https://example.com'); - expect(selection.scroll).toMatchInlineSnapshot(` -

          bold{Cursor.CONTENTS}

          + expect(selection.root).toEqualHTML(` +

          bold${Cursor.CONTENTS}


          `); }); diff --git a/test/unit/formats/align.spec.ts b/test/unit/formats/align.spec.ts index 5d399ae34e..67ee2cf5c4 100644 --- a/test/unit/formats/align.spec.ts +++ b/test/unit/formats/align.spec.ts @@ -17,7 +17,7 @@ describe('Align', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { align: 'center' }), ); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

          0123

          ', ); }); @@ -28,7 +28,7 @@ describe('Align', () => { ); editor.formatText(4, 1, { align: false }); expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); test('whitelist', () => { @@ -39,7 +39,7 @@ describe('Align', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { align: 'center' }), ); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

          0123

          ', ); }); @@ -48,6 +48,6 @@ describe('Align', () => { const editor = new Editor(createScroll('

          0123

          ')); editor.formatText(1, 2, { align: 'center' }); expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); }); diff --git a/test/unit/formats/bold.spec.ts b/test/unit/formats/bold.spec.ts index 0bd8e14773..59657a7edb 100644 --- a/test/unit/formats/bold.spec.ts +++ b/test/unit/formats/bold.spec.ts @@ -18,6 +18,6 @@ describe('Bold', () => { scroll.domNode.firstChild.lastChild, ); scroll.update(); - expect(scroll).toMatchInlineSnapshot('

          abc

          '); + expect(scroll.domNode).toEqualHTML('

          abc

          '); }); }); diff --git a/test/unit/formats/code.spec.ts b/test/unit/formats/code.spec.ts index 1863c2a2b3..d4ed2a7cfa 100644 --- a/test/unit/formats/code.spec.ts +++ b/test/unit/formats/code.spec.ts @@ -19,7 +19,7 @@ describe('Code', () => { test('format newline', () => { const editor = new Editor(createScroll('


          ')); editor.formatLine(0, 1, { 'code-block': true }); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`

          @@ -36,7 +36,7 @@ describe('Code', () => { .insert('5678') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          0123
          5678
          @@ -52,7 +52,7 @@ describe('Code', () => { ); editor.formatText(4, 1, { 'code-block': false }); expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); test('delete last', () => { @@ -68,7 +68,7 @@ describe('Code', () => { .insert('\n', { 'code-block': true }) .insert('5678\n'), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          0123
          @@ -86,7 +86,7 @@ describe('Code', () => { expect(editor.getDelta()).toEqual( new Delta().insert('01234567').insert('\n', { 'code-block': true }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          01234567
          @@ -103,7 +103,7 @@ describe('Code', () => { expect(editor.getDelta()).toEqual( new Delta().insert('01234567').insert('\n', { header: 1 }), ); - expect(editor.scroll).toMatchInlineSnapshot('

          01234567

          '); + expect(editor.scroll.domNode).toEqualHTML('

          01234567

          '); }); test('delete across before partial merge', () => { @@ -127,7 +127,7 @@ describe('Code', () => { .insert('60') .insert('\n', { header: 1 }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          01
          34
          @@ -154,7 +154,7 @@ describe('Code', () => { .insert('89') .insert('\n', { header: 1 }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          01
          @@ -180,7 +180,7 @@ describe('Code', () => { .insert('89') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          016
          89
          @@ -198,7 +198,7 @@ describe('Code', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { header: 1 }), ); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); test('replace multiple', () => { @@ -220,7 +220,7 @@ describe('Code', () => { .insert('23') .insert('\n', { header: 1 }), ); - expect(editor.scroll).toMatchInlineSnapshot('

          01

          \n

          23

          '); + expect(editor.scroll.domNode).toEqualHTML('

          01

          \n

          23

          '); }); test('format imprecise bounds', () => { @@ -245,7 +245,7 @@ describe('Code', () => { .insert('45') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`

          01

          23

          @@ -276,7 +276,7 @@ describe('Code', () => { .insert('45') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          01
          23
          @@ -307,7 +307,7 @@ describe('Code', () => { .insert('45') .insert('\n', { 'code-block': true }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          01
          @@ -328,7 +328,7 @@ describe('Code', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { 'code-block': true }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          0123
          @@ -351,7 +351,7 @@ describe('Code', () => { .delete(1) .retain(1, { 'code-block': null }); editor.applyDelta(delta); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          a
          b
          diff --git a/test/unit/formats/color.spec.ts b/test/unit/formats/color.spec.ts index b376d5e662..79422422d1 100644 --- a/test/unit/formats/color.spec.ts +++ b/test/unit/formats/color.spec.ts @@ -18,7 +18,7 @@ describe('Color', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0').insert('12', { color: 'red' }).insert('3\n'), ); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

          0123

          ', ); }); @@ -33,7 +33,7 @@ describe('Color', () => { .insert('12', { bold: true }) .insert('3\n'); expect(editor.getDelta()).toEqual(delta); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); test('remove unwrap', () => { @@ -42,13 +42,13 @@ describe('Color', () => { ); editor.formatText(1, 2, { color: false }); expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); test('invalid scope', () => { const editor = new Editor(createScroll('

          0123

          ')); editor.formatText(4, 1, { color: 'red' }); expect(editor.getDelta()).toEqual(new Delta().insert('0123\n')); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); }); diff --git a/test/unit/formats/header.spec.ts b/test/unit/formats/header.spec.ts index 541b7f42c4..c4f3018021 100644 --- a/test/unit/formats/header.spec.ts +++ b/test/unit/formats/header.spec.ts @@ -18,7 +18,7 @@ describe('Header', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123', { italic: true }).insert('\n', { header: 1 }), ); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); test('remove', () => { @@ -27,7 +27,7 @@ describe('Header', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123', { italic: true }).insert('\n'), ); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); test('change', () => { @@ -36,6 +36,6 @@ describe('Header', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123', { italic: true }).insert('\n', { header: 2 }), ); - expect(editor.scroll).toMatchInlineSnapshot('

          0123

          '); + expect(editor.scroll.domNode).toEqualHTML('

          0123

          '); }); }); diff --git a/test/unit/formats/indent.spec.ts b/test/unit/formats/indent.spec.ts index c862092422..18de866811 100644 --- a/test/unit/formats/indent.spec.ts +++ b/test/unit/formats/indent.spec.ts @@ -20,7 +20,7 @@ describe('Indent', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { list: 'bullet', indent: 1 }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          1. 0123
          @@ -37,7 +37,7 @@ describe('Indent', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { list: 'bullet' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
          1. 0123
          diff --git a/test/unit/formats/link.spec.ts b/test/unit/formats/link.spec.ts index b584bf481a..f1a5580cdc 100644 --- a/test/unit/formats/link.spec.ts +++ b/test/unit/formats/link.spec.ts @@ -21,7 +21,7 @@ describe('Link', () => { .insert('12', { link: 'https://quilljs.com' }) .insert('3\n'), ); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

          0123

          ', ); }); @@ -46,7 +46,7 @@ describe('Link', () => { .insert('12', { link: Link.SANITIZED_URL }) .insert('3\n'), ); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

          0123

          ', ); }); @@ -64,7 +64,7 @@ describe('Link', () => { .insert('12', { link: 'https://quilljs.com' }) .insert('3\n'), ); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

          0123

          ', ); }); @@ -81,7 +81,7 @@ describe('Link', () => { .insert('12', { size: 'large' }) .insert('3\n'); expect(editor.getDelta()).toEqual(delta); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

          0123

          ', ); }); diff --git a/test/unit/formats/list.spec.ts b/test/unit/formats/list.spec.ts index 391f2240c2..1f0b9c5c79 100644 --- a/test/unit/formats/list.spec.ts +++ b/test/unit/formats/list.spec.ts @@ -31,7 +31,7 @@ describe('List', () => { .insert('\n', { list: 'ordered' }) .insert('0123\n'), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`

          0123

          1. 5678
          2. @@ -61,7 +61,7 @@ describe('List', () => { .insert('\n', { list: 'unchecked' }) .insert('0123\n'), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
            1. 0123
            2. 5678
            3. @@ -82,7 +82,7 @@ describe('List', () => { ); editor.formatText(9, 1, { list: null }); expect(editor.getDelta()).toEqual(new Delta().insert('0123\n5678\n0123\n')); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`

              0123

              5678

              0123

              @@ -106,7 +106,7 @@ describe('List', () => { .insert('\n', { list: 'bullet' }) .insert('0123\n'), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`

              0123

              1. 5678
              2. @@ -129,7 +129,7 @@ describe('List', () => { expect(editor.getDelta()).toEqual( new Delta().insert('0123').insert('\n', { list: 'bullet' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                1. 0123
                @@ -148,7 +148,7 @@ describe('List', () => { .insert('0123') .insert('\n', { align: 'center', list: 'bullet' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                1. 0123
                @@ -175,7 +175,7 @@ describe('List', () => { .insert('0123') .insert('\n', { list: 'ordered' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                1. 0123
                2. 5678
                3. @@ -201,7 +201,7 @@ describe('List', () => { .insert('0123') .insert('\n', { list: 'ordered' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                  1. 0123
                  2. 0123
                  3. @@ -229,7 +229,7 @@ describe('List', () => { .insert('0123') .insert('\n', { list: 'checked' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                    1. 0123
                    2. 5678
                    3. @@ -243,13 +243,13 @@ describe('List', () => { createScroll('

                      '), ); editor.insertText(0, 'Test'); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                      1. Test
                      `); editor.deleteText(0, 4); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`

                      @@ -268,7 +268,7 @@ describe('List', () => { ), ); editor.deleteText(2, 5); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                      1. 0178
                      2. 0123
                      3. @@ -285,7 +285,7 @@ describe('List', () => { ), ); editor.deleteText(2, 5); - expect(editor.scroll).toMatchInlineSnapshot('

                        0178

                        '); + expect(editor.scroll.domNode).toEqualHTML('

                        0178

                        '); }); test('delete partial', () => { @@ -293,7 +293,7 @@ describe('List', () => { createScroll('

                        0123

                        1. 5678
                        '), ); editor.deleteText(2, 5); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                        1. 0178
                        @@ -313,7 +313,7 @@ describe('List', () => { ), ); editor.formatLine(1, 10, { list: 'bullet' }); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                        1. One
                        2. Alpha
                        3. @@ -327,7 +327,7 @@ describe('List', () => { createScroll('

                          Test

                          '), ); editor.formatLine(4, 1, { list: 'bullet' }); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          1. Test
                          @@ -343,11 +343,11 @@ describe('List', () => { 'video', 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0', ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          1. Te
                          -
                          1. st
                          @@ -363,8 +363,8 @@ describe('List', () => { 'video', 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0', ); - expect(editor.scroll).toMatchInlineSnapshot(` -
                          1. Test
                          @@ -380,11 +380,11 @@ describe('List', () => { 'video', 'https://www.youtube.com/embed/QHH3iSeDBLo?showinfo=0', ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          1. Test
                          -

                          diff --git a/test/unit/formats/script.spec.ts b/test/unit/formats/script.spec.ts index 1706e80dac..05186def74 100644 --- a/test/unit/formats/script.spec.ts +++ b/test/unit/formats/script.spec.ts @@ -15,7 +15,7 @@ describe('Script', () => { createScroll('

                          a2 + b2 = c2

                          '), ); editor.formatText(6, 1, { script: 'super' }); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

                          a2 + b2 = c2

                          ', ); }); @@ -25,7 +25,7 @@ describe('Script', () => { createScroll('

                          a2 + b2

                          '), ); editor.formatText(1, 1, { script: false }); - expect(editor.scroll).toMatchInlineSnapshot('

                          a2 + b2

                          '); + expect(editor.scroll.domNode).toEqualHTML('

                          a2 + b2

                          '); }); test('replace', () => { @@ -33,7 +33,7 @@ describe('Script', () => { createScroll('

                          a2 + b2

                          '), ); editor.formatText(1, 1, { script: 'sub' }); - expect(editor.scroll).toMatchInlineSnapshot( + expect(editor.scroll.domNode).toEqualHTML( '

                          a2 + b2

                          ', ); }); diff --git a/test/unit/formats/table.spec.ts b/test/unit/formats/table.spec.ts index 83d1d3c921..bf5975e838 100644 --- a/test/unit/formats/table.spec.ts +++ b/test/unit/formats/table.spec.ts @@ -65,19 +65,19 @@ describe('Table', () => { test('initialize', () => { const editor = new Editor(createScroll(tableHTML)); expect(editor.getDelta()).toEqual(tableDelta); - expect(editor.scroll).toMatchInlineSnapshot(tableHTML); + expect(editor.scroll.domNode).toEqualHTML(tableHTML); }); test('add', () => { const editor = new Editor(createScroll('')); editor.applyDelta(new Delta([...tableDelta.ops]).delete(1)); - expect(editor.scroll).toMatchInlineSnapshot(tableHTML); + expect(editor.scroll.domNode).toEqualHTML(tableHTML); }); test('add format plaintext', () => { const editor = new Editor(createScroll('

                          Test

                          ')); editor.formatLine(0, 5, { table: 'a' }); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(` @@ -91,7 +91,7 @@ describe('Table', () => { test('add format replace', () => { const editor = new Editor(createScroll('

                          Test

                          ')); editor.formatLine(0, 5, { table: 'a' }); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          @@ -107,7 +107,7 @@ describe('Table', () => { createScroll('
                          Test
                          '), ); editor.formatLine(0, 5, { table: null }); - expect(editor.scroll).toMatchInlineSnapshot('

                          Test

                          '); + expect(editor.scroll.domNode).toEqualHTML('

                          Test

                          '); }); test('remove format replace', () => { @@ -115,7 +115,7 @@ describe('Table', () => { createScroll('
                          Test
                          '), ); editor.formatLine(0, 5, { header: 1 }); - expect(editor.scroll).toMatchInlineSnapshot('

                          Test

                          '); + expect(editor.scroll.domNode).toEqualHTML('

                          Test

                          '); }); test('group rows', () => { @@ -133,7 +133,7 @@ describe('Table', () => { ); // @ts-expect-error editor.scroll.children.head.children.head.children.head.optimize(); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(` @@ -159,7 +159,7 @@ describe('Table', () => { ); // @ts-expect-error editor.scroll.children.head.children.head.children.head.optimize(); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          @@ -186,7 +186,7 @@ describe('Table', () => { ); // @ts-expect-error editor.scroll.children.head.children.head.children.head.optimize(); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          @@ -224,7 +224,7 @@ describe('Table', () => { ); // @ts-expect-error editor.scroll.children.head.balanceCells(); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          @@ -251,7 +251,7 @@ describe('Table', () => { const editor = new Editor(createScroll('

                          a

                          b

                          1

                          2

                          ')); editor.formatLine(0, 4, { table: 'a' }); editor.formatLine(4, 4, { table: 'b' }); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          @@ -272,7 +272,7 @@ describe('Table', () => { editor.applyDelta( new Delta().insert('\n\n', { table: 'a' }).insert('\n\n', { table: 'b' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          @@ -297,7 +297,7 @@ describe('Table', () => { .insert('A2\nB2\nC2\n', { table: '2' }) .insert('A3\nB3\n', { table: '3' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          @@ -343,7 +343,7 @@ describe('Table', () => { .retain(1, { table: '1' }) .insert('\n', { table: '2' }), ); - expect(editor.scroll).toMatchInlineSnapshot(` + expect(editor.scroll.domNode).toEqualHTML(`
                          diff --git a/test/unit/modules/clipboard.spec.ts b/test/unit/modules/clipboard.spec.ts index e610a468f6..a3d7f3e26e 100644 --- a/test/unit/modules/clipboard.spec.ts +++ b/test/unit/modules/clipboard.spec.ts @@ -45,7 +45,7 @@ describe('Clipboard', () => { const quill = createQuill(); quill.clipboard.onCapturePaste(clipboardEvent); await sleep(2); - expect(quill.scroll).toMatchInlineSnapshot( + expect(quill.root).toEqualHTML( '

                          01|78

                          ', ); expect(quill.getSelection()).toEqual(new Range(3)); @@ -65,7 +65,7 @@ describe('Clipboard', () => { }); await sleep(2); expect(upload).not.toHaveBeenCalled(); - expect(quill.scroll).toMatchInlineSnapshot( + expect(quill.root).toEqualHTML( '

                          01|78

                          ', ); expect(quill.getSelection()).toEqual(new Range(3)); @@ -118,7 +118,7 @@ describe('Clipboard', () => { const { clipboardData, clipboardEvent } = setup(); quill.clipboard.onCaptureCopy(clipboardEvent, true); await sleep(2); - expect(quill.scroll).toMatchInlineSnapshot('

                          0178

                          '); + expect(quill.root).toEqualHTML('

                          0178

                          '); expect(quill.getSelection()).toEqual(new Range(2)); expect(clipboardData['text/plain']).toEqual('23\n56'); expect(clipboardData['text/html']).toEqual( @@ -130,15 +130,13 @@ describe('Clipboard', () => { test('dangerouslyPasteHTML(html)', () => { const quill = createQuill(); quill.clipboard.dangerouslyPasteHTML('abcd'); - expect(quill.scroll).toMatchInlineSnapshot( - '

                          abcd

                          ', - ); + expect(quill.root).toEqualHTML('

                          abcd

                          '); }); test('dangerouslyPasteHTML(index, html)', () => { const quill = createQuill(); quill.clipboard.dangerouslyPasteHTML(2, 'ab'); - expect(quill.scroll).toMatchInlineSnapshot(` + expect(quill.root).toEqualHTML(`

                          01ab23

                          5678

                          `);