diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 46ad2547..162b32db 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,50 +1,64 @@ module.exports = { - root: true, - parser: '@typescript-eslint/parser', - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - // 'plugin:@typescript-eslint/recommended-requiring-type-checking', - 'prettier' - ], - plugins: ['svelte3', 'tailwindcss', '@typescript-eslint', 'es', 'vitest'], - ignorePatterns: [ - 'docs/*', - '*.cjs', - '*.js', - '*.md', - 'snapshots.js', - 'svelte.config.js', - 'renovate.json', - 'package.json', - 'tsconfig.json' - ], - overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], - settings: { - 'svelte3/typescript': () => require('typescript') - }, - parserOptions: { - sourceType: 'module', - ecmaVersion: 2019, - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - extraFileExtensions: ['.svelte'], - allowAutomaticSingleRunInference: true - }, - env: { - browser: true, - es2017: true, - node: true - }, - rules: { - '@typescript-eslint/ban-ts-comment': [ - 'error', - { - 'ts-ignore': 'allow-with-description' - } - ], - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/no-unsafe-assignment': 'off', - 'es/no-regexp-lookbehind-assertions': 'error' - } + root: true, + parser: '@typescript-eslint/parser', + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + // 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:@typescript-eslint/strict', + 'prettier' + ], + plugins: ['svelte3', 'tailwindcss', '@typescript-eslint', 'es', 'vitest', 'no-only-tests'], + ignorePatterns: [ + 'docs/*', + '*.cjs', + '*.js', + '*.md', + 'snapshots.js', + 'svelte.config.js', + 'renovate.json', + 'package.json', + 'tsconfig.json' + ], + overrides: [ + { files: ['*.svelte'], processor: 'svelte3/svelte3' }, + { + files: ['*.ts'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:@typescript-eslint/strict', + 'prettier' + ] + } + ], + settings: { + 'svelte3/typescript': () => require('typescript') + }, + parserOptions: { + sourceType: 'module', + ecmaVersion: 2020, + tsconfigRootDir: __dirname, + project: ['./tsconfig.json'], + extraFileExtensions: ['.svelte'], + allowAutomaticSingleRunInference: true + }, + env: { + browser: true, + es2020: true + }, + rules: { + '@typescript-eslint/ban-ts-comment': [ + 'error', + { + 'ts-ignore': 'allow-with-description' + } + ], + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + 'es/no-regexp-lookbehind-assertions': 'error', + curly: ['error', 'all'], + 'no-only-tests/no-only-tests': 'error' + } }; diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..00e0771a --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,5 @@ +# .git-blame-ignore-revs +# Prettier Pass +6fde9e22a3ba0b80879a1909fb233367ef20b738 +# Tabs -> Spaces +0ac606b8fbf6f94215cbda1d4511e2dcd30e4655 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..695b6d30 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [sidharthv96, knsv] diff --git a/.github/dependabot.yml b/.github/dependabot.disabled.yml similarity index 100% rename from .github/dependabot.yml rename to .github/dependabot.disabled.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0cdf8d69..fcdc4c04 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: '16' + node-version: 18 cache: yarn - name: Build & Deploy diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 3291e338..a150127f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -8,13 +8,13 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v5 + - uses: actions/stale@v6 with: repo-token: ${{ secrets.GITHUB_TOKEN }} exempt-issue-labels: 'retained' exempt-pr-labels: 'retained' - stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days' - stale-pr-message: 'This pr is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days' + stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days' + stale-pr-message: 'This pr is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days' days-before-stale: 90 - days-before-close: 14 + days-before-close: 30 days-before-pr-close: -1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5498b747..c35dff12 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 cache: 'yarn' # Install NPM dependencies, cache them correctly @@ -48,3 +48,4 @@ jobs: parallel: true env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + CYPRESS_CI: true diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index ee582139..f812d373 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 cache: 'yarn' - name: Lint & Test diff --git a/.github/workflows/update-browserlist.yml b/.github/workflows/update-browserlist.yml index 450692d7..3e278a67 100644 --- a/.github/workflows/update-browserlist.yml +++ b/.github/workflows/update-browserlist.yml @@ -1,10 +1,9 @@ name: Update Browserslist on: - workflow_dispatch: push: - branches: - - develop - + branches-ignore: + - 'develop' + - 'master' jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/update-monaco-editor.yml b/.github/workflows/update-monaco-editor.yml index cb1586e6..31c2fd15 100644 --- a/.github/workflows/update-monaco-editor.yml +++ b/.github/workflows/update-monaco-editor.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v3 with: node-version: 18 - name: Update monaco version diff --git a/.prettierrc b/.prettierrc index 53609cfb..ab65daf2 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,8 +1,7 @@ { - "singleQuote": true, - "svelteSortOrder": "options-scripts-markup-styles", - "bracketSameLine": true, - "useTabs": true, - "trailingComma": "none", - "printWidth": 100 + "singleQuote": true, + "svelteSortOrder": "options-scripts-markup-styles", + "bracketSameLine": true, + "trailingComma": "none", + "printWidth": 100 } diff --git a/.vscode/launch.json b/.vscode/launch.json index 197e0480..1689524c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,15 +1,15 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "pwa-chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:3000", - "webRoot": "${workspaceFolder}" - } - ] + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}" + } + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index cd3023f6..925342c8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,9 @@ { - "editor.formatOnSave": true, - "cSpell.words": ["pako", "Serde", "serdes"] + "editor.formatOnSave": true, + "cSpell.words": ["asyncable", "KROKI", "mindmap", "pako", "Serde", "serdes", "tailwindcss"], + "vitest.commandLine": "yarn test:unit", + "vitest.enable": true, + "testing.autoRun.mode": "rerun", + "svelte.enable-ts-plugin": true, + "githubPullRequests.ignoredPullRequestBranches": ["develop"] } diff --git a/Dockerfile b/Dockerfile index edc42c3f..627f7841 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ # Stop : press ctrl + c # or # docker stop mermaid-live-editor -FROM node:18.7.0 as mermaid-live-editor-builder +FROM node:18.12.1 as mermaid-live-editor-builder COPY --chown=node:node . /home WORKDIR /home RUN yarn install diff --git a/bin/update-monaco.js b/bin/update-monaco.js index 3d81bdfc..875639ba 100755 --- a/bin/update-monaco.js +++ b/bin/update-monaco.js @@ -9,37 +9,37 @@ const monacoVersion = packageJson.dependencies['monaco-editor'].replace('^', '') // fetch monaco sri info from cdnjs api const cdnjsAPIResp = await fetch( - `https://api.cdnjs.com/libraries/monaco-editor/${monacoVersion}?fields=sri` + `https://api.cdnjs.com/libraries/monaco-editor/${monacoVersion}?fields=sri` ); if (cdnjsAPIResp.ok) { - const respJson = await cdnjsAPIResp.json(); - const htmlPath = path.join('src', 'app.html'); - const appHtml = fs - .readFileSync(htmlPath, 'utf8') - // update monaco version of every asset in app.html - .replaceAll(/[0-9.]+\/min\/vs/g, `${monacoVersion}/min/vs`); - const root = parse(appHtml); - const updateIntegrity = (tag, attr) => { - for (const node of root - .getElementsByTagName(tag) - .filter((node) => node.getAttribute(attr)?.includes('monaco-editor'))) { - const file = node.getAttribute(attr).split(`${monacoVersion}/`)[1]; - node.setAttribute('integrity', respJson.sri[file]); - } - }; + const respJson = await cdnjsAPIResp.json(); + const htmlPath = path.join('src', 'app.html'); + const appHtml = fs + .readFileSync(htmlPath, 'utf8') + // update monaco version of every asset in app.html + .replaceAll(/[0-9.]+\/min\/vs/g, `${monacoVersion}/min/vs`); + const root = parse(appHtml); + const updateIntegrity = (tag, attr) => { + for (const node of root + .getElementsByTagName(tag) + .filter((node) => node.getAttribute(attr)?.includes('monaco-editor'))) { + const file = node.getAttribute(attr).split(`${monacoVersion}/`)[1]; + node.setAttribute('integrity', respJson.sri[file]); + } + }; - updateIntegrity('script', 'src'); - updateIntegrity('link', 'href'); + updateIntegrity('script', 'src'); + updateIntegrity('link', 'href'); - fs.writeFileSync( - htmlPath, - prettier.format(root.toString(), { - singleQuote: false, - parser: 'html', - bracketSameLine: true, - useTabs: true - }) - ); + fs.writeFileSync( + htmlPath, + prettier.format(root.toString(), { + singleQuote: false, + parser: 'html', + bracketSameLine: true, + useTabs: true + }) + ); } else { - throw Error('Unable to fetch monaco sri data from cdnjs api.'); + throw Error('Unable to fetch monaco sri data from cdnjs api.'); } diff --git a/cypress.config.js b/cypress.config.js index 40248bb5..0e2c5933 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -2,34 +2,34 @@ import { defineConfig } from 'cypress'; import fs from 'fs'; import { isFileExist, findFiles } from 'cy-verify-downloads'; export default defineConfig({ - projectId: '2ckppp', - viewportWidth: 1440, - viewportHeight: 768, - snapshotFileName: './cypress/snapshots.js', - defaultCommandTimeout: 16000, - requestTimeout: 16000, - retries: { - runMode: 2, - openMode: 0 - }, - e2e: { - setupNodeEvents(on, config) { - on('task', { - isFileExist, - findFiles, - deleteFile(path) { - fs.rmSync(path); - return null; - }, - readFileMaybe(filename) { - if (fs.existsSync(filename)) { - return fs.readFileSync(filename, 'utf8'); - } - return null; - } - }); - }, - baseUrl: 'http://localhost:3000', - specPattern: 'cypress/e2e/**/*.spec.ts' - } + projectId: '2ckppp', + viewportWidth: 1440, + viewportHeight: 768, + snapshotFileName: './cypress/snapshots.js', + defaultCommandTimeout: 16000, + requestTimeout: 16000, + retries: { + runMode: 4, + openMode: 0 + }, + e2e: { + setupNodeEvents(on, config) { + on('task', { + isFileExist, + findFiles, + deleteFile(path) { + fs.rmSync(path); + return null; + }, + readFileMaybe(filename) { + if (fs.existsSync(filename)) { + return fs.readFileSync(filename, 'utf8'); + } + return null; + } + }); + }, + baseUrl: 'http://localhost:3000', + specPattern: 'cypress/e2e/**/*.spec.ts' + } }); diff --git a/cypress/.eslintrc b/cypress/.eslintrc index 43c00855..01edfeeb 100644 --- a/cypress/.eslintrc +++ b/cypress/.eslintrc @@ -1,10 +1,10 @@ { - "plugins": ["cypress"], - "extends": ["plugin:cypress/recommended"], - "rules": { - "jest/expect-expect": "off" - }, - "env": { - "cypress/globals": true - } + "plugins": ["cypress"], + "extends": ["plugin:cypress/recommended"], + "rules": { + "jest/expect-expect": "off" + }, + "env": { + "cypress/globals": true + } } diff --git a/cypress/e2e/actions.spec.ts b/cypress/e2e/actions.spec.ts index 78e818e4..d004e81a 100644 --- a/cypress/e2e/actions.spec.ts +++ b/cypress/e2e/actions.spec.ts @@ -1,55 +1,48 @@ -import { disableDebounce } from './util'; +import { verifyFileSize } from './util'; describe('Check actions', () => { - beforeEach(() => { - cy.clearLocalStorage(); - cy.visit('/edit'); - disableDebounce(); - }); + beforeEach(() => { + cy.clearLocalStorage(); + cy.visit('/edit'); + }); - it('should update markdown code', () => { - cy.get('#markdown') - .invoke('val') - .then((oldText) => { - cy.get('#editor').click('bottom').type('{enter}C --> HistoryTest'); - cy.get('#markdown') - .invoke('val') - .then((newText) => { - expect(oldText).to.not.eq(newText); - }); - }); - }); + it('should update markdown code', () => { + cy.get('#markdown') + .invoke('val') + .then((oldText) => { + cy.get('#editor').click('bottom').type('{enter}C --> HistoryTest'); + cy.get('#markdown') + .invoke('val') + .then((newText) => { + expect(oldText).to.not.eq(newText); + }); + }); + }); - it('should load gists from URL', () => { - cy.get('#gist').type('https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a'); - cy.contains('Load Gist').click(); - cy.contains('Go shopping!!'); - }); + it('should load gists from URL', () => { + cy.get('#gist').type('https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a'); + cy.contains('Load Gist').click(); + cy.contains('Go shopping!!'); + }); - it('should download png and svg', () => { - cy.clock(new Date(2022, 0, 1).getTime()); - const downloadsFolder = Cypress.config('downloadsFolder'); + it('should download png and svg', () => { + cy.clock(new Date(2022, 0, 1).getTime()); - const verifyFileSize = (fileType: string, size: number) => { - cy.get(`#download${fileType.toUpperCase()}`).click(); - const fileName = `mermaid-diagram-2022-01-01-000000.${fileType}`; - const filePath = `${downloadsFolder}/${fileName}`; - cy.verifyDownload(fileName); - cy.readFile(filePath, null, { - log: false - }).then((buffer) => expect((buffer as ArrayBuffer).byteLength).to.be.gt(size)); - cy.task('deleteFile', filePath); - }; + cy.get(`#downloadPNG`).click(); + verifyFileSize('diagram', 'png', 21_000); - verifyFileSize('png', 21_000); - verifyFileSize('svg', 11_000); + cy.get(`#downloadSVG`).click(); + verifyFileSize('diagram', 'svg', 10_000); - // Verify downloaded file is different for different diagrams - cy.contains('Sample Diagrams').click(); - cy.contains('ER Diagram').click(); + // Verify downloaded file is different for different diagrams + cy.contains('Sample Diagrams').click(); + cy.contains('ER').click(); - verifyFileSize('png', 46_000); - verifyFileSize('svg', 12_000); + cy.get(`#downloadPNG`).click(); + verifyFileSize('diagram', 'png', 46_000); - cy.clock().invoke('restore'); - }); + cy.get(`#downloadSVG`).click(); + verifyFileSize('diagram', 'svg', 12_000); + + cy.clock().invoke('restore'); + }); }); diff --git a/cypress/e2e/diagramUpdate.spec.ts b/cypress/e2e/diagramUpdate.spec.ts index dc251c78..c209be3e 100644 --- a/cypress/e2e/diagramUpdate.spec.ts +++ b/cypress/e2e/diagramUpdate.spec.ts @@ -1,69 +1,94 @@ -import { getEditor, cmd, disableDebounce } from './util'; +import { getEditor, cmd } from './util'; describe('Auto sync tests', () => { - beforeEach(() => { - cy.clearLocalStorage(); - cy.visit('/'); - disableDebounce(); - }); + beforeEach(() => { + cy.clearLocalStorage(); + cy.visit('/'); + }); - it('should dim diagram when code is edited', () => { - cy.contains('Auto sync').click(); - cy.get('#view').should('not.have.class', 'outOfSync'); - getEditor().type(' C --> Test'); - cy.get('#view').should('have.class', 'outOfSync'); - cy.getLocalStorage('codeStore').snapshot(); - }); + it('should dim diagram when code is edited', () => { + cy.contains('Auto sync').click(); + cy.get('#view').should('not.have.class', 'outOfSync'); + cy.get('#errorContainer').should('not.exist'); + getEditor({ bottom: true, newline: true }).type(' C --> Test'); + cy.get('#view').should('have.class', 'outOfSync'); + cy.get('#errorContainer').should('contain.text', 'Diagram out of sync.'); + cy.getLocalStorage('codeStore').snapshot(); + }); - it('should update diagram when shortcut is used', () => { - cy.contains('Auto sync').click(); - cy.get('#view').should('not.have.class', 'outOfSync'); - getEditor().type(' C --> Test'); - cy.get('#view').should('have.class', 'outOfSync'); - getEditor().type(`${cmd}{enter}`); - cy.get('#view').should('not.have.class', 'outOfSync'); - }); + it('should update diagram when shortcut is used', () => { + cy.contains('Auto sync').click(); + cy.get('#view').should('not.have.class', 'outOfSync'); + getEditor().type(' C --> Test'); + cy.get('#view').should('have.class', 'outOfSync'); + cy.get('#errorContainer').should('contain.text', 'Diagram out of sync.'); + getEditor().type(`${cmd}{enter}`); + cy.get('#errorContainer').should('not.exist'); + cy.get('#view').should('not.have.class', 'outOfSync'); + }); - it('should show/hide sync button with auto sync', () => { - cy.get('[data-cy=sync]').should('not.exist'); - cy.contains('Auto sync').click(); - cy.get('[data-cy=sync]').should('exist'); - cy.get('#autoSync').check(); - cy.get('[data-cy=sync]').should('not.exist'); - }); + it('should show/hide sync button with auto sync', () => { + cy.get('[data-cy=sync]').should('not.exist'); + cy.contains('Auto sync').click(); + cy.get('[data-cy=sync]').should('exist'); + cy.get('#autoSync').check(); + cy.get('[data-cy=sync]').should('not.exist'); + }); - it('should not dim diagram when code is in sync', () => { - cy.contains('Auto sync').click(); - cy.get('#view').should('not.have.class', 'outOfSync'); - getEditor().type(' C --> Test'); - cy.get('#view').should('have.class', 'outOfSync'); - cy.get('[data-cy=sync]').click(); - cy.get('#view').should('not.have.class', 'outOfSync'); - cy.get('#autoSync').check(); - getEditor().type('ing'); - cy.get('#view').should('not.have.class', 'outOfSync'); - cy.getLocalStorage('codeStore').snapshot(); - }); + it('should not dim diagram when code is in sync', () => { + cy.contains('Auto sync').click(); + cy.get('#view').should('not.have.class', 'outOfSync'); + getEditor().type(' C --> Test'); + cy.get('#view').should('have.class', 'outOfSync'); + cy.get('[data-cy=sync]').click(); + cy.get('#view').should('not.have.class', 'outOfSync'); + cy.get('#autoSync').check(); + getEditor().type('ing'); + cy.get('#view').should('not.have.class', 'outOfSync'); + cy.getLocalStorage('codeStore').snapshot(); + }); - it('supports commenting code out/in', () => { - getEditor().type(`{uparrow}${cmd}/`); - cy.get('#view').contains('Car').should('not.exist'); + it('supports commenting code out/in', () => { + getEditor().type(`{uparrow}${cmd}/`); + cy.get('#view').contains('Car').should('not.exist'); - getEditor().type(`{uparrow}${cmd}/`); - cy.get('#view').contains('Car').should('exist'); - }); + getEditor().type(`{uparrow}${cmd}/`); + cy.get('#view').contains('Car').should('exist'); + }); - it('supports editing code when code is incorrect', () => { - cy.visit( - '/edit#pako:eNpljjEKwzAMRa8SNOcEnlt6gK5eVFvYJsgOqkwpIXevg9smEE1PnyfxF3DFExgISW-CczQ2D21cYU7a-SGYXRwyvTp9jUhuKlVP-eHy7zA-leQsMEmg_QOM0BLG5FujZVMsaCQmC6ahR5ks2Lw2r84ela4-aREwKpVGwKrl_s7ut3fnkjAIcg_XDzuaUhs' - ); - cy.get('#errorContainer').should('not.exist'); - getEditor({ newline: true }).type(`branch test`); - cy.get('#editor').contains('branch test').should('exist'); - cy.get('#errorContainer') - .contains( - 'Error: Trying to checkout branch which is not yet created. (Help try using "branch master")' - ) - .should('exist'); - }); + it('supports editing code when code is incorrect', () => { + cy.visit( + '/edit#pako:eNpljjEKwzAMRa8SNOcEnlt6gK5eVFvYJsgOqkwpIXevg9smEE1PnyfxF3DFExgISW-CczQ2D21cYU7a-SGYXRwyvTp9jUhuKlVP-eHy7zA-leQsMEmg_QOM0BLG5FujZVMsaCQmC6ahR5ks2Lw2r84ela4-aREwKpVGwKrl_s7ut3fnkjAIcg_XDzuaUhs' + ); + cy.get('#errorContainer').should('not.exist'); + getEditor({ newline: true }).type(`branch test`); + cy.get('#editor').contains('branch test').should('exist'); + cy.get('#errorContainer') + .contains( + 'Error: Trying to checkout branch which is not yet created. (Help try using "branch master")' + ) + .should('exist'); + }); + + it('should update diagram after entire text is removed', () => { + // https://github.com/mermaid-js/mermaid-live-editor/issues/1102 + getEditor().type(`${cmd} a {backspace}`); + getEditor().type('graph LR'); + getEditor().type(' {enter} A-->Car'); + cy.get('#view').contains('Car').should('exist'); + }); +}); + +describe('Pan and Zoom', () => { + beforeEach(() => { + cy.clearLocalStorage(); + cy.visit('/'); + }); + it('should toggle pan and zoom', () => { + cy.get('#svg-pan-zoom-reset-pan-zoom').should('not.exist'); + cy.contains('Pan & Zoom').click(); + cy.get('#svg-pan-zoom-reset-pan-zoom').should('exist'); + cy.contains('Pan & Zoom').click(); + cy.get('#svg-pan-zoom-reset-pan-zoom').should('not.exist'); + }); }); diff --git a/cypress/e2e/docMap.spec.ts b/cypress/e2e/docMap.spec.ts index 904e165d..5c7e8201 100755 --- a/cypress/e2e/docMap.spec.ts +++ b/cypress/e2e/docMap.spec.ts @@ -1,36 +1,36 @@ describe('Editor docs tests', () => { - beforeEach(() => { - cy.on('uncaught:exception', () => { - return false; - }); - cy.clearLocalStorage(); - cy.visit('/edit'); - cy.contains('Sample Diagrams').click(); - }); + beforeEach(() => { + cy.on('uncaught:exception', () => { + return false; + }); + cy.clearLocalStorage(); + cy.visit('/edit'); + cy.contains('Sample Diagrams').click(); + }); - it('Test default loading', () => { - cy.get(`[data-cy=docs][href^="https://mermaid-js.github.io/mermaid"]`).should('exist'); - }); + it('Test default loading', () => { + cy.get(`[data-cy=docs][href^="https://mermaid-js.github.io/mermaid"]`).should('exist'); + }); - it('Test to see if the correct URL loads when changing from one diagram to other', () => { - cy.contains('Flow Chart').click(); - cy.get(`[data-cy=docs][href$="/#/flowchart"]`).should('exist'); + it('Test to see if the correct URL loads when changing from one diagram to other', () => { + cy.contains('Flow').click(); + cy.get(`[data-cy=docs][href$="/#/flowchart"]`).should('exist'); - cy.contains('Config').click(); - cy.get(`[data-cy=docs][href$="/#/flowchart?id=configuration"]`).should('exist'); + cy.contains('Config').click(); + cy.get(`[data-cy=docs][href$="/#/flowchart?id=configuration"]`).should('exist'); - cy.contains('Sequence Diagram').click(); - cy.get(`[data-cy=docs][href$="/#/sequenceDiagram?id=configuration"]`).should('exist'); + cy.contains('Sequence').click(); + cy.get(`[data-cy=docs][href$="/#/sequenceDiagram?id=configuration"]`).should('exist'); - cy.contains('Code').click(); - cy.get(`[data-cy=docs][href$="/#/sequenceDiagram"]`).should('exist'); - }); + cy.contains('Code').click(); + cy.get(`[data-cy=docs][href$="/#/sequenceDiagram"]`).should('exist'); + }); - it("Test to check URLs for a case where config URL doesn't exist", () => { - cy.contains('State Diagram').click(); - cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist'); + it("Test to check URLs for a case where config URL doesn't exist", () => { + cy.contains('State').click(); + cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist'); - cy.contains('Config').click(); - cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist'); - }); + cy.contains('Config').click(); + cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist'); + }); }); diff --git a/cypress/e2e/history.spec.ts b/cypress/e2e/history.spec.ts index 92b558d8..af5305c9 100644 --- a/cypress/e2e/history.spec.ts +++ b/cypress/e2e/history.spec.ts @@ -1,67 +1,105 @@ -import { getEditor, disableDebounce } from './util'; +import { getEditor, verifyFileSnapshot } from './util'; describe('Save History', () => { - beforeEach(() => { - cy.clock(); - cy.clearLocalStorage(); - cy.visit('/edit'); - disableDebounce(); - cy.contains('Actions').click(); - cy.contains('History').click(); - }); + beforeEach(() => { + cy.clock(new Date(2022, 0, 1).getTime()); + cy.clearLocalStorage(); + cy.visit('/edit'); - it('should save when clicked', () => { - cy.get('#historyList').find('li').should('have.length', 0); - cy.get('#historyList').contains('No items in History'); - cy.get('#saveHistory').click(); - cy.get('#historyList').find('No items in History').should('not.exist'); - cy.get('#historyList').find('li').should('have.length', 1); - cy.get('#saveHistory').click(); - cy.on('window:alert', (str) => { - expect(str).to.equal('State already saved.'); - }); - cy.on('window:confirm', () => true); - getEditor().type(' C --> HistoryTest'); - cy.get('#saveHistory').click(); - cy.get('#historyList').find('li').should('have.length', 2); - }); + cy.contains('Actions').click(); + cy.contains('History').click(); + }); - it('should be able to restore and delete', () => { - cy.get('#saveHistory').click(); - getEditor().type(' C --> HistoryTest'); - cy.get('#historyList').find('No items in History').should('not.exist'); - cy.get('#historyList').find('li').should('have.length', 1); - cy.contains('HistoryTest'); - cy.contains('Restore').click(); - cy.contains('HistoryTest').should('not.exist'); - cy.contains('Delete').click(); - cy.get('#historyList').find('li').should('have.length', 0); - cy.get('#historyList').contains('No items in History'); - cy.get('#saveHistory').click(); - getEditor().type(' C --> HistoryTest'); - cy.get('#saveHistory').click(); - cy.get('#editor').type('ing'); - cy.get('#clearHistory').click(); - cy.on('window:alert', (str) => { - expect(str).to.equal('Clear all saved items?'); - }); - cy.on('window:confirm', () => true); - cy.get('#historyList').contains('No items in History'); - }); + afterEach(() => { + cy.clock().invoke('restore'); + }); - // TODO: Fix #639 - xit('should auto save history', () => { - getEditor().type(' C --> HistoryTest'); - cy.tick(70000); - cy.contains('Timeline').click(); - cy.get('#historyList').find('li').should('have.length', 1); - cy.get('#editor').type('ing'); - cy.tick(70000); - cy.get('#historyList').find('li').should('have.length', 2); - for (let i = 0; i < 31; i++) { - cy.get('#editor').type('.'); - cy.tick(70000); - } - cy.get('#historyList').find('li').should('have.length', 30); - }); + it('should load history from localstorage', () => { + cy.setLocalStorage( + 'manualHistoryStore', + '[{"state":{"code":"graph TD\\n A[Halloween] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":false},"time":0,"type":"manual","id":"d7ea820e-21dd-418a-b984-fd58acde09df","name":"hollow-art"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":true},"time":0,"type":"manual","id":"b749ffc6-522b-4a44-86cf-7c1ffc3146b3","name":"helpful-ocean"}]' + ); + cy.setLocalStorage( + 'autoHistoryStore', + '[{"state":{"code":"graph TD\\n A[New Year] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":false},"time":0,"type":"auto","id":"69ea820e-522b-4a44-86cf-fd58acde09df","name":"barking-dog"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":true},"time":0,"type":"manual","id":"x749ffc6-21dd-418a-b984-7c1ffc3146b3","name":"needy-mosquito"}]' + ); + cy.reload(); + cy.contains('Actions').click(); + cy.contains('History').click(); + cy.get('#historyList').find('li').should('have.length', 2); + cy.get('#historyList').find('No items in History').should('not.exist'); + cy.get('#historyList').contains('helpful-ocean'); + cy.get('#historyList').contains('hollow-art'); + cy.contains('Restore').click(); + cy.contains('Halloween'); + cy.contains('Timeline').click(); + + cy.get('#historyList').find('li').should('have.length', 2); + cy.get('#historyList').find('No items in History').should('not.exist'); + cy.get('#historyList').contains('needy-mosquito'); + cy.get('#historyList').contains('barking-dog'); + cy.contains('Restore').click(); + cy.contains('New Year'); + }); + + it('should save when clicked', () => { + cy.get('#historyList').find('li').should('have.length', 0); + cy.get('#historyList').contains('No items in History'); + cy.get('#saveHistory').click(); + cy.get('#historyList').find('No items in History').should('not.exist'); + cy.get('#historyList').find('li').should('have.length', 1); + cy.get('#saveHistory').click(); + cy.on('window:alert', (str) => { + expect(str).to.equal('State already saved.'); + }); + cy.on('window:confirm', () => true); + getEditor().type(' C --> HistoryTest'); + cy.get('#saveHistory').click(); + cy.get('#historyList').find('li').should('have.length', 2); + }); + + it('should be able to restore and delete', () => { + cy.get('#saveHistory').click(); + getEditor().type(' C --> HistoryTest'); + cy.get('#historyList').find('No items in History').should('not.exist'); + cy.get('#historyList').find('li').should('have.length', 1); + cy.contains('HistoryTest'); + cy.contains('Restore').click(); + cy.contains('HistoryTest').should('not.exist'); + cy.contains('Delete').click(); + cy.get('#historyList').find('li').should('have.length', 0); + cy.get('#historyList').contains('No items in History'); + cy.get('#saveHistory').click(); + getEditor().type(' C --> HistoryTest'); + cy.get('#saveHistory').click(); + cy.get('#editor').type('ing'); + cy.get('#clearHistory').click(); + cy.on('window:alert', (str) => { + expect(str).to.equal('Clear all saved items?'); + }); + cy.on('window:confirm', () => true); + cy.get('#historyList').contains('No items in History'); + }); + + // TODO: Fix #639 + xit('should auto save history', () => { + getEditor().type(' C --> HistoryTest'); + cy.tick(70000); + cy.contains('Timeline').click(); + cy.get('#historyList').find('li').should('have.length', 1); + cy.get('#editor').type('ing'); + cy.tick(70000); + cy.get('#historyList').find('li').should('have.length', 2); + for (let i = 0; i < 31; i++) { + cy.get('#editor').type('.'); + cy.tick(70000); + } + cy.get('#historyList').find('li').should('have.length', 30); + }); + + it('should download history', () => { + cy.get('#saveHistory').click(); + cy.get(`#downloadHistory`).click(); + verifyFileSnapshot('history', 'json', 'A[Christmas] -->|Get money| B(Go shopping)'); + }); }); diff --git a/cypress/e2e/loadSite.spec.ts b/cypress/e2e/loadSite.spec.ts index 50497339..b80104e2 100644 --- a/cypress/e2e/loadSite.spec.ts +++ b/cypress/e2e/loadSite.spec.ts @@ -1,120 +1,122 @@ import { toBase64 } from 'js-base64'; -import { disableDebounce } from './util'; describe('Site Loads', () => { - beforeEach(() => { - cy.clearLocalStorage(); - cy.visit('/'); - disableDebounce(); - }); - it('Check Home page load', () => { - cy.url().should('include', '/edit'); - cy.contains('History').click(); - cy.getLocalStorage('codeStore').snapshot(); - }); + beforeEach(() => { + cy.clearLocalStorage(); + cy.visit('/'); + }); - it('Check Redirect from old URL', () => { - cy.visit( - '/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0NocmlzdG1hc10gLS0-fEdldCBtb25leXwgQihHbyBzaG9wcGluZylcbiAgICBCIC0tPiBDe0xldCBtZSB0aGlua31cbiAgICBDIC0tPnxPbmV8IERbTGFwdG9wXVxuICAgIEMgLS0-fFR3b3wgRVtpUGhvbmVdXG4gICAgQyAtLT58VGhyZWV8IEZbZmE6ZmEtY2FyIENhcl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ' - ); - cy.url().should('include', '/edit#pako:eNp'); - }); + it('Check Home page load', () => { + cy.url().should('include', '/edit'); + cy.contains('History').click(); + cy.getLocalStorage('codeStore').snapshot(); + }); - it('should load sample diagrams when clicked', () => { - cy.contains('Sample Diagrams').click(); - cy.contains('Pie Chart').click(); - cy.contains('pie title Pets adopted by volunteers'); - cy.contains('Class Diagram').click(); - cy.contains('classDiagram'); - }); + it('Check Redirect from old URL', () => { + cy.visit( + '/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0NocmlzdG1hc10gLS0-fEdldCBtb25leXwgQihHbyBzaG9wcGluZylcbiAgICBCIC0tPiBDe0xldCBtZSB0aGlua31cbiAgICBDIC0tPnxPbmV8IERbTGFwdG9wXVxuICAgIEMgLS0-fFR3b3wgRVtpUGhvbmVdXG4gICAgQyAtLT58VGhyZWV8IEZbZmE6ZmEtY2FyIENhcl0iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ' + ); + cy.url().should('include', '/edit#pako:eNp'); + }); - it('should load diagram from gist', () => { - cy.visit(`/edit?gist=https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a`); - cy.contains('History').click(); - cy.contains('Go shopping!!'); - cy.contains('Revisions'); - cy.contains('sidharthv96 v8f8f1e2'); - cy.contains('sidharthv96 v7851e19'); - cy.getLocalStorage('codeStore').snapshot(); - }); + it('should load sample diagrams when clicked', () => { + cy.contains('Sample Diagrams').click(); + cy.contains('Pie').click(); + cy.contains('pie title Pets adopted by volunteers'); + cy.contains('Class').click(); + cy.contains('classDiagram'); + }); - it('should load diagram from gist revision', () => { - cy.visit( - '/edit?gist=https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/ec9b4ab0e41e4ff6287326cd3cb47affd7851e19' - ); - cy.contains('History').click(); - cy.contains('Party'); - cy.contains('Revisions'); - cy.contains('sidharthv96 v7851e19'); - cy.getLocalStorage('codeStore').snapshot(); - }); + (Cypress.env('CI') === 'true' ? describe : describe.skip)('github', () => { + it('should load diagram from gist', () => { + cy.visit(`/edit?gist=https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a`); + cy.contains('History').click(); + cy.contains('Go shopping!!'); + cy.contains('Revisions'); + cy.contains('sidharthv96 v8f8f1e2'); + cy.contains('sidharthv96 v7851e19'); + cy.getLocalStorage('codeStore').snapshot(); + }); - it('should load diagram from raw files', () => { - cy.visit( - '/edit?code=https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/code.mmd&config=https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/config.json' - ); - cy.contains('Party'); - cy.getLocalStorage('codeStore').snapshot(); - }); + it('should load diagram from gist revision', () => { + cy.visit( + '/edit?gist=https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/ec9b4ab0e41e4ff6287326cd3cb47affd7851e19' + ); + cy.contains('History').click(); + cy.contains('Party'); + cy.contains('Revisions'); + cy.contains('sidharthv96 v7851e19'); + cy.getLocalStorage('codeStore').snapshot(); + }); - // Disabled temporarily. Should be enabled after the issue is fixed in Mermaid. - // it('should prevent setting the "securityLevel" option via URL', () => { - // const b64State = toBase64( - // `{"code":"graph TD\\nA[\\"\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`, - // true - // ); - // cy.on('window:confirm', () => true); - // cy.visit(`/edit#${b64State}`); - // cy.contains('Config').click(); - // cy.contains('forest'); - // cy.contains('securityLevel').should('not.exist'); - // cy.get('#view').find('img').should('not.exist'); - // cy.get('#view').contains(' { + cy.visit( + '/edit?code=https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/code.mmd&config=https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/config.json' + ); + cy.contains('Party'); + cy.getLocalStorage('codeStore').snapshot(); + }); + }); - it('should allow persisting "securityLevel" using confirm dialogue', () => { - const b64State = toBase64( - `{"code":"graph TD\\nA[\\"\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","updateEditor":true,"autoSync":true,"updateDiagram":true}`, - true - ); - cy.on('window:confirm', () => false); - cy.visit(`/edit#${b64State}`); - cy.contains('Config').click(); - cy.contains('forest'); - cy.contains('securityLevel'); - cy.get('#view').find('img').should('be.visible'); - }); + // Disabled temporarily. Should be enabled after the issue is fixed in Mermaid. + // it('should prevent setting the "securityLevel" option via URL', () => { + // const b64State = toBase64( + // `{"code":"graph TD\\nA[\\"\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","autoSync":true,"updateDiagram":true}`, + // true + // ); + // cy.on('window:confirm', () => true); + // cy.visit(`/edit#${b64State}`); + // cy.contains('Config').click(); + // cy.contains('forest'); + // cy.contains('securityLevel').should('not.exist'); + // cy.get('#view').find('img').should('not.exist'); + // cy.get('#view').contains(' { - cy.visit('/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAg'); - cy.reload(true); - cy.contains('Please Click here to Raise an issue in github.'); - }); + it.skip('should allow persisting "securityLevel" using confirm dialogue', () => { + const b64State = toBase64( + `{"code":"graph TD\\nA[\\"\\"]","mermaid":"{\\"securityLevel\\": \\"loose\\", \\"theme\\": \\"forest\\"}","autoSync":true,"updateDiagram":true}`, + true + ); + cy.on('window:confirm', () => false); + cy.visit(`/edit#${b64State}`); + cy.get('#editor').type(' '); + cy.contains('Config').click(); + cy.contains('forest'); + cy.contains('securityLevel'); + cy.get('#view').find('img').should('be.visible'); + }); - it('should load uncompressed URL', () => { - cy.visit( - '/edit/#eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW05ldyBZZWFyXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuICAgIEIgLS0-IEN7TGV0IG1lIHRoaW5rfVxuICAgIEMgLS0-fE9uZXwgRFtMYXB0b3BdXG4gICAgQyAtLT58VHdvfCBFW2lQaG9uZV1cbiAgICBDIC0tPnxUaHJlZXwgRltmYTpmYS1jYXIgQ2FyXSIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9' - ); - cy.contains('New Year'); - cy.visit( - '/edit#eyJjb2RlIjoiY2xhc3NEaWFncmFtXG4gICAgQW5pbWFsIDx8LS0gRHVja1xuICAgIEFuaW1hbCA8fC0tIEZpc2hcbiAgICBBbmltYWwgPHwtLSBaZWJyYVxuICAgIEFuaW1hbCA6ICtpbnQgYWdlXG4gICAgQW5pbWFsIDogK1N0cmluZyBnZW5kZXJcbiAgICBBbmltYWw6ICtpc01hbW1hbCgpXG4gICAgQW5pbWFsOiArbWF0ZSgpXG4gICAgY2xhc3MgRHVja3tcbiAgICAgICtTdHJpbmcgYmVha0NvbG9yXG4gICAgICArc3dpbSgpXG4gICAgICArcXVhY2soKVxuICAgIH1cbiAgICBjbGFzcyBGaXNoe1xuICAgICAgLWludCBzaXplSW5GZWV0XG4gICAgICAtY2FuRWF0KClcbiAgICB9XG4gICAgY2xhc3MgWmVicmF7XG4gICAgICArYm9vbCBpc193aWxkXG4gICAgICArcnVuKClcbiAgICB9XG4gICAgICAgICAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGFya1wiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ' - ); - cy.contains('Animal'); - cy.visit( - '/edit/#base64:eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW05ldyBZZWFyXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuICAgIEIgLS0-IEN7TGV0IG1lIHRoaW5rfVxuICAgIEMgLS0-fE9uZXwgRFtMYXB0b3BdXG4gICAgQyAtLT58VHdvfCBFW2lQaG9uZV1cbiAgICBDIC0tPnxUaHJlZXwgRltmYTpmYS1jYXIgQ2FyXSIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9' - ); - cy.contains('New Year'); - }); + it('should show troubleshooting steps if loading fails', () => { + cy.visit('/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbiAg'); + cy.reload(true); + cy.contains('Please Click here to Raise an issue in github.'); + }); - it('should load compressed URL', () => { - cy.visit( - '/edit#pako:eNpVkM2KwkAQhF-l6dMK5gVyEDRxvYi7sF6WjIcm0zqDzg_jBJEk725Hd2G3Tw31VVFUj23QjCWeEkUD-1p5kFs2O77BN1M6QFEshg1ncMHzfYDV2ybA1YQYrT_NXvhqgqDqtxPGkI315_ElVU__h-cB6mZLMYd4-Kvsb2GAdWM_jcT_V0xicb03RyqPVLSUoJI-OEfHyZHV0rqfDAqzYccKS3k1pbNC5Ufhuqgp81rbHBJKxuXKc6Quh6-7b7HMqeNfqLYkC7gfanwAlW1ZvQ' - ); - cy.contains('New Year'); - cy.visit( - '/edit#pako:eNptkU1PwzAMhv9K5BOI9Q9EXBDbJA477YYqITcxndV8QD40weh_Jy1rGR0-OY_tV2_sEyivCSQogzGuGduAtnaixINji0bcf1WVWGfVXdMtx8M1faYm4B8sxR27JLClJd6nwK4VLTlN4bI4jMQd2pLe3C4KFhNNcLQ92jv9ADGLNoTdozc-zIV4ZDsNlud7RtVN7_5Sb_jYrFcN3iN_0pPbEqUZK3QbTP_Ojyv4NdR4bwTHlyMbPcOQ3WJ2CliBpWCRdbnLqFJDOpClGmRJNYauhtr1pS-_6bKMjebkA8hXNJFWgDn5_YdTIFPINDWdb3vu6r8BaWOZRQ' - ); - cy.contains('Animal'); - }); + it('should load uncompressed URL', () => { + cy.visit( + '/edit/#eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW05ldyBZZWFyXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuICAgIEIgLS0-IEN7TGV0IG1lIHRoaW5rfVxuICAgIEMgLS0-fE9uZXwgRFtMYXB0b3BdXG4gICAgQyAtLT58VHdvfCBFW2lQaG9uZV1cbiAgICBDIC0tPnxUaHJlZXwgRltmYTpmYS1jYXIgQ2FyXSIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9' + ); + cy.contains('New Year'); + cy.visit( + '/edit#eyJjb2RlIjoiY2xhc3NEaWFncmFtXG4gICAgQW5pbWFsIDx8LS0gRHVja1xuICAgIEFuaW1hbCA8fC0tIEZpc2hcbiAgICBBbmltYWwgPHwtLSBaZWJyYVxuICAgIEFuaW1hbCA6ICtpbnQgYWdlXG4gICAgQW5pbWFsIDogK1N0cmluZyBnZW5kZXJcbiAgICBBbmltYWw6ICtpc01hbW1hbCgpXG4gICAgQW5pbWFsOiArbWF0ZSgpXG4gICAgY2xhc3MgRHVja3tcbiAgICAgICtTdHJpbmcgYmVha0NvbG9yXG4gICAgICArc3dpbSgpXG4gICAgICArcXVhY2soKVxuICAgIH1cbiAgICBjbGFzcyBGaXNoe1xuICAgICAgLWludCBzaXplSW5GZWV0XG4gICAgICAtY2FuRWF0KClcbiAgICB9XG4gICAgY2xhc3MgWmVicmF7XG4gICAgICArYm9vbCBpc193aWxkXG4gICAgICArcnVuKClcbiAgICB9XG4gICAgICAgICAgICAiLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGFya1wiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ' + ); + cy.contains('Animal'); + cy.visit( + '/edit/#base64:eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW05ldyBZZWFyXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuICAgIEIgLS0-IEN7TGV0IG1lIHRoaW5rfVxuICAgIEMgLS0-fE9uZXwgRFtMYXB0b3BdXG4gICAgQyAtLT58VHdvfCBFW2lQaG9uZV1cbiAgICBDIC0tPnxUaHJlZXwgRltmYTpmYS1jYXIgQ2FyXSIsIm1lcm1haWQiOiJ7XG4gIFwidGhlbWVcIjogXCJkZWZhdWx0XCJcbn0iLCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9' + ); + cy.contains('New Year'); + }); + + it('should load compressed URL', () => { + cy.visit( + '/edit#pako:eNpVkM2KwkAQhF-l6dMK5gVyEDRxvYi7sF6WjIcm0zqDzg_jBJEk725Hd2G3Tw31VVFUj23QjCWeEkUD-1p5kFs2O77BN1M6QFEshg1ncMHzfYDV2ybA1YQYrT_NXvhqgqDqtxPGkI315_ElVU__h-cB6mZLMYd4-Kvsb2GAdWM_jcT_V0xicb03RyqPVLSUoJI-OEfHyZHV0rqfDAqzYccKS3k1pbNC5Ufhuqgp81rbHBJKxuXKc6Quh6-7b7HMqeNfqLYkC7gfanwAlW1ZvQ' + ); + cy.contains('New Year'); + cy.visit( + '/edit#pako:eNptkU1PwzAMhv9K5BOI9Q9EXBDbJA477YYqITcxndV8QD40weh_Jy1rGR0-OY_tV2_sEyivCSQogzGuGduAtnaixINji0bcf1WVWGfVXdMtx8M1faYm4B8sxR27JLClJd6nwK4VLTlN4bI4jMQd2pLe3C4KFhNNcLQ92jv9ADGLNoTdozc-zIV4ZDsNlud7RtVN7_5Sb_jYrFcN3iN_0pPbEqUZK3QbTP_Ojyv4NdR4bwTHlyMbPcOQ3WJ2CliBpWCRdbnLqFJDOpClGmRJNYauhtr1pS-_6bKMjebkA8hXNJFWgDn5_YdTIFPINDWdb3vu6r8BaWOZRQ' + ); + cy.contains('Animal'); + }); }); diff --git a/cypress/e2e/themes.spec.ts b/cypress/e2e/themes.spec.ts index a5a5c77f..c7d986ff 100644 --- a/cypress/e2e/themes.spec.ts +++ b/cypress/e2e/themes.spec.ts @@ -1,56 +1,56 @@ describe('Test themes', () => { - describe('Test light themes', () => { - beforeEach(() => { - cy.clearLocalStorage(); - cy.visit('/edit', { - onBeforeLoad(win) { - cy.stub(win, 'matchMedia') - .callThrough() - .withArgs('(prefers-color-scheme: dark)') - .returns({ - matches: false - }); - } - }); - cy.contains('Change Theme').click(); - }); + describe('Test light themes', () => { + beforeEach(() => { + cy.clearLocalStorage(); + cy.visit('/edit', { + onBeforeLoad(win) { + cy.stub(win, 'matchMedia') + .callThrough() + .withArgs('(prefers-color-scheme: dark)') + .returns({ + matches: false + }); + } + }); + cy.contains('Change Theme').click(); + }); - it('should set light theme as default', () => { - cy.contains('light').parent().should('have.class', 'bordered'); - cy.contains('dark').parent().should('not.have.class', 'bordered'); - cy.getLocalStorage('themeStore').snapshot(); - }); + it('should set light theme as default', () => { + cy.contains('light').parent().should('have.class', 'bordered'); + cy.contains('dark').parent().should('not.have.class', 'bordered'); + cy.getLocalStorage('themeStore').snapshot(); + }); - it('should change themes when clicked', () => { - cy.contains('light').parent().should('have.class', 'bordered'); - cy.contains('cupcake').click(); - cy.contains('cupcake').parent().should('have.class', 'bordered'); - cy.contains('light').parent().should('not.have.class', 'bordered'); - cy.contains('dark').parent().should('not.have.class', 'bordered'); - cy.getLocalStorage('themeStore').snapshot(); - }); - }); + it('should change themes when clicked', () => { + cy.contains('light').parent().should('have.class', 'bordered'); + cy.contains('cupcake').click(); + cy.contains('cupcake').parent().should('have.class', 'bordered'); + cy.contains('light').parent().should('not.have.class', 'bordered'); + cy.contains('dark').parent().should('not.have.class', 'bordered'); + cy.getLocalStorage('themeStore').snapshot(); + }); + }); - describe('Test dark mode', () => { - beforeEach(() => { - cy.clearLocalStorage(); - cy.visit('/edit', { - onBeforeLoad(win) { - cy.stub(win, 'matchMedia') - .callThrough() - .withArgs('(prefers-color-scheme: dark)') - .returns({ - matches: true - }); - } - }); - cy.contains('Change Theme').click(); - }); + describe('Test dark mode', () => { + beforeEach(() => { + cy.clearLocalStorage(); + cy.visit('/edit', { + onBeforeLoad(win) { + cy.stub(win, 'matchMedia') + .callThrough() + .withArgs('(prefers-color-scheme: dark)') + .returns({ + matches: true + }); + } + }); + cy.contains('Change Theme').click(); + }); - it('should set dark theme as default', () => { - cy.contains('light').parent().should('not.have.class', 'bordered'); - cy.contains('dark').parent().should('have.class', 'bordered'); - cy.getLocalStorage('themeStore').snapshot(); - }); - }); + it('should set dark theme as default', () => { + cy.contains('light').parent().should('not.have.class', 'bordered'); + cy.contains('dark').parent().should('have.class', 'bordered'); + cy.getLocalStorage('themeStore').snapshot(); + }); + }); }); diff --git a/cypress/e2e/util.ts b/cypress/e2e/util.ts index e715fd36..6aa17ce5 100644 --- a/cypress/e2e/util.ts +++ b/cypress/e2e/util.ts @@ -1,11 +1,43 @@ export const cmd = `{${Cypress.platform === 'darwin' ? 'meta' : 'ctrl'}}`; export const getEditor = ({ bottom = true, newline = false } = {}) => - cy - .get('#editor textarea:first') - .click() - .focused() - .type(`${bottom ? '{pageDown}' : cmd}`) - .type(`${newline ? '{enter}' : cmd}`); + cy + .get('#editor textarea:first') + .click() + .focused() + .type(`${bottom ? '{pageDown}' : cmd}`) + .type(`${newline ? '{enter}' : cmd}`); -export const disableDebounce = () => cy.setLocalStorage('noDebounce', 'true'); +const downloadsFolder = Cypress.config('downloadsFolder'); + +export const verifyFileSize = ( + fileType: 'history' | 'diagram', + extension: string, + size: number +) => { + const fileName = `mermaid-${fileType}-2022-01-01-000000.${extension}`; + const filePath = `${downloadsFolder}/${fileName}`; + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + cy.verifyDownload(fileName); + cy.readFile(filePath, null, { + log: false + }).then((buffer) => expect((buffer as ArrayBuffer).byteLength).to.be.gt(size)); + cy.task('deleteFile', filePath); +}; + +export const verifyFileSnapshot = ( + fileType: 'history' | 'diagram', + extension: string, + content: string +) => { + const fileName = `mermaid-${fileType}-2022-01-01-000000.${extension}`; + const filePath = `${downloadsFolder}/${fileName}`; + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + cy.verifyDownload(fileName); + cy.readFile(filePath, null, { + log: false + }).then((buffer) => + expect(new TextDecoder('utf-8').decode(buffer as ArrayBuffer)).to.contain(content) + ); + cy.task('deleteFile', filePath); +}; diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json index 0ff2d645..02e42543 100644 --- a/cypress/fixtures/example.json +++ b/cypress/fixtures/example.json @@ -1,5 +1,5 @@ { - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" } diff --git a/cypress/snapshots.js b/cypress/snapshots.js index 0de6a809..547d2f44 100644 --- a/cypress/snapshots.js +++ b/cypress/snapshots.js @@ -1,28 +1,28 @@ module.exports = { "Site Loads": { "Check Home page load": { - "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":true,\"autoSync\":true,\"updateDiagram\":true}" + "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"autoSync\":true,\"updateDiagram\":true}" }, "Check Redirect from old URL": { - "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true}" + "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"autoSync\":true,\"updateDiagram\":true}" }, "should load diagram from gist": { - "1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping!!)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello world\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"gist\",\"config\":{\"url\":\"https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a\"}}}" + "1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping!!)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello world\\\"\\n}\",\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"gist\",\"config\":{\"url\":\"https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a\"}}}" }, "should load diagram from gist revision": { - "1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"gist\",\"config\":{\"url\":\"https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/ec9b4ab0e41e4ff6287326cd3cb47affd7851e19\"}}}" + "1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello\\\"\\n}\",\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"gist\",\"config\":{\"url\":\"https://gist.github.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/ec9b4ab0e41e4ff6287326cd3cb47affd7851e19\"}}}" }, "should load diagram from raw files": { - "1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping!!)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello world\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"files\",\"config\":{\"codeURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/code.mmd\",\"configURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/config.json\"}}}" + "1": "{\"code\":\"graph TD\\n A[Party] -->|Get money| B(Go shopping!!)\\n \",\"mermaid\":\"{\\n \\\"theme\\\": \\\"forest\\\",\\n \\\"test\\\": \\\"hello world\\\"\\n}\",\"autoSync\":true,\"updateDiagram\":true,\"loader\":{\"type\":\"files\",\"config\":{\"codeURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/code.mmd\",\"configURL\":\"https://gist.githubusercontent.com/sidharthv96/6268a23e673a533dcb198f241fd7012a/raw/4eb03887e6a41397e80bdcdbf94017c498f8f1e2/config.json\"}}}" } }, - "__version": "10.4.0", + "__version": "11.2.0", "Auto sync tests": { "should dim diagram when code is edited": { - "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n C --> Test\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":false,\"updateDiagram\":false}" + "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n C --> Test\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"autoSync\":false,\"updateDiagram\":false}" }, "should not dim diagram when code is in sync": { - "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n C --> Testing\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"updateEditor\":false,\"autoSync\":true,\"updateDiagram\":false}" + "1": "{\"code\":\"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)\\n B --> C{Let me think}\\n C -->|One| D[Laptop]\\n C -->|Two| E[iPhone]\\n C -->|Three| F[fa:fa-car Car]\\n C --> Testing\",\"mermaid\":\"{\\n \\\"theme\\\": \\\"default\\\"\\n}\",\"autoSync\":true,\"updateDiagram\":false}" } }, "Test themes": { diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index fe4e2603..0f4147cd 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -27,12 +27,12 @@ import { register } from '@cypress/snapshot'; // eslint-disable-next-line @typescript-eslint/no-unsafe-call register(); declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace - namespace Cypress { - interface Chainable { - snapshot(): void; - } - } + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + interface Chainable { + snapshot(): void; + } + } } import 'cypress-localstorage-commands'; diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index af0278d8..d9401131 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -21,8 +21,8 @@ require('cy-verify-downloads').addCustomCommand(); // require('./commands') Cypress.on('uncaught:exception', (err) => { - /* returning false here prevents Cypress from failing the test */ - if (err.message.includes('ResizeObserver loop limit exceeded')) { - return false; - } + /* returning false here prevents Cypress from failing the test */ + if (err.message.includes('ResizeObserver loop limit exceeded')) { + return false; + } }); diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index efeb6a0f..ec647435 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,7 +1,7 @@ { - "compilerOptions": { - "allowJs": true, - "types": ["cypress", "cypress-localstorage-commands", "cy-verify-downloads"] - }, - "include": ["**/*.ts"] + "compilerOptions": { + "allowJs": true, + "types": ["cypress", "cypress-localstorage-commands", "cy-verify-downloads"] + }, + "include": ["**/*.ts"] } diff --git a/package.json b/package.json index 241e3a2e..5275c366 100644 --- a/package.json +++ b/package.json @@ -1,93 +1,98 @@ { - "name": "mermaid-live-editor", - "version": "2.0.67", - "type": "module", - "license": "MIT", - "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "vite preview", - "lint": "prettier --check --cache --plugin-search-dir=. .;eslint --ignore-path .gitignore .", - "lint:fix": "prettier --write --cache --plugin-search-dir=. .;eslint --fix --ignore-path .gitignore .", - "format": "prettier --write --cache --plugin-search-dir=. .", - "pre-commit": "lint-staged", - "postinstall": "husky install; cypress cache prune; svelte-kit sync", - "test:unit": "vitest", - "test:ui": "vitest --ui", - "test:coverage": "vitest run --coverage", - "test:browser": "cypress run", - "test": "test:unit && test:browser", - "cy": "cypress open" - }, - "devDependencies": { - "@cypress/snapshot": "2.1.7", - "@playwright/test": "^1.25.0", - "@sveltejs/adapter-static": "1.0.0-next.39", - "@sveltejs/kit": "1.0.0-next.405", - "@testing-library/jest-dom": "5.16.5", - "@testing-library/svelte": "3.1.3", - "@types/mermaid": "8.2.9", - "@types/pako": "1.0.3", - "@typescript-eslint/eslint-plugin": "5.33.0", - "@typescript-eslint/parser": "5.33.0", - "@vitest/ui": "0.21.1", - "autoprefixer": "10.4.8", - "c8": "7.12.0", - "chai": "4.3.6", - "cssnano": "5.1.12", - "cy-verify-downloads": "0.1.8", - "cypress": "10.4.0", - "cypress-localstorage-commands": "2.2.0", - "eslint": "8.21.0", - "eslint-config-prettier": "8.5.0", - "eslint-plugin-cypress": "2.12.1", - "eslint-plugin-es": "4.1.0", - "eslint-plugin-postcss-modules": "2.0.0", - "eslint-plugin-svelte3": "4.0.0", - "eslint-plugin-tailwindcss": "3.6.0", - "eslint-plugin-vitest": "0.0.8", - "husky": "8.0.1", - "jsdom": "20.0.0", - "lint-staged": "13.0.3", - "node-html-parser": "5.4.1", - "postcss": "8.4.16", - "postcss-load-config": "4.0.1", - "prettier": "2.7.1", - "prettier-plugin-svelte": "2.7.0", - "svelte": "3.49.0", - "svelte-preprocess": "4.10.7", - "tailwindcss": "3.1.8", - "tslib": "2.4.0", - "typescript": "4.7.4", - "vite": "3.0.6", - "vitest": "0.21.1", - "vitest-svelte-kit": "0.0.7" - }, - "dependencies": { - "@analytics/google-analytics": "1.0.3", - "@macfja/svelte-persistent-store": "1.3.0", - "analytics": "0.8.1", - "daisyui": "2.22.0", - "js-base64": "3.7.2", - "mermaid": "9.1.5", - "moment": "2.29.4", - "monaco-editor": "0.34.0", - "monaco-mermaid": "1.0.6", - "pako": "2.0.4", - "random-word-slugs": "0.1.6", - "svg-pan-zoom": "^3.6.1" - }, - "lint-staged": { - "*.{ts,svelte,js,css,md,json}": [ - "prettier --plugin-search-dir=. --write", - "eslint --ignore-path .gitignore " - ] - }, - "volta": { - "node": "18.5.0", - "yarn": "1.22.10" - }, - "engines": { - "node": ">=16.7" - } -} \ No newline at end of file + "name": "mermaid-live-editor", + "version": "2.0.67", + "type": "module", + "license": "MIT", + "scripts": { + "dev": "vite dev", + "dev:force": "MERMAID_LOCAL=true yarn dev --force", + "dev:test": "yarn dev", + "build": "vite build", + "preview": "vite preview", + "lint": "prettier --check --cache --plugin-search-dir=. .;eslint --ignore-path .gitignore .", + "lint:fix": "prettier --write --cache --plugin-search-dir=. .;eslint --fix --ignore-path .gitignore .", + "format": "prettier --write --cache --plugin-search-dir=. .", + "pre-commit": "lint-staged", + "postinstall": "husky install && svelte-kit sync && (git config blame.ignoreRevsFile .git-blame-ignore-revs || true)", + "test:unit": "vitest", + "test:ui": "vitest --ui", + "test:coverage": "vitest run --coverage", + "test:browser": "cypress run", + "test": "test:unit && test:browser", + "cy": "cypress open" + }, + "devDependencies": { + "@cypress/snapshot": "2.1.7", + "@playwright/test": "^1.28.1", + "@sveltejs/adapter-static": "1.0.0-next.48", + "@sveltejs/kit": "1.0.0-next.561", + "@testing-library/jest-dom": "5.16.5", + "@testing-library/svelte": "3.2.2", + "@types/pako": "2.0.0", + "@types/uuid": "8.3.4", + "@typescript-eslint/eslint-plugin": "5.44.0", + "@typescript-eslint/parser": "5.44.0", + "@vitest/ui": "^0.25.3", + "autoprefixer": "^10.4.13", + "c8": "7.12.0", + "chai": "^4.3.7", + "cssnano": "^5.1.14", + "cy-verify-downloads": "0.1.11", + "cypress": "11.2.0", + "cypress-localstorage-commands": "2.2.1", + "eslint": "8.28.0", + "eslint-config-prettier": "8.5.0", + "eslint-plugin-cypress": "2.12.1", + "eslint-plugin-es": "4.1.0", + "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-postcss-modules": "2.0.0", + "eslint-plugin-svelte3": "4.0.0", + "eslint-plugin-tailwindcss": "3.7.0", + "eslint-plugin-vitest": "^0.0.20", + "esserializer": "1.3.5", + "font-awesome": "^4.7.0", + "husky": "^8.0.2", + "jsdom": "20.0.3", + "lint-staged": "13.0.3", + "node-html-parser": "^6.1.4", + "postcss": "^8.4.19", + "postcss-load-config": "4.0.1", + "prettier": "2.8.0", + "prettier-plugin-svelte": "^2.8.1", + "svelte": "3.53.1", + "svelte-preprocess": "4.10.7", + "tailwindcss": "^3.2.4", + "tslib": "^2.4.1", + "typescript": "4.9.3", + "vite": "^3.2.4", + "vitest": "^0.25.3" + }, + "dependencies": { + "@mermaid-js/mermaid-mindmap": "9.2.2", + "analytics": "0.8.1", + "analytics-plugin-plausible": "0.0.6", + "daisyui": "2.42.1", + "js-base64": "3.7.3", + "mermaid": "9.2.2", + "moment": "2.29.4", + "monaco-editor": "0.34.1", + "monaco-mermaid": "1.0.8", + "pako": "2.1.0", + "random-word-slugs": "0.1.6", + "svg-pan-zoom": "3.6.1", + "uuid": "9.0.0" + }, + "lint-staged": { + "*.{ts,svelte,js,css,md,json}": [ + "prettier --plugin-search-dir=. --write", + "eslint --ignore-path .gitignore " + ] + }, + "volta": { + "node": "18.12.1", + "yarn": "1.22.19" + }, + "engines": { + "node": ">=16.7" + } +} diff --git a/postcss.config.cjs b/postcss.config.cjs index 483734f1..efb41d9e 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -6,18 +6,18 @@ const mode = process.env.NODE_ENV; const dev = mode === 'development'; module.exports = { - plugins: [ - // Some plugins, like postcss-nested, need to run before Tailwind + plugins: [ + // Some plugins, like postcss-nested, need to run before Tailwind - tailwindcss, + tailwindcss, - // But others, like autoprefixer, need to run after + // But others, like autoprefixer, need to run after - autoprefixer, + autoprefixer, - !dev && - cssnano({ - preset: 'default' - }) - ] + !dev && + cssnano({ + preset: 'default' + }) + ] }; diff --git a/renovate.json b/renovate.json index 86d2a300..1413a3ce 100644 --- a/renovate.json +++ b/renovate.json @@ -1,28 +1,24 @@ { - "extends": [ - "config:base", - ":rebaseStalePrs", - "group:allNonMajor", - "schedule:earlyMondays", - ":automergeMinor", - ":automergeTesters", - ":automergeLinters", - ":automergeTypes", - ":automergePatch" - ], - "packageRules": [ - { - "matchUpdateTypes": ["minor", "patch", "pin", "digest"], - "automerge": true - }, - { - "matchDatasources": ["npm"], - "stabilityDays": 3 - } - ], - "dependencyDashboard": true, - "major": { - "dependencyDashboardApproval": true - }, - "dependencyDashboardAutoclose": true + "extends": [ + "config:base", + ":rebaseStalePrs", + "group:allNonMajor", + "schedule:earlyMondays", + ":automergeMinor", + ":automergeTesters", + ":automergeLinters", + ":automergeTypes", + ":automergePatch" + ], + "packageRules": [ + { + "matchUpdateTypes": ["minor", "patch", "pin", "digest"], + "automerge": true + } + ], + "dependencyDashboard": true, + "major": { + "dependencyDashboardApproval": true + }, + "dependencyDashboardAutoclose": true } diff --git a/src/app.html b/src/app.html index 0b9ca8f3..3dcfd710 100644 --- a/src/app.html +++ b/src/app.html @@ -1,55 +1,57 @@ - - - - Online FlowChart & Diagrams Editor - Mermaid Live Editor - - - - - - - - - - - - %sveltekit.head% - - -
%sveltekit.body%
- + + + + Online FlowChart & Diagrams Editor - Mermaid Live Editor + + + + + + + + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ diff --git a/src/app.postcss b/src/app.postcss index 1b5c3824..888c737e 100644 --- a/src/app.postcss +++ b/src/app.postcss @@ -3,8 +3,8 @@ @tailwind utilities; .input { - @apply flex-1 border-primary border-solid border-2 rounded; + @apply flex-1 border-primary border-solid border-2 rounded; } .action-btn { - @apply btn btn-primary; + @apply btn btn-primary; } diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 00000000..8188f7aa --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,14 @@ +/// + +interface ImportMetaEnv { + readonly MERMAID_RENDERER_URL?: string; + readonly MERMAID_KROKI_RENDERER_URL?: string; + readonly MERMAID_CDN_URL?: string; + readonly MERMAID_BASE_URL?: string; + readonly MERMAID_LOCAL?: boolean; + // more env variables... +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/src/global.d.ts b/src/global.d.ts index 17fa2e24..95ecd6a0 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -6,10 +6,11 @@ import type { TestingLibraryMatchers } from '@testing-library/jest-dom/matchers'; declare global { - namespace jest { - interface Matchers - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - extends TestingLibraryMatchers {} - } + namespace jest { + interface Matchers + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + // eslint-disable-next-line no-undef + extends TestingLibraryMatchers {} + } } diff --git a/src/hooks.ts b/src/hooks.server.ts similarity index 58% rename from src/hooks.ts rename to src/hooks.server.ts index 916b2c81..49af22b0 100644 --- a/src/hooks.ts +++ b/src/hooks.server.ts @@ -1,9 +1,6 @@ import type { Handle } from '@sveltejs/kit'; export const handle: Handle = async ({ event, resolve }) => { - const response = await resolve(event, { - ssr: false - }); - - return response; + const response = await resolve(event, {}); + return response; }; diff --git a/src/lib/components/Actions.svelte b/src/lib/components/Actions.svelte new file mode 100644 index 00000000..166a58cd --- /dev/null +++ b/src/lib/components/Actions.svelte @@ -0,0 +1,265 @@ + + + +
+ {#if isClipboardAvailable()} + + {/if} + + + + + + + + + + + + +
+ PNG size + + + + + + + {#if imagemodeselected !== 'auto'} + + {/if} +
+ +
+ + +
+ +
+ + +
+ {#if isNetlify} + + {/if} +
+
diff --git a/src/lib/components/Card/Card.svelte b/src/lib/components/Card/Card.svelte new file mode 100644 index 00000000..38098eb6 --- /dev/null +++ b/src/lib/components/Card/Card.svelte @@ -0,0 +1,31 @@ + + +
+
(isOpen = !isOpen)} + on:keypress={() => (isOpen = !isOpen)}> +
+ +
+ +
+
+
+ {#if isOpen} +
+ +
+ {/if} +
diff --git a/src/lib/components/Card/Tabs.svelte b/src/lib/components/Card/Tabs.svelte new file mode 100644 index 00000000..3c7c8f9d --- /dev/null +++ b/src/lib/components/Card/Tabs.svelte @@ -0,0 +1,52 @@ + + +
+ (isOpen = !isOpen)} + on:keypress|stopPropagation={() => (isOpen = !isOpen)}> + {#if isCloseable} + + {/if} + {title} + {#if isOpen && tabs} +
    + {#each tabs as tab} +
    toggleTabs(tab)} + on:keypress|stopPropagation={() => toggleTabs(tab)}> + + {tab.title} +
    + {/each} +
+ {/if} +
+ + diff --git a/src/lib/components/Card/__snapshots__/card.test.ts.snap b/src/lib/components/Card/__snapshots__/card.test.ts.snap new file mode 100644 index 00000000..c23d7e06 --- /dev/null +++ b/src/lib/components/Card/__snapshots__/card.test.ts.snap @@ -0,0 +1,3 @@ +// Vitest Snapshot v1 + +exports[`card.svelte > mounts 1`] = `"
TabTest
    title1
    title2
"`; diff --git a/src/lib/components/Card/card.test.ts b/src/lib/components/Card/card.test.ts new file mode 100644 index 00000000..36698822 --- /dev/null +++ b/src/lib/components/Card/card.test.ts @@ -0,0 +1,24 @@ +import { cleanup, render } from '@testing-library/svelte'; +import { describe, expect, it, afterEach } from 'vitest'; +import Card from './Card.svelte'; + +describe('card.svelte', () => { + // TODO: @testing-library/svelte claims to add this automatically but it doesn't work without explicit afterEach + afterEach(() => cleanup()); + + it('mounts', () => { + const { container } = render(Card, { + title: 'TabTest', + tabs: [ + { id: 't1', title: 'title1', icon: 'fab fa-git-alt' }, + { id: 't2', title: 'title2', icon: 'far fa-bookmark' } + ] + }); + expect(container).toBeTruthy(); + expect(container).toHaveTextContent('TabTest'); + expect(container).toHaveTextContent('title1'); + expect(container).toHaveTextContent('title2'); + expect(container).not.toHaveTextContent('title3'); + expect(container.innerHTML).toMatchSnapshot(); + }); +}); diff --git a/src/lib/components/Editor.svelte b/src/lib/components/Editor.svelte new file mode 100644 index 00000000..5525afe9 --- /dev/null +++ b/src/lib/components/Editor.svelte @@ -0,0 +1,131 @@ + + +
diff --git a/src/lib/components/History/History.svelte b/src/lib/components/History/History.svelte new file mode 100644 index 00000000..3663b71d --- /dev/null +++ b/src/lib/components/History/History.svelte @@ -0,0 +1,192 @@ + + + +
+ + {#if $historyStore.length > 0} + + {/if} + | + + {#if $historyModeStore !== 'loader'} + + {/if} +
+
    + {#if $historyStore.length > 0} + {#each $historyStore as { id, state, time, name, url, type }} +
  • +
    +
    +
    + {#if url} + {name} + {:else} + {name} + {/if} + {relativeTime(time)} +
    +
    +
    + + {#if type !== 'loader'} + + {/if} +
    +
    +
  • + {/each} + {:else} +
    + No items in History
    + Click the Save button to save current state and restore it later.
    + Timeline will automatically be saved every minute. +
    + {/if} +
+
diff --git a/src/lib/components/History/history.test.ts b/src/lib/components/History/history.test.ts new file mode 100644 index 00000000..482de012 --- /dev/null +++ b/src/lib/components/History/history.test.ts @@ -0,0 +1,126 @@ +import type { HistoryEntry } from '$lib/types'; +import { describe, it, expect } from 'vitest'; +import { + addHistoryEntry, + injectHistoryIDs, + clearHistoryData, + historyModeStore, + historyStore +} from './history'; +import { defaultState } from '$lib/util/state'; +import { get } from 'svelte/store'; + +describe('history', () => { + it('should handle saving individual history entry', () => { + expect(window.localStorage.getItem('manualHistoryStore')).toBe('[]'); + expect(window.localStorage.getItem('autoHistoryStore')).toBe('[]'); + + addHistoryEntry({ + state: defaultState, + time: 12345, + type: 'manual' + }); + + const [manualEntry] = JSON.parse( + window.localStorage.getItem('manualHistoryStore') ?? '[]' + ) as HistoryEntry[]; + + expect(manualEntry.time).toBe(12345); + expect(manualEntry.type).toBe('manual'); + expect(manualEntry.name).not.toBeNull(); + expect(manualEntry.state).not.toBeNull(); + + addHistoryEntry({ + state: defaultState, + time: 54321, + type: 'auto' + }); + + const [autoEntry] = JSON.parse( + window.localStorage.getItem('autoHistoryStore') ?? '[]' + ) as HistoryEntry[]; + + expect(autoEntry.time).toBe(54321); + expect(autoEntry.type).toBe('auto'); + expect(autoEntry.name).not.toBeNull(); + expect(autoEntry.state).not.toBeNull(); + + historyModeStore.set('manual'); + clearHistoryData(); + historyModeStore.set('auto'); + clearHistoryData(); + expect(window.localStorage.getItem('manualHistoryStore')).toBe('[]'); + expect(window.localStorage.getItem('autoHistoryStore')).toBe('[]'); + }); + + it('should clear history entries', () => { + addHistoryEntry({ + state: defaultState, + time: 12345, + type: 'manual' + }); + addHistoryEntry({ + state: { ...defaultState, code: 'graph TD\\n A[Christmas] -->|Get money| B(Go shopping)' }, + time: 123456, + type: 'manual' + }); + + historyModeStore.set('manual'); + const store: HistoryEntry[] = get(historyStore); + expect(store.length).toBe(2); + clearHistoryData(store[1].id); + expect(get(historyStore).length).toBe(1); + clearHistoryData(); + expect(get(historyStore).length).toBe(0); + + historyModeStore.set('auto'); + addHistoryEntry({ + state: defaultState, + time: 54321, + type: 'auto' + }); + addHistoryEntry({ + state: { ...defaultState, code: 'graph TD\\n A[Christmas] -->|Get money| B(Go shopping)' }, + time: 654321, + type: 'auto' + }); + expect(get(historyStore).length).toBe(2); + clearHistoryData(); + expect(get(historyStore).length).toBe(0); + // Test calling when history is empty + clearHistoryData(); + expect(get(historyStore).length).toBe(0); + }); +}); + +describe('history migration', () => { + it('should inject history IDs as migration', () => { + window.localStorage.setItem( + 'manualHistoryStore', + '[{"state":{"code":"graph TD\\n A[Halloween] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":false},"time":0,"type":"manual","name":"hollow-art"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"helpful-ocean"}]' + ); + window.localStorage.setItem( + 'autoHistoryStore', + '[{"state":{"code":"graph TD\\n A[New Year] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":false},"time":0,"type":"auto","name":"barking-dog"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"needy-mosquito"}]' + ); + let manualHistoryStore = JSON.parse( + window.localStorage.getItem('manualHistoryStore') ?? '[]' + ) as HistoryEntry[]; + let autoHistoryStore = JSON.parse( + window.localStorage.getItem('autoHistoryStore') ?? '[]' + ) as HistoryEntry[]; + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + + injectHistoryIDs(); + + manualHistoryStore = JSON.parse( + window.localStorage.getItem('manualHistoryStore') ?? '[]' + ) as HistoryEntry[]; + autoHistoryStore = JSON.parse( + window.localStorage.getItem('autoHistoryStore') ?? '[]' + ) as HistoryEntry[]; + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + }); +}); diff --git a/src/lib/components/History/history.ts b/src/lib/components/History/history.ts new file mode 100644 index 00000000..20f19ba3 --- /dev/null +++ b/src/lib/components/History/history.ts @@ -0,0 +1,141 @@ +import { derived, writable, get } from 'svelte/store'; +import type { Readable, Writable } from 'svelte/store'; +import { persist, localStorage } from '$lib/util/persist'; +import { generateSlug } from 'random-word-slugs'; +import type { HistoryEntry, HistoryType, Optional } from '$lib/types'; +import { v4 as uuidV4 } from 'uuid'; +import { logEvent } from '$lib/util/stats'; + +const MAX_AUTO_HISTORY_LENGTH = 30; + +export const historyModeStore: Writable = persist( + writable('manual'), + localStorage(), + 'autoHistoryMode' +); + +const autoHistoryStore: Writable = persist( + writable([]), + localStorage(), + 'autoHistoryStore' +); + +const manualHistoryStore: Writable = persist( + writable([]), + localStorage(), + 'manualHistoryStore' +); + +export const loaderHistoryStore: Writable = writable([] as HistoryEntry[]); + +export const historyStore: Readable = derived( + [historyModeStore, autoHistoryStore, manualHistoryStore, loaderHistoryStore], + ([historyMode, autoHistories, manualHistories, loadedHistories], set) => { + if (historyMode === 'auto') { + set(autoHistories); + } else if (historyMode === 'manual') { + set(manualHistories); + } else if (historyMode === 'loader') { + set(loadedHistories); + } else { + set(autoHistories); + } + } +); + +export const addHistoryEntry = (entryToAdd: Optional): void => { + const entry: HistoryEntry = { + ...entryToAdd, + id: uuidV4() + }; + + if (entry.type === 'loader') { + loaderHistoryStore.update((entries) => [entry, ...entries]); + return; + } + + if (!entry.name) { + entry.name = generateSlug(2); + } + + if (entry.type === 'auto') { + autoHistoryStore.update((entries) => { + if (entries.length >= MAX_AUTO_HISTORY_LENGTH) { + entries = entries.slice(0, MAX_AUTO_HISTORY_LENGTH - 1); + } + return [entry, ...entries]; + }); + } else if (entry.type === 'manual') { + manualHistoryStore.update((entries) => [entry, ...entries]); + logEvent('history', { action: 'save' }); + } +}; + +export const clearHistoryData = (idToClear?: string): void => { + (get(historyModeStore) === 'auto' ? autoHistoryStore : manualHistoryStore).update((entries) => { + if (get(historyModeStore) !== 'loader') { + entries = entries.filter(({ id }) => idToClear && id != idToClear); + logEvent('history', { action: 'clear', type: idToClear ? 'single' : 'all' }); + } + return entries; + }); +}; + +export const getPreviousState = (auto: boolean): string => { + const entries = get(auto ? autoHistoryStore : manualHistoryStore); + if (entries.length > 0) { + return JSON.stringify(entries[0].state); + } + return ''; +}; + +export const restoreHistory = (data: HistoryEntry[]) => { + const entries = data.filter(validateEntry); + const invalidEntryCount = data.length - entries.length; + if (invalidEntryCount > 0) { + console.error(`${invalidEntryCount} invalid history entries were removed.`); + console.error(data); + } + if (entries.length > 0) { + let entryCount = 0; + (entries[0].type === 'auto' ? autoHistoryStore : manualHistoryStore).update((existing) => { + const existingIDs = new Set(existing.map(({ id }) => id)); + const newEntries = entries.filter(({ id }) => !existingIDs.has(id)); + entryCount = newEntries.length; + const combined = [...existing, ...newEntries]; + combined.sort((a, b) => b.time - a.time); + return combined; + }); + + alert( + `${entryCount} entries restored. ${invalidEntryCount} invalid, ${ + entries.length - entryCount + } duplicates.` + ); + logEvent('history', { + action: 'restore', + success: entryCount, + invalid: invalidEntryCount, + duplicates: entries.length - entryCount + }); + } else { + alert('No valid entries found.'); + } +}; + +export const injectHistoryIDs = (): void => { + const setIDs = (entries: HistoryEntry[]) => { + for (const entry of entries) { + if (!entry.id) { + entry.id = uuidV4(); + } + } + return entries; + }; + autoHistoryStore.update(setIDs); + manualHistoryStore.update(setIDs); +}; + +const validateEntry = (entry: HistoryEntry): boolean => { + return entry.type && entry.state && entry.time && true; +}; diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte new file mode 100644 index 00000000..3ef0a3c8 --- /dev/null +++ b/src/lib/components/Navbar.svelte @@ -0,0 +1,82 @@ + + + + + + + diff --git a/src/lib/components/Preset.svelte b/src/lib/components/Preset.svelte new file mode 100644 index 00000000..ad3831ee --- /dev/null +++ b/src/lib/components/Preset.svelte @@ -0,0 +1,145 @@ + + + +
+ {#each diagramOrder as sample} + + {/each} +
+
diff --git a/src/lib/components/Theme.svelte b/src/lib/components/Theme.svelte new file mode 100644 index 00000000..ba35753e --- /dev/null +++ b/src/lib/components/Theme.svelte @@ -0,0 +1,64 @@ + + + diff --git a/src/lib/components/View.svelte b/src/lib/components/View.svelte new file mode 100644 index 00000000..8e0b6854 --- /dev/null +++ b/src/lib/components/View.svelte @@ -0,0 +1,165 @@ + + +{#if (error && $stateStore.error instanceof Error) || outOfSync} +
+ {#if error} + {@html $stateStore.error.toString().replace(/\n/g, '
')} + {:else} + Diagram out of sync.
+ Press (Sync button) or {cmdKey} + Enter to sync. + {/if} +
+{/if} + +
+
+
+ + diff --git a/src/lib/components/actions.svelte b/src/lib/components/actions.svelte deleted file mode 100644 index e504de0d..00000000 --- a/src/lib/components/actions.svelte +++ /dev/null @@ -1,251 +0,0 @@ - - - -
- {#if isClipboardAvailable()} - - {/if} - - - - - - - - - - - - - - -
- PNG size - - - - - - - {#if imagemodeselected !== 'auto'} - - {/if} -
- -
- - -
- -
- - -
- {#if isNetlify} - - {/if} -
-
diff --git a/src/lib/components/card/__snapshots__/card.test.ts.snap b/src/lib/components/card/__snapshots__/card.test.ts.snap deleted file mode 100644 index eb662c95..00000000 --- a/src/lib/components/card/__snapshots__/card.test.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Vitest Snapshot v1 - -exports[`card.svelte > mounts 1`] = `"
TabTest
    title1
    title2
"`; diff --git a/src/lib/components/card/card.svelte b/src/lib/components/card/card.svelte deleted file mode 100644 index 90b93e8a..00000000 --- a/src/lib/components/card/card.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - -
-
(isOpen = !isOpen)}> -
- -
- -
-
-
- {#if isOpen} -
- -
- {/if} -
diff --git a/src/lib/components/card/card.test.ts b/src/lib/components/card/card.test.ts deleted file mode 100644 index 98ffccd3..00000000 --- a/src/lib/components/card/card.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { cleanup, render } from '@testing-library/svelte'; -import { describe, expect, it, afterEach } from 'vitest'; -import Card from './card.svelte'; - -describe('card.svelte', () => { - // TODO: @testing-library/svelte claims to add this automatically but it doesn't work without explicit afterEach - afterEach(() => cleanup()); - - it('mounts', () => { - const { container } = render(Card, { - title: 'TabTest', - tabs: [ - { id: 't1', title: 'title1' }, - { id: 't2', title: 'title2' } - ] - }); - expect(container).toBeTruthy(); - expect(container).toHaveTextContent('TabTest'); - expect(container).toHaveTextContent('title1'); - expect(container).toHaveTextContent('title2'); - expect(container).not.toHaveTextContent('title3'); - expect(container.innerHTML).toMatchSnapshot(); - }); -}); diff --git a/src/lib/components/card/tabs.svelte b/src/lib/components/card/tabs.svelte deleted file mode 100644 index 5fe726b9..00000000 --- a/src/lib/components/card/tabs.svelte +++ /dev/null @@ -1,46 +0,0 @@ - - -
- (isOpen = !isOpen)}> - {#if isCloseable} - - {/if} - {title} - {#if isOpen && tabs} -
    - {#each tabs as tab} -
    toggleTabs(tab)}> - - {tab.title} -
    - {/each} -
- {/if} -
- - diff --git a/src/lib/components/editor.svelte b/src/lib/components/editor.svelte deleted file mode 100644 index e9299a5e..00000000 --- a/src/lib/components/editor.svelte +++ /dev/null @@ -1,96 +0,0 @@ - - -
diff --git a/src/lib/components/history/history.svelte b/src/lib/components/history/history.svelte deleted file mode 100644 index 6ee60774..00000000 --- a/src/lib/components/history/history.svelte +++ /dev/null @@ -1,142 +0,0 @@ - - - -
- - {#if $historyModeStore !== 'loader'} - - {/if} -
-
    - {#if $historyStore.length > 0} - {#each $historyStore as { state, time, name, url, type }} -
  • -
    -
    -
    - {#if url} - {name} - {:else} - {name} - {/if} - {relativeTime(time)} -
    -
    -
    - - {#if type !== 'loader'} - - {/if} -
    -
    -
  • - {/each} - {:else} -
    - No items in History
    - Click the Save button to save current state and restore it later.
    - Timeline will automatically be saved every minute. -
    - {/if} -
-
diff --git a/src/lib/components/history/history.ts b/src/lib/components/history/history.ts deleted file mode 100644 index 94586223..00000000 --- a/src/lib/components/history/history.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { derived, writable, get } from 'svelte/store'; -import type { Readable, Writable } from 'svelte/store'; -import { persist, localStorage } from '@macfja/svelte-persistent-store'; -import { generateSlug } from 'random-word-slugs'; -import type { HistoryEntry, HistoryType } from '$lib/types'; - -const MAX_AUTO_HISTORY_LENGTH = 30; - -export const historyModeStore: Writable = persist( - writable('manual'), - localStorage(), - 'autoHistoryMode' -); - -const autoHistoryStore: Writable = persist( - writable([]), - localStorage(), - 'autoHistoryStore' -); - -const manualHistoryStore: Writable = persist( - writable([]), - localStorage(), - 'manualHistoryStore' -); - -export const loaderHistoryStore: Writable = writable([] as HistoryEntry[]); - -export const historyStore: Readable = derived( - [historyModeStore, autoHistoryStore, manualHistoryStore, loaderHistoryStore], - ([historyMode, autoHistories, manualHistories, loadedHistories], set) => { - if (historyMode === 'auto') { - set(autoHistories); - } else if (historyMode === 'manual') { - set(manualHistories); - } else if (historyMode === 'loader') { - set(loadedHistories); - } else { - set(autoHistories); - } - } -); - -export const addHistoryEntry = (entry: HistoryEntry): void => { - if (entry.type === 'loader') { - loaderHistoryStore.update((entries) => [entry, ...entries]); - return; - } - entry.name = generateSlug(2); - if (entry.type !== 'auto') { - manualHistoryStore.update((entries) => [entry, ...entries]); - return; - } - autoHistoryStore.update((entries) => { - if (entries.length === MAX_AUTO_HISTORY_LENGTH) { - entries.pop(); - } - return [entry, ...entries]; - }); -}; - -export const clearHistoryData = (time?: number): void => { - (get(historyModeStore) === 'auto' ? autoHistoryStore : manualHistoryStore).update((entries) => { - if (get(historyModeStore) !== 'loader') { - entries = entries.filter((entry) => time && entry.time != time); - } - return entries; - }); -}; - -export const getPreviousState = (auto: boolean): string => { - const entries = get(auto ? autoHistoryStore : manualHistoryStore); - if (entries.length > 0) { - return JSON.stringify(entries[0].state); - } - return ''; -}; diff --git a/src/lib/components/navbar.svelte b/src/lib/components/navbar.svelte deleted file mode 100644 index bdaf56b0..00000000 --- a/src/lib/components/navbar.svelte +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - diff --git a/src/lib/components/preset.svelte b/src/lib/components/preset.svelte deleted file mode 100644 index 310b73b4..00000000 --- a/src/lib/components/preset.svelte +++ /dev/null @@ -1,113 +0,0 @@ - - - -
- {#each Object.keys(samples) as sample} - - {/each} -
-
diff --git a/src/lib/components/theme.svelte b/src/lib/components/theme.svelte deleted file mode 100644 index f7d0a88c..00000000 --- a/src/lib/components/theme.svelte +++ /dev/null @@ -1,59 +0,0 @@ - - - diff --git a/src/lib/components/view.svelte b/src/lib/components/view.svelte deleted file mode 100644 index 01ca38ad..00000000 --- a/src/lib/components/view.svelte +++ /dev/null @@ -1,123 +0,0 @@ - - -{#if error && $stateStore.error instanceof Error} -
{$stateStore.error}
-{/if} - -
-
-
- - diff --git a/src/lib/types.d.ts b/src/lib/types.d.ts index 9ff6d86b..cb70ca3e 100644 --- a/src/lib/types.d.ts +++ b/src/lib/types.d.ts @@ -1,85 +1,88 @@ -/** - * Can be made globally available by placing this - * inside `global.d.ts` and removing `export` keyword - */ -export interface Locals { - userid: string; -} - export interface MarkerData { - severity: number; - message: string; - source?: string; - startLineNumber: number; - startColumn: number; - endLineNumber: number; - endColumn: number; -} - -export interface EditorUpdateEvent { - text: string; -} -export interface EditorEvents { - update: EditorUpdateEvent; + severity: number; + message: string; + source?: string; + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; } export interface TabEvents { - select: Tab; + select: Tab; } export interface Tab { - id: string; - title: string; - icon: string; + id: string; + title: string; + icon: string; } export interface State { - code: string; - mermaid: string; - updateEditor: boolean; - updateDiagram: boolean; - autoSync: boolean; - pan?: { x: number; y: number }; - zoom?: number; - loader?: LoaderConfig; + code: string; + mermaid: string; + updateDiagram: boolean; + autoSync: boolean; + editorMode?: EditorMode; + panZoom?: boolean; + pan?: { x: number; y: number }; + zoom?: number; + loader?: LoaderConfig; } export interface ValidatedState extends State { - error: unknown; - errorMarkers: MarkerData[]; - serialized: string; + editorMode: EditorMode; + error?: Error; + errorMarkers: MarkerData[]; + serialized: string; } export interface GistLoaderConfig { - url: string; + url: string; } export interface LoadingState { - loading: boolean; - message?: string; + loading: boolean; + message?: string; } export interface FileLoaderConfig { - codeURL: string; - configURL?: string; + codeURL: string; + configURL?: string; } export interface LoaderConfig { - type: 'gist' | 'files'; - config: GistLoaderConfig | FileLoaderConfig; + type: 'gist' | 'files'; + config: GistLoaderConfig | FileLoaderConfig; } export type HistoryType = 'auto' | 'manual' | 'loader'; -export interface HistoryEntry { - state: State; - time: number; - name?: string; - type: HistoryType; - url?: string; -} +export type HistoryEntry = { id: string; state: State; time: number; url?: string } & ( + | { + type: 'loader'; + name: string; + } + | { + type: HistoryType; + name?: string; + } +); -export interface DocConfig { - [key: string]: { - code: string; - config?: string; - }; -} +export type DocConfig = Record< + string, + { + code: string; + config?: string; + } +>; + +export type EditorMode = 'code' | 'config'; export type Loader = (url: string) => Promise; +export type Optional = Pick, K> & Omit; + +export interface ErrorHash { + loc: { + first_line: number; + last_line: number; + first_column: number; + last_column: number; + }; +} diff --git a/src/lib/util/env.ts b/src/lib/util/env.ts index 128761f2..2c14a52e 100644 --- a/src/lib/util/env.ts +++ b/src/lib/util/env.ts @@ -1,4 +1,9 @@ -export const rendererUrl: string = - (import.meta.env.MERMAID_RENDERER_URL as string) ?? 'https://mermaid.ink'; -export const krokiRendererUrl: string = - (import.meta.env.MERMAID_KROKI_RENDERER_URL as string) ?? 'https://kroki.io'; +export const env = { + rendererUrl: import.meta.env.MERMAID_RENDERER_URL ?? 'https://mermaid.ink', + krokiRendererUrl: import.meta.env.MERMAID_KROKI_RENDERER_URL ?? 'https://kroki.io', + mermaidCDNUrl: import.meta.env.MERMAID_CDN_URL ?? 'https://unpkg.com/@mermaid-js', + mermaidBaseURL: import.meta.env.MERMAID_BASE_URL ?? 'http://localhost:9000', + useLocalMermaid: import.meta.env.MERMAID_LOCAL ?? false, + isDev: import.meta.env.DEV, + baseURL: import.meta.env.BASE_URL +}; diff --git a/src/lib/util/fileLoaders/gist.ts b/src/lib/util/fileLoaders/gist.ts index 6304f9c5..58ff85ea 100644 --- a/src/lib/util/fileLoaders/gist.ts +++ b/src/lib/util/fileLoaders/gist.ts @@ -3,105 +3,124 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { State } from '$lib/types'; -import { defaultState } from '../state'; -import { addHistoryEntry } from '../../components/history/history'; +import { defaultState } from '$lib/util/state'; +import { addHistoryEntry } from '$lib/components/History/history'; const codeFileName = 'code.mmd'; const configFileName = 'config.json'; +interface GithubFile { + truncated: boolean; + raw_url: string; + content: string; +} + const isValidGist = (files: any): boolean => { - return codeFileName in files; + return codeFileName in files; }; -const getFileContent = async (file: any): Promise => { - if (file.truncated) { - return await (await fetch(file.raw_url)).text(); - } - return file.content; +const getFileContent = async (file: GithubFile): Promise => { + if (file.truncated) { + return await (await fetch(file.raw_url)).text(); + } + return file.content; }; interface GistData { - code: string; - config?: string; - author: string; - time: number; - version: string; - url: string; + code: string; + config?: string; + author: string; + time: number; + version: string; + url: string; +} + +interface GistResponse { + files: Record; + html_url: string; + history: { url: string; committed_at: string; version: string; user: { login: string } }[]; } const getGistData = async (gistURL: string): Promise => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [_, __, gistID, revisionID] = gistURL.split('github.com').pop().split('/'); - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const { html_url, files, history } = await ( - await fetch(`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`) - ).json(); - if (isValidGist(files)) { - const code = await getFileContent(files[codeFileName]); - let config: string; - if (configFileName in files) { - config = await getFileContent(files[configFileName]); - } - const currentItem = history[0]; - return { - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - url: `${html_url}/${currentItem.version}`, - code, - config, - author: currentItem.user.login, - time: new Date(currentItem.committed_at).getTime(), - version: (currentItem.version as string).slice(-7) - }; - } else { - throw 'Invalid gist provided'; - } + const path = gistURL.split('github.com').pop(); + if (!path) { + throw new Error('Invalid GitHub URL' + gistURL); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [_, __, gistID, revisionID] = path.split('/'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { html_url, files, history }: GistResponse = await ( + await fetch(`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`) + ).json(); + if (isValidGist(files)) { + const code = await getFileContent(files[codeFileName]); + let config = '{}'; + if (configFileName in files) { + config = await getFileContent(files[configFileName]); + } + const currentItem = history[0]; + return { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + url: `${html_url}/${currentItem.version}`, + code, + config, + author: currentItem.user.login, + time: new Date(currentItem.committed_at).getTime(), + version: currentItem.version.slice(-7) + }; + } else { + throw new Error('Invalid gist provided'); + } }; const getStateFromGist = (gist: GistData, gistURL: string = gist.url): State => { - const state: State = { - ...defaultState, - code: gist.code, - loader: { - type: 'gist', - config: { - url: gistURL - } - } - }; - gist.config && (state.mermaid = gist.config); - return state; + const state: State = { + ...defaultState, + code: gist.code, + loader: { + type: 'gist', + config: { + url: gistURL + } + } + }; + gist.config && (state.mermaid = gist.config); + return state; }; export const loadGistData = async (gistURL: string): Promise => { - try { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [_, __, gistID, revisionID] = gistURL.split('github.com').pop().split('/'); - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const { history } = await ( - await fetch(`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`) - ).json(); - const gistHistory: GistData[] = []; - for (const entry of history) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const data: GistData = await getGistData(entry.url).catch(() => undefined); - data && gistHistory.push(data); - } - if (gistHistory.length === 0) { - throw 'Invalid gist provided'; - } - gistHistory.reverse(); - const state = getStateFromGist(gistHistory.slice(-1).pop(), gistURL); - for (const gist of gistHistory) { - addHistoryEntry({ - state: getStateFromGist(gist), - time: gist.time, - type: 'loader', - url: gist.url, - name: `${gist.author} v${gist.version}` - }); - } - return state; - } catch (err) { - console.error(err); - } + const path = gistURL.split('github.com').pop(); + if (!path) { + throw new Error('Invalid GitHub URL' + gistURL); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [_, __, gistID, revisionID] = path.split('/'); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { history }: GistResponse = await ( + await fetch(`https://api.github.com/gists/${gistID}${revisionID ? '/' + revisionID : ''}`) + ).json(); + const gistHistory: GistData[] = []; + for (const entry of history) { + const data: GistData | undefined = await getGistData(entry.url).catch(() => undefined); + data && gistHistory.push(data); + } + if (gistHistory.length === 0) { + throw new Error('Invalid gist provided'); + } + gistHistory.reverse(); + const entry = gistHistory.slice(-1).pop(); + if (!entry) { + throw new Error('Invalid gist provided'); + } + const state = getStateFromGist(entry, gistURL); + for (const gist of gistHistory) { + addHistoryEntry({ + state: getStateFromGist(gist), + time: gist.time, + type: 'loader', + url: gist.url, + name: `${gist.author} v${gist.version}` + }); + } + return state; }; diff --git a/src/lib/util/fileLoaders/loader.ts b/src/lib/util/fileLoaders/loader.ts index ea63800a..596d02a2 100644 --- a/src/lib/util/fileLoaders/loader.ts +++ b/src/lib/util/fileLoaders/loader.ts @@ -2,59 +2,59 @@ import { loadGistData } from './gist'; import { updateCodeStore, defaultState } from '../state'; import type { Loader, State } from '$lib/types'; const loaders: Record = { - gist: loadGistData + gist: loadGistData }; export const loadDataFromUrl = async (): Promise => { - const searchParams = new URLSearchParams(window.location.search); - let state: Partial = defaultState; - let code: string, config: string; - let loaded = false; - const codeURL: string = searchParams.get('code'); - const configURL: string = searchParams.get('config'); + const searchParams = new URLSearchParams(window.location.search); + let state: Partial = defaultState; + let code: string | undefined = undefined; + let config: string | undefined = undefined; + let loaded = false; + const codeURL: string | undefined = searchParams.get('code') ?? undefined; + const configURL: string | undefined = searchParams.get('config') ?? undefined; - if (codeURL) { - code = await (await fetch(codeURL)).text(); - loaded = true; - } - if (configURL) { - config = await (await fetch(configURL)).text(); - } else { - config = defaultState.mermaid; - } - if (!code) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - for (const [key, value] of searchParams.entries()) { - if (key in loaders) { - try { - state = await loaders[key](value); - loaded = true; - break; - } catch (err) { - console.error(err); - } - } - } - } else { - state = { - code, - mermaid: config, - loader: { - type: 'files', - config: { - codeURL, - configURL - } - } - }; - } - loaded && - updateCodeStore({ - ...state, - autoSync: true, - updateDiagram: true, - updateEditor: true - }); + if (codeURL) { + code = await (await fetch(codeURL)).text(); + loaded = true; + } + if (configURL) { + config = await (await fetch(configURL)).text(); + } else { + config = defaultState.mermaid; + } + if (!code) { + for (const [key, value] of searchParams.entries()) { + if (key in loaders) { + try { + state = await loaders[key](value); + loaded = true; + break; + } catch (err) { + console.error(err); + } + } + } + } else { + if (!codeURL) { + throw new Error('Code URL is not defined'); + } + state = { + code, + mermaid: config, + loader: { + type: 'files', + config: { + codeURL, + configURL + } + } + }; + } + loaded && + updateCodeStore({ + ...state, + autoSync: true, + updateDiagram: true + }); }; diff --git a/src/lib/util/loading.ts b/src/lib/util/loading.ts index 0d483c91..cebe1947 100644 --- a/src/lib/util/loading.ts +++ b/src/lib/util/loading.ts @@ -3,18 +3,18 @@ import type { Writable } from 'svelte/store'; import type { LoadingState } from '$lib/types'; const defaultLoading: LoadingState = { - loading: false + loading: false }; export const loadingStateStore: Writable = writable(defaultLoading); export const initLoading = async (message: string, task: Promise): Promise => { - loadingStateStore.set({ - loading: true, - message - }); - const result: T = await task; - loadingStateStore.set({ - loading: false - }); - return result; + loadingStateStore.set({ + loading: true, + message + }); + const result: T = await task; + loadingStateStore.set({ + loading: false + }); + return result; }; diff --git a/src/lib/util/mermaid.ts b/src/lib/util/mermaid.ts new file mode 100644 index 00000000..f4d09e72 --- /dev/null +++ b/src/lib/util/mermaid.ts @@ -0,0 +1,27 @@ +import mermaid, { type MermaidConfig } from 'mermaid'; +import mindmap from '@mermaid-js/mermaid-mindmap'; + +const initialize = mermaid.registerExternalDiagrams([mindmap]); + +export const init = async () => { + await initialize; +}; + +export const render = async ( + config: MermaidConfig, + code: string, + id: string, + callback: Parameters[2] +): Promise => { + // Should be able to call this multiple times without any issues. + mermaid.initialize(config); + // console.log('Rendering', code); + // mermaid.mermaidAPI.render(id, code, callback); + await init(); + await mermaid.mermaidAPI.renderAsync(id, code, callback); +}; + +export const parse = async (code: string): Promise => { + await init(); + return await mermaid.parseAsync(code); +}; diff --git a/src/lib/util/migrations.test.ts b/src/lib/util/migrations.test.ts new file mode 100644 index 00000000..8c7a3a28 --- /dev/null +++ b/src/lib/util/migrations.test.ts @@ -0,0 +1,38 @@ +import type { HistoryEntry } from '$lib/types'; +import { describe, it, expect, beforeEach } from 'vitest'; + +describe('migrations', () => { + beforeEach(() => { + window.localStorage.setItem( + 'manualHistoryStore', + '[{"state":{"code":"graph TD\\n A[Halloween] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":false},"time":0,"type":"manual","name":"hollow-art"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"helpful-ocean"}]' + ); + window.localStorage.setItem( + 'autoHistoryStore', + '[{"state":{"code":"graph TD\\n A[New Year] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":false},"time":0,"type":"auto","name":"barking-dog"},{"state":{"code":"graph TD\\n A[Christmas] -->|Get money| B(Go shopping)","mermaid":"{\\n \\"theme\\": \\"dark\\"\\n}","autoSync":true,"updateDiagram":true},"time":0,"type":"manual","name":"needy-mosquito"}]' + ); + }); + + it('should migrate from v0 to v1', async () => { + const { applyMigrations } = await import('./migrations'); + let manualHistoryStore: HistoryEntry[] = JSON.parse( + window.localStorage.getItem('manualHistoryStore') ?? '[]' + ) as HistoryEntry[]; + let autoHistoryStore: HistoryEntry[] = JSON.parse( + window.localStorage.getItem('autoHistoryStore') ?? '[]' + ) as HistoryEntry[]; + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(false); + + applyMigrations(); + + manualHistoryStore = JSON.parse( + window.localStorage.getItem('manualHistoryStore') ?? '[]' + ) as HistoryEntry[]; + autoHistoryStore = JSON.parse( + window.localStorage.getItem('autoHistoryStore') ?? '[]' + ) as HistoryEntry[]; + expect(manualHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + expect(autoHistoryStore.every(({ id }) => id !== undefined)).toBe(true); + }); +}); diff --git a/src/lib/util/migrations.ts b/src/lib/util/migrations.ts new file mode 100644 index 00000000..7851270b --- /dev/null +++ b/src/lib/util/migrations.ts @@ -0,0 +1,35 @@ +import { writable, get, type Writable } from 'svelte/store'; +import { persist, localStorage } from '$lib/util/persist'; +import { injectHistoryIDs } from '$lib/components/History/history'; +import { logEvent } from './stats'; + +interface MigrationState { + version: number; +} + +const migrations: Record void> = { + injectHistoryIDs +}; + +const migrationStore: Writable = persist( + writable({ version: -1 }), + localStorage(), + 'migrations' +); + +export const applyMigrations = (): void => { + const { version }: MigrationState = get(migrationStore); + const allMigrations = Object.entries(migrations); + if (version === allMigrations.length - 1) { + return; + } + console.log(`Current migration version: v${version}. Migrating to v${allMigrations.length - 1}.`); + for (let i = version + 1; i < allMigrations.length; i++) { + const [key, fn] = allMigrations[i]; + console.log(`Applying migration ${i}: ${key}.`); + fn(); + logEvent('migration', { key }); + migrationStore.set({ version: i }); + } + logEvent('migration', { status: 'complete', from: version, to: allMigrations.length - 1 }); +}; diff --git a/src/lib/util/notify.ts b/src/lib/util/notify.ts index b9c54a27..3c9e6ded 100644 --- a/src/lib/util/notify.ts +++ b/src/lib/util/notify.ts @@ -1,7 +1,7 @@ export const notify = (message: string): void => { - alert(message); + alert(message); }; export const prompt = (message: string): boolean => { - return confirm(message); + return confirm(message); }; diff --git a/src/lib/util/persist.ts b/src/lib/util/persist.ts new file mode 100644 index 00000000..31aeba3f --- /dev/null +++ b/src/lib/util/persist.ts @@ -0,0 +1,259 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +// Copied from https://github.com/MacFJA/svelte-persistent-store +// # The MIT License (MIT) + +// Copyright (c) 2021 [MacFJA](https://github.com/MacFJA) + +// > Permission is hereby granted, free of charge, to any person obtaining a copy +// > of this software and associated documentation files (the "Software"), to deal +// > in the Software without restriction, including without limitation the rights +// > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// > copies of the Software, and to permit persons to whom the Software is +// > furnished to do so, subject to the following conditions: +// > +// > The above copyright notice and this permission notice shall be included in +// > all copies or substantial portions of the Software. +// > +// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// > THE SOFTWARE. + +import ESSerializer from 'esserializer'; +import type { Writable } from 'svelte/store'; + +/** + * Disabled warnings about missing/unavailable storages + */ +export function disableWarnings(): void { + noWarnings = true; +} +/** + * If set to true, no warning will be emitted if the requested Storage is not found. + * This option can be useful when the lib is used on a server. + */ +let noWarnings = false; +/** + * List of storages where the warning have already been displayed. + */ +const alreadyWarnFor: string[] = []; + +/** + * Add a log to indicate that the requested Storage have not been found. + * @param {string} storageName + */ +const warnStorageNotFound = (storageName: string) => { + const isProduction = typeof process !== 'undefined' && process.env.NODE_ENV === 'production'; + + if (!noWarnings && !alreadyWarnFor.includes(storageName) && !isProduction) { + let message = `Unable to find the ${storageName}. No data will be persisted.`; + if (typeof window === 'undefined') { + message += + '\n' + + 'Are you running on a server? Most of storages are not available while running on a server.'; + } + console.warn(message); + alreadyWarnFor.push(storageName); + } +}; + +const serialize = (value: unknown): string => ESSerializer.serialize(value); +const deserialize = (value?: string | null): unknown => { + // @TODO: to remove in the next major + if (value === 'undefined') { + return undefined; + } + + if (value !== null && value !== undefined) { + try { + return ESSerializer.deserialize(value); + } catch (e) { + // Do nothing + // use the value "as is" + } + try { + return JSON.parse(value); + } catch (e) { + // Do nothing + // use the value "as is" + } + } + return value; +}; + +/** + * A store that keep it's value in time. + */ +export interface PersistentStore extends Writable { + /** + * Delete the store value from the persistent storage + */ + delete(): void; +} + +/** + * Storage interface + */ +export interface StorageInterface { + /** + * Get a value from the storage. + * + * If the value doesn't exists in the storage, `null` should be returned. + * This method MUST be synchronous. + * @param key The key/name of the value to retrieve + */ + getValue(key: string): T | null; + + /** + * Save a value in the storage. + * @param key The key/name of the value to save + * @param value The value to save + */ + setValue(key: string, value: T): void; + + /** + * Remove a value from the storage + * @param key The key/name of the value to remove + */ + deleteValue(key: string): void; +} + +export interface SelfUpdateStorageInterface extends StorageInterface { + /** + * Add a listener to the storage values changes + * @param {string} key The key to listen + * @param {(newValue: T) => void} listener The listener callback function + */ + addListener(key: string, listener: (newValue: T) => void): void; + /** + * Remove a listener from the storage values changes + * @param {string} key The key that was listened + * @param {(newValue: T) => void} listener The listener callback function to remove + */ + removeListener(key: string, listener: (newValue: T) => void): void; +} + +/** + * Make a store persistent + * @param {Writable<*>} store The store to enhance + * @param {StorageInterface} storage The storage to use + * @param {string} key The name of the data key + */ +export function persist( + store: Writable, + storage: StorageInterface, + key: string +): PersistentStore { + const initialValue = storage.getValue(key); + + if (null !== initialValue) { + store.set(initialValue); + } + + if ('addListener' in storage) { + (storage as SelfUpdateStorageInterface).addListener(key, (newValue) => { + store.set(newValue); + }); + } + + store.subscribe((value) => { + storage.setValue(key, value); + }); + + return { + ...store, + delete() { + storage.deleteValue(key); + } + }; +} + +function getBrowserStorage( + browserStorage: Storage, + listenExternalChanges = false +): SelfUpdateStorageInterface { + const listeners: { key: string; listener: (newValue: any) => void }[] = []; + const listenerFunction = (event: StorageEvent) => { + const eventKey = event.key; + if (event.storageArea === browserStorage) { + listeners + .filter(({ key }) => key === eventKey) + .forEach(({ listener }) => { + listener(deserialize(event.newValue)); + }); + } + }; + const connect = () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (listenExternalChanges && typeof window !== 'undefined' && window.addEventListener) { + window.addEventListener('storage', listenerFunction); + } + }; + const disconnect = () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (listenExternalChanges && typeof window !== 'undefined' && window.removeEventListener) { + window.removeEventListener('storage', listenerFunction); + } + }; + + return { + addListener(key: string, listener: (newValue: any) => void) { + listeners.push({ key, listener }); + if (listeners.length === 1) { + connect(); + } + }, + removeListener(key: string, listener: (newValue: any) => void) { + const index = listeners.indexOf({ key, listener }); + if (index !== -1) { + listeners.splice(index, 1); + } + if (listeners.length === 0) { + disconnect(); + } + }, + getValue(key: string): any | null { + const value = browserStorage.getItem(key); + return deserialize(value); + }, + deleteValue(key: string) { + browserStorage.removeItem(key); + }, + setValue(key: string, value: any) { + browserStorage.setItem(key, serialize(value)); + } + }; +} + +/** + * Storage implementation that use the browser local storage + * @param listenExternalChanges - Update the store if the localStorage is updated from another page + */ +export function localStorage(listenExternalChanges = false): StorageInterface { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (typeof window !== 'undefined' && window.localStorage) { + return getBrowserStorage(window.localStorage, listenExternalChanges); + } + warnStorageNotFound('window.localStorage'); + return noopStorage(); +} + +/** + * Storage implementation that do nothing + */ +export function noopStorage(): StorageInterface { + return { + getValue(): null { + return null; + }, + deleteValue() { + // Do nothing + }, + setValue() { + // Do nothing + } + }; +} diff --git a/src/lib/util/serde.test.ts b/src/lib/util/serde.test.ts index 51171e8f..c66f7f0f 100644 --- a/src/lib/util/serde.test.ts +++ b/src/lib/util/serde.test.ts @@ -4,37 +4,37 @@ import { defaultState } from './state'; import type { State } from '$lib/types'; describe('Serde tests', () => { - const verifySerde = (state: State, serde?: SerdeType): string => { - const serialized = serializeState(state, serde); - const deserialized = deserializeState(serialized); - expect(deserialized).to.deep.equal(state); - return serialized; - }; + const verifySerde = (state: State, serde?: SerdeType): string => { + const serialized = serializeState(state, serde); + const deserialized = deserializeState(serialized); + expect(deserialized).to.deep.equal(state); + return serialized; + }; - it('should serialize and deserialize with default serde', () => { - expect(verifySerde(defaultState)).toMatchInlineSnapshot( - '"pako:eNpVkM1qw0AMhF9F6JRC_AI-FBo7ySXQQnPz5iC8cnZp9oe1TAm2373rmEKik5j5ZhAasQ2ascRromjgXCsPeT6ayiTbi6P-AkXxPh1ZwAXP9wl2m2OA3oQYrb--rfxugaAaTwvGIMb6n3m1qkf-0_MEdXOiKCFenp3zb5hg39gvk-tfHZM4pw5NR2VHRUsJKkoPBLfoODmyOp8-LopCMexYYZlXzR0NN1Go_JzRIWoS3msrIWGuuvW8RRokfN99i6Wkgf-h2lL-hFvF-Q9-YFyS"' - ); - }); + it('should serialize and deserialize with default serde', () => { + expect(verifySerde(defaultState)).toMatchInlineSnapshot( + '"pako:eNpVj81qw0AMhF9F6NRC_AI-BGK7zSXQQHLz5iBsObuk-8Naphjb7551fEl1EjPfiNGEjW8Zc7xHChqulXKQ5lCXOppeLPU3yLL9fGQB6x2PMxQfRw-99iEYd__c-GKFoJxOK8Yg2rjHslnlK__jeIaqPlEQH27vzvXPz_BVm7NO5_87OnJKfdcd5R1lDUUoKb4Q3KHlaMm0qfq0KgpFs2WFeVpb7mj4FYXKLQmlQfxldA3mEgfe4RBaEq4MpaftJi5PNtJU8w"' + ); + }); - it('should serialize and deserialize with base64 serde', () => { - expect(verifySerde(defaultState, 'base64')).toMatchInlineSnapshot( - '"base64:eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0NocmlzdG1hc10gLS0-fEdldCBtb25leXwgQihHbyBzaG9wcGluZylcbiAgICBCIC0tPiBDe0xldCBtZSB0aGlua31cbiAgICBDIC0tPnxPbmV8IERbTGFwdG9wXVxuICAgIEMgLS0-fFR3b3wgRVtpUGhvbmVdXG4gICAgQyAtLT58VGhyZWV8IEZbZmE6ZmEtY2FyIENhcl1cbiAgIiwibWVybWFpZCI6IntcbiAgXCJ0aGVtZVwiOiBcImRlZmF1bHRcIlxufSIsInVwZGF0ZUVkaXRvciI6ZmFsc2UsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjp0cnVlfQ"' - ); - }); + it('should serialize and deserialize with base64 serde', () => { + expect(verifySerde(defaultState, 'base64')).toMatchInlineSnapshot( + '"base64:eyJjb2RlIjoiZ3JhcGggVERcbiAgICBBW0NocmlzdG1hc10gLS0-fEdldCBtb25leXwgQihHbyBzaG9wcGluZylcbiAgICBCIC0tPiBDe0xldCBtZSB0aGlua31cbiAgICBDIC0tPnxPbmV8IERbTGFwdG9wXVxuICAgIEMgLS0-fFR3b3wgRVtpUGhvbmVdXG4gICAgQyAtLT58VGhyZWV8IEZbZmE6ZmEtY2FyIENhcl1cbiAgIiwibWVybWFpZCI6IntcbiAgXCJ0aGVtZVwiOiBcImRlZmF1bHRcIlxufSIsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjp0cnVlfQ"' + ); + }); - it('should serialize and deserialize with pako serde', () => { - expect(verifySerde(defaultState, 'pako')).toMatchInlineSnapshot( - '"pako:eNpVkM1qw0AMhF9F6JRC_AI-FBo7ySXQQnPz5iC8cnZp9oe1TAm2373rmEKik5j5ZhAasQ2ascRromjgXCsPeT6ayiTbi6P-AkXxPh1ZwAXP9wl2m2OA3oQYrb--rfxugaAaTwvGIMb6n3m1qkf-0_MEdXOiKCFenp3zb5hg39gvk-tfHZM4pw5NR2VHRUsJKkoPBLfoODmyOp8-LopCMexYYZlXzR0NN1Go_JzRIWoS3msrIWGuuvW8RRokfN99i6Wkgf-h2lL-hFvF-Q9-YFyS"' - ); - }); + it('should serialize and deserialize with pako serde', () => { + expect(verifySerde(defaultState, 'pako')).toMatchInlineSnapshot( + '"pako:eNpVj81qw0AMhF9F6NRC_AI-BGK7zSXQQHLz5iBsObuk-8Naphjb7551fEl1EjPfiNGEjW8Zc7xHChqulXKQ5lCXOppeLPU3yLL9fGQB6x2PMxQfRw-99iEYd__c-GKFoJxOK8Yg2rjHslnlK__jeIaqPlEQH27vzvXPz_BVm7NO5_87OnJKfdcd5R1lDUUoKb4Q3KHlaMm0qfq0KgpFs2WFeVpb7mj4FYXKLQmlQfxldA3mEgfe4RBaEq4MpaftJi5PNtJU8w"' + ); + }); - it('should throw error for unrecognized serde', () => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - expect(() => serializeState(defaultState, 'unknown')).toThrowError( - 'Unknown serde type: unknown' - ); - expect(() => deserializeState('unknown:hello')).toThrowError('Unknown serde type: unknown'); - }); + it('should throw error for unrecognized serde', () => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + expect(() => serializeState(defaultState, 'unknown')).toThrowError( + 'Unknown serde type: unknown' + ); + expect(() => deserializeState('unknown:hello')).toThrowError('Unknown serde type: unknown'); + }); }); diff --git a/src/lib/util/serde.ts b/src/lib/util/serde.ts index 643401ff..5dbffa1b 100644 --- a/src/lib/util/serde.ts +++ b/src/lib/util/serde.ts @@ -3,61 +3,61 @@ import { toUint8Array, fromUint8Array, toBase64, fromBase64 } from 'js-base64'; import type { State } from '$lib/types'; interface Serde { - serialize: (state: string) => string; - deserialize: (state: string) => string; + serialize: (state: string) => string; + deserialize: (state: string) => string; } const base64Serde: Serde = { - serialize: (state: string): string => { - return toBase64(state, true); - }, - deserialize: (state: string): string => { - return fromBase64(state); - } + serialize: (state: string): string => { + return toBase64(state, true); + }, + deserialize: (state: string): string => { + return fromBase64(state); + } }; export const pakoSerde: Serde = { - serialize: (state: string): string => { - const data = new TextEncoder().encode(state); - const compressed = deflate(data, { level: 9 }); - return fromUint8Array(compressed, true); - }, - deserialize: (state: string): string => { - const data = toUint8Array(state); - return inflate(data, { to: 'string' }); - } + serialize: (state: string): string => { + const data = new TextEncoder().encode(state); + const compressed = deflate(data, { level: 9 }); + return fromUint8Array(compressed, true); + }, + deserialize: (state: string): string => { + const data = toUint8Array(state); + return inflate(data, { to: 'string' }); + } }; export type SerdeType = 'base64' | 'pako'; const serdes: { [key in SerdeType]: Serde } = { - base64: base64Serde, - pako: pakoSerde + base64: base64Serde, + pako: pakoSerde }; export const serializeState = (state: State, serde: SerdeType = 'pako'): string => { - if (serdes[serde] === undefined) { - throw new Error(`Unknown serde type: ${serde}`); - } - const json = JSON.stringify(state); - const serialized = serdes[serde].serialize(json); - return `${serde}:${serialized}`; + if (!(serde in serdes)) { + throw new Error(`Unknown serde type: ${serde}`); + } + const json = JSON.stringify(state); + const serialized = serdes[serde].serialize(json); + return `${serde}:${serialized}`; }; export const deserializeState = (state: string): State => { - let type: SerdeType, serialized: string; - if (state.includes(':')) { - let tempType: string; - [tempType, serialized] = state.split(':'); - if (tempType in serdes) { - type = tempType as SerdeType; - } else { - throw new Error(`Unknown serde type: ${tempType}`); - } - } else { - type = 'base64'; - serialized = state; - } - const json = serdes[type].deserialize(serialized); - return JSON.parse(json) as State; + let type: SerdeType, serialized: string; + if (state.includes(':')) { + let tempType: string; + [tempType, serialized] = state.split(':'); + if (tempType in serdes) { + type = tempType as SerdeType; + } else { + throw new Error(`Unknown serde type: ${tempType}`); + } + } else { + type = 'base64'; + serialized = state; + } + const json = serdes[type].deserialize(serialized); + return JSON.parse(json) as State; }; diff --git a/src/lib/util/state.ts b/src/lib/util/state.ts index 4294f39a..1dc7ed11 100644 --- a/src/lib/util/state.ts +++ b/src/lib/util/state.ts @@ -1,31 +1,30 @@ -import { writable, get, derived } from 'svelte/store'; -import { persist, localStorage } from '@macfja/svelte-persistent-store'; -import { saveStatistics } from './stats'; +import { writable, get, type Readable, derived } from 'svelte/store'; +import { persist, localStorage } from './persist'; +import { saveStatistics, countLines } from './stats'; import { serializeState, deserializeState } from './serde'; -import { cmdKey } from './util'; -import mermaid from 'mermaid'; +import { cmdKey, errorDebug } from './util'; +import { parse } from './mermaid'; -import type { Readable } from 'svelte/store'; -import type { MarkerData, State, ValidatedState } from '$lib/types'; +import type { ErrorHash, MarkerData, State, ValidatedState } from '$lib/types'; +import type { MermaidConfig } from 'mermaid'; export const defaultState: State = { - code: `graph TD + code: `graph TD A[Christmas] -->|Get money| B(Go shopping) B --> C{Let me think} C -->|One| D[Laptop] C -->|Two| E[iPhone] C -->|Three| F[fa:fa-car Car] `, - mermaid: JSON.stringify( - { - theme: 'default' - }, - null, - 2 - ), - updateEditor: false, - autoSync: true, - updateDiagram: true + mermaid: JSON.stringify( + { + theme: 'default' + }, + null, + 2 + ), + autoSync: true, + updateDiagram: true }; const urlParseFailedState = `graph TD @@ -42,131 +41,164 @@ const urlParseFailedState = `graph TD // inputStateStore handles all updates and is shared externally when exporting via URL, History, etc. export const inputStateStore = persist(writable(defaultState), localStorage(), 'codeStore'); +export const currentState: ValidatedState = (() => { + const state = get(inputStateStore); + return { + ...state, + serialized: serializeState(state), + errorMarkers: [], + error: undefined, + editorMode: state.editorMode ?? 'code' + }; +})(); + +const processState = async (state: State) => { + const processed: ValidatedState = { + ...state, + serialized: '', + errorMarkers: [], + error: undefined, + editorMode: state.editorMode ?? 'code' + }; + // No changes should be done to fields part of `state`. + try { + processed.serialized = serializeState(state); + await parse(state.code); + JSON.parse(state.mermaid); + } catch (e) { + processed.error = e as Error; + errorDebug(); + console.error(e); + if ('hash' in e) { + try { + const { + loc: { first_line, last_line, first_column, last_column } + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + } = e.hash as ErrorHash; + const marker: MarkerData = { + severity: 8, // Error + startLineNumber: first_line, + startColumn: first_column, + endLineNumber: last_line, + endColumn: last_column + 1, + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + message: e.str + }; + processed.errorMarkers = [marker]; + } catch (err) { + console.error('Error without line helper', err); + } + } + } + return processed; +}; + // All internal reads should be done via stateStore, but it should not be persisted/shared externally. -export const stateStore: Readable = derived([inputStateStore], ([state]) => { - const processed: ValidatedState = { - ...state, - serialized: '', - errorMarkers: [], - error: undefined - }; - // No changes should be done to fields part of `state`. - try { - processed.serialized = serializeState(state); - mermaid.parse(state.code); - JSON.parse(state.mermaid); - } catch (e) { - processed.error = e; - console.error(e); - if (e.hash) { - try { - const marker: MarkerData = { - severity: 8, // Error - startLineNumber: e.hash.loc.first_line, - startColumn: e.hash.loc.first_column, - endLineNumber: e.hash.loc.last_line, - endColumn: (e.hash.loc.last_column as number) + 1, - message: e.str - }; - processed.errorMarkers = [marker]; - } catch (err) { - console.error('Error without line helper', err); - } - } - } - return processed; -}); +export const stateStore: Readable = derived( + [inputStateStore], + ([state], set) => { + void processState(state).then(set); + }, + currentState +); export const loadState = (data: string): void => { - let state: State; - console.log(`Loading '${data}'`); - try { - state = deserializeState(data); - const mermaidConfig: { [key: string]: string } = - typeof state.mermaid === 'string' ? JSON.parse(state.mermaid) : state.mermaid; - if ( - mermaidConfig.securityLevel && - mermaidConfig.securityLevel !== 'strict' && - confirm( - `Removing "securityLevel":"${mermaidConfig.securityLevel}" from the config for safety.\nClick Cancel if you trust the source of this Diagram.` - ) - ) { - delete mermaidConfig.securityLevel; // Prevent setting overriding securityLevel when loading state to mitigate possible XSS attack - } - state.mermaid = JSON.stringify(mermaidConfig, null, 2); - } catch (e) { - state = get(inputStateStore); - if (data) { - console.error('Init error', e); - state.code = urlParseFailedState; - state.mermaid = defaultState.mermaid; - } - } - updateCodeStore({ ...state, updateEditor: true }); + let state: State; + console.log(`Loading '${data}'`); + try { + state = deserializeState(data); + const mermaidConfig: MermaidConfig = + typeof state.mermaid === 'string' + ? (JSON.parse(state.mermaid) as MermaidConfig) + : state.mermaid; + if ( + mermaidConfig.securityLevel && + mermaidConfig.securityLevel !== 'strict' && + confirm( + `Removing "securityLevel":"${mermaidConfig.securityLevel}" from the config for safety.\nClick Cancel if you trust the source of this Diagram.` + ) + ) { + delete mermaidConfig.securityLevel; // Prevent setting overriding securityLevel when loading state to mitigate possible XSS attack + } + state.mermaid = JSON.stringify(mermaidConfig, null, 2); + } catch (e) { + state = get(inputStateStore); + if (data) { + console.error('Init error', e); + state.code = urlParseFailedState; + state.mermaid = defaultState.mermaid; + } + } + updateCodeStore(state); }; export const updateCodeStore = (newState: Partial): void => { - inputStateStore.update((state) => { - return { ...state, ...newState }; - }); + inputStateStore.update((state) => { + return { ...state, ...newState }; + }); }; let prompted = false; export const updateCode = ( - code: string, - { - updateEditor, - updateDiagram = false, - resetPanZoom = false - }: { updateEditor: boolean; updateDiagram?: boolean; resetPanZoom?: boolean } + code: string, + { + updateDiagram = false, + resetPanZoom = false + }: { updateDiagram?: boolean; resetPanZoom?: boolean } = {} ): void => { - saveStatistics(code); - const lines = (code.match(/\n/g) || '').length + 1; + console.log('updateCode', code); + const lines = countLines(code); + saveStatistics(code); + errorDebug(); + if (lines > 50 && !prompted && get(stateStore).autoSync) { + const turnOff = confirm( + `Long diagram detected. Turn off Auto Sync? Use ${cmdKey} + Enter or click the sync logo to manually sync.` + ); + prompted = true; + if (turnOff) { + updateCodeStore({ + autoSync: false + }); + } + } - if (lines > 50 && !prompted && get(stateStore).autoSync) { - const turnOff = confirm( - `Long diagram detected. Turn off Auto Sync? Use ${cmdKey} + Enter or click the sync logo to manually sync.` - ); - prompted = true; - if (turnOff) { - updateCodeStore({ - autoSync: false - }); - } - } - - inputStateStore.update((state) => { - if (resetPanZoom) { - state.pan = undefined; - state.zoom = undefined; - } - return { ...state, code, updateEditor, updateDiagram }; - }); + inputStateStore.update((state) => { + if (resetPanZoom) { + state.pan = undefined; + state.zoom = undefined; + } + return { ...state, code, updateDiagram }; + }); }; -export const updateConfig = (config: string, updateEditor: boolean): void => { - inputStateStore.update((state) => { - return { ...state, mermaid: config, updateEditor }; - }); +export const updateConfig = (config: string): void => { + console.log('updateConfig', config); + inputStateStore.update((state) => { + return { ...state, mermaid: config }; + }); }; export const toggleDarkTheme = (dark: boolean): void => { - inputStateStore.update((state) => { - const config = JSON.parse(state.mermaid); - if (!config.theme || ['dark', 'default'].includes(config.theme)) { - config.theme = dark ? 'dark' : 'default'; - } + inputStateStore.update((state) => { + const config = JSON.parse(state.mermaid) as MermaidConfig; + if (!config.theme || ['dark', 'default'].includes(config.theme)) { + config.theme = dark ? 'dark' : 'default'; + } - return { ...state, mermaid: JSON.stringify(config, null, 2), updateEditor: true }; - }); + return { ...state, mermaid: JSON.stringify(config, null, 2) }; + }); }; +let urlDebounce: number; export const initURLSubscription = (): void => { - stateStore.subscribe(({ serialized }) => { - history.replaceState(undefined, undefined, `#${serialized}`); - }); + stateStore.subscribe(({ serialized }) => { + clearTimeout(urlDebounce); + urlDebounce = window.setTimeout(() => { + history.replaceState(undefined, '', `#${serialized}`); + }, 250); + }); }; export const getStateString = (): string => { - return JSON.stringify(get(inputStateStore)); + return JSON.stringify(get(inputStateStore)); }; diff --git a/src/lib/util/stats.test.ts b/src/lib/util/stats.test.ts new file mode 100644 index 00000000..518a55b1 --- /dev/null +++ b/src/lib/util/stats.test.ts @@ -0,0 +1,19 @@ +import { describe, it, expect } from 'vitest'; +import { detectType } from './stats'; +describe('diagram detection', () => { + it('should detect diagrams correctly', () => { + expect( + detectType(`%%{{ + graph`) + ).toBe('graph'); + expect(detectType(`gitGraph`)).toBe('gitGraph'); + expect( + detectType(`%%{{ + + + flowChart + graph`) + ).toBe('flowChart'); + expect(detectType(`loki -> thor`)).toBe(undefined); + }); +}); diff --git a/src/lib/util/stats.ts b/src/lib/util/stats.ts index 34915f58..c349088d 100644 --- a/src/lib/util/stats.ts +++ b/src/lib/util/stats.ts @@ -1,49 +1,99 @@ -import { browser } from '$app/env'; +import { browser } from '$app/environment'; import type { AnalyticsInstance } from 'analytics'; - -export let analytics: AnalyticsInstance; +export let analytics: AnalyticsInstance | undefined; export const initAnalytics = async (): Promise => { - if (browser && !analytics) { - try { - const { Analytics } = await import('analytics'); - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const googleAnalytics = await import('@analytics/google-analytics'); - analytics = Analytics({ - app: 'mermaid-live-editor', - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - plugins: [ - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access - googleAnalytics.init({ - trackingId: 'UA-153180559-1' - }) - ] - }); - } catch { - console.info('Analytics blocked ;)'); - } - } + if (browser && !analytics) { + try { + const [{ Analytics }, { default: plausible }] = await Promise.all([ + import('analytics'), + import('analytics-plugin-plausible') + ]); + analytics = Analytics({ + app: 'mermaid-live-editor', + plugins: [ + plausible({ + domain: 'mermaid.live', + hashMode: false, + trackLocalhost: false, // By default 'false' + apiHost: 'https://plausible.io' + }) + ] + }); + } catch (e) { + console.log(e); + console.info('Analytics blocked ;)'); + } + } }; -const detectType = (text: string): string => { - return text - .replace(/^\s*%%.*\n/g, '\n') - .trimStart() - .split(' ')[0]; +export const detectType = (text: string): string | undefined => { + const possibleDiagramTypes = [ + 'classDiagram', + 'erDiagram', + 'flowChart', + 'gantt', + 'gitGraph', + 'graph', + 'journey', + 'pie', + 'stateDiagram' + ]; + const firstLine = text + .replace(/^\s*%%.*\n/g, '\n') + .trimStart() + .split(' ')[0] + .toLowerCase(); + const detectedDiagram = possibleDiagramTypes.find((d) => firstLine.includes(d.toLowerCase())); + return detectedDiagram; +}; + +export const countLines = (code: string): number => { + return (code.match(/\n/g)?.length ?? 0) + 1; }; -// manual debounce -let timeout; export const saveStatistics = (graph: string): void => { - if (analytics) { - clearTimeout(timeout); - // Only save statistics after a 5 sec delay - timeout = setTimeout(function () { - const graphType = detectType(graph); - console.debug('ga:', 'send', 'event', 'render', graphType); - void analytics.track('render', { - graphType - }); - }, 5000); - } + const graphType = detectType(graph); + if (!graphType) { + return; + } + const length = countLines(graph); + logEvent('render', { graphType, length }); +}; + +const minutesToMilliSeconds = (minutes: number): number => { + return minutes * 60_000; +}; + +const defaultDelay = minutesToMilliSeconds(1); +const delaysPerEvent = { + render: minutesToMilliSeconds(5), + panZoom: minutesToMilliSeconds(10), + copyClipboard: defaultDelay, + download: defaultDelay, + copyMarkdown: defaultDelay, + loadGist: defaultDelay, + loadSampleDiagram: defaultDelay, + renderDiagram: defaultDelay, + history: defaultDelay, + migration: defaultDelay, + themeChange: defaultDelay +}; +export type AnalyticsEvent = keyof typeof delaysPerEvent; +const timeouts: Map = new Map(); +// manual debounce to reduce the number of events sent to analytics +export const logEvent = (name: AnalyticsEvent, data?: unknown): void => { + if (!analytics) { + return; + } + const key = data ? JSON.stringify({ name, data }) : name; + if (!timeouts.has(key)) { + void analytics.track(name, data); + } else { + clearTimeout(timeouts.get(key)); + } + timeouts.set( + key, + window.setTimeout(() => timeouts.delete(key), delaysPerEvent[name]) + ); }; diff --git a/src/lib/util/theme.ts b/src/lib/util/theme.ts index 033bbe39..0da7f3ad 100644 --- a/src/lib/util/theme.ts +++ b/src/lib/util/theme.ts @@ -1,36 +1,38 @@ import { writable } from 'svelte/store'; import type { Writable } from 'svelte/store'; -import { persist, localStorage } from '@macfja/svelte-persistent-store'; +import { persist, localStorage } from '$lib/util/persist'; +import { logEvent } from './stats'; export interface ThemeConfig { - isDark: boolean; - theme?: string; + isDark: boolean; + theme?: string; } export const themeStore: Writable = persist( - writable({ - isDark: false - }), - localStorage(), - 'themeStore' + writable({ + isDark: false + }), + localStorage(), + 'themeStore' ); const darkThemes = [ - 'dark', - 'synthwave', - 'halloween', - 'aqua', - 'forest', - 'luxury', - 'black', - 'dracula' + 'dark', + 'synthwave', + 'halloween', + 'aqua', + 'forest', + 'luxury', + 'black', + 'dracula' ]; export const setTheme = (theme: string): void => { - if (theme.includes(' ')) { - theme = theme.split(' ')[1].trim(); - } - const isDark = darkThemes.includes(theme); - console.log('Setting theme', theme); - themeStore.set({ theme, isDark }); + if (theme.includes(' ')) { + theme = theme.split(' ')[1].trim(); + } + const isDark = darkThemes.includes(theme); + console.log('Setting theme', theme); + themeStore.set({ theme, isDark }); + logEvent('themeChange', { theme, isDark }); }; diff --git a/src/lib/util/util.ts b/src/lib/util/util.ts index 025752e2..bf2c7606 100644 --- a/src/lib/util/util.ts +++ b/src/lib/util/util.ts @@ -2,27 +2,39 @@ import { initURLSubscription, loadState, updateCodeStore } from './state'; import { analytics, initAnalytics } from './stats'; import { loadDataFromUrl } from './fileLoaders/loader'; import { initLoading } from './loading'; +import { applyMigrations } from './migrations'; +import { init } from './mermaid'; export const loadStateFromURL = (): void => { - loadState(window.location.hash.slice(1)); + loadState(window.location.hash.slice(1)); }; export const syncDiagram = (): void => { - updateCodeStore({ - updateDiagram: true - }); + updateCodeStore({ + updateDiagram: true + }); }; export const initHandler = async (): Promise => { - loadStateFromURL(); - await initLoading('Loading Gist...', loadDataFromUrl().catch(console.error)); - syncDiagram(); - initURLSubscription(); - await initAnalytics(); - analytics?.page(); + applyMigrations(); + await initLoading('Loading Mermaid...', init()); + loadStateFromURL(); + await initLoading('Loading Gist...', loadDataFromUrl().catch(console.error)); + syncDiagram(); + initURLSubscription(); + await initAnalytics(); + await analytics?.page(); }; -export const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; +export const isMac = navigator.platform.toUpperCase().includes('MAC'); export const cmdKey = isMac ? 'Cmd' : 'Ctrl'; -export const debounceEnabled = window.localStorage.getItem('noDebounce') !== 'true'; +let count = 0; +export const errorDebug = (limit = 100) => { + count += 1; + if (count > limit) { + console.log(count, limit); + // eslint-disable-next-line no-debugger + debugger; + } +}; diff --git a/src/routes/+layout.js b/src/routes/+layout.js new file mode 100644 index 00000000..96544443 --- /dev/null +++ b/src/routes/+layout.js @@ -0,0 +1,4 @@ +export const prerender = true; +export const csr = true; +export const ssr = false; +export const trailingSlash = 'ignore'; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 00000000..099537f6 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,87 @@ + + +
+ +
+ +{#if $loadingStateStore.loading} +
+
+
+
{$loadingStateStore.message}
+
+
+{/if} + + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 00000000..4a12a8b8 --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,17 @@ + diff --git a/src/routes/[fallback]/manifest.json.ts b/src/routes/[fallback]/manifest.json.ts deleted file mode 100644 index c7761d5b..00000000 --- a/src/routes/[fallback]/manifest.json.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { GET as manifestGet } from '../manifest.json'; -export const GET = manifestGet; diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte deleted file mode 100644 index 26aa808c..00000000 --- a/src/routes/__layout.svelte +++ /dev/null @@ -1,87 +0,0 @@ - - -
- -
- -{#if $loadingStateStore.loading} -
-
-
-
{$loadingStateStore.message}
-
-
-{/if} - - diff --git a/src/routes/edit.svelte b/src/routes/edit.svelte deleted file mode 100644 index 45bbd3e9..00000000 --- a/src/routes/edit.svelte +++ /dev/null @@ -1,234 +0,0 @@ - - -
- -
- - -
- - diff --git a/src/routes/edit/+page.svelte b/src/routes/edit/+page.svelte new file mode 100644 index 00000000..ae92d28d --- /dev/null +++ b/src/routes/edit/+page.svelte @@ -0,0 +1,206 @@ + + +
+ +
+ + +
+ + diff --git a/src/routes/index.svelte b/src/routes/index.svelte deleted file mode 100644 index ca9daa13..00000000 --- a/src/routes/index.svelte +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/src/routes/manifest.json.ts b/src/routes/manifest.json.ts deleted file mode 100644 index 45e6320f..00000000 --- a/src/routes/manifest.json.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { base } from '$app/paths'; -export const GET = (): { body: unknown } => { - return { - body: { - short_name: 'Mermaid', - name: 'Mermaid Live Editor', - icons: [ - { - src: `${base}/icon-192.png`, - type: 'image/png', - sizes: '192x192' - }, - { - src: `${base}/icon-512.png`, - type: 'image/png', - sizes: '512x512' - } - ], - start_url: `${base}/edit/`, - background_color: '#6366F1', - display: 'standalone', - scope: `${base}/edit/`, - theme_color: '#6366F1', - description: 'FlowChart & Diagrams Editor.', - orientation: 'landscape' - } - }; -}; diff --git a/src/routes/view.svelte b/src/routes/view.svelte deleted file mode 100644 index 216251f0..00000000 --- a/src/routes/view.svelte +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/src/routes/view/+page.svelte b/src/routes/view/+page.svelte new file mode 100644 index 00000000..936fc0d1 --- /dev/null +++ b/src/routes/view/+page.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/tests/setup.ts b/src/tests/setup.ts index b210af53..51d4037f 100644 --- a/src/tests/setup.ts +++ b/src/tests/setup.ts @@ -1,4 +1,11 @@ import matchers from '@testing-library/jest-dom/matchers'; -import { expect } from 'vitest'; +import { expect, beforeAll, vi } from 'vitest'; expect.extend(matchers); + +// TODO: Remove once https://github.com/sveltejs/kit/issues/6259 is closed. +beforeAll(() => { + vi.mock('$app/environment', () => ({ + browser: 'window' in globalThis + })); +}); diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 00000000..7873127f Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/favicon.png b/static/favicon.png index 1c2e38b9..05d8a737 100644 Binary files a/static/favicon.png and b/static/favicon.png differ diff --git a/static/favicon.svg b/static/favicon.svg new file mode 100644 index 00000000..993c56b9 --- /dev/null +++ b/static/favicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/icon-192.png b/static/icon-192.png deleted file mode 100644 index 0bfa1a5c..00000000 Binary files a/static/icon-192.png and /dev/null differ diff --git a/static/icon-512.png b/static/icon-512.png deleted file mode 100644 index 8e89b9f9..00000000 Binary files a/static/icon-512.png and /dev/null differ diff --git a/static/manifest.json b/static/manifest.json new file mode 100644 index 00000000..d57636a2 --- /dev/null +++ b/static/manifest.json @@ -0,0 +1,18 @@ +{ + "short_name": "Mermaid", + "name": "Mermaid Live Editor", + "icons": [ + { + "src": "/favicon.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": "/edit/", + "background_color": "#6366F1", + "display": "standalone", + "scope": "/edit/", + "theme_color": "#6366F1", + "description": "FlowChart & Diagrams Editor.", + "orientation": "landscape" +} \ No newline at end of file diff --git a/svelte.config.js b/svelte.config.js index 2c404688..7b34bfa1 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -3,27 +3,23 @@ import adapter from '@sveltejs/adapter-static'; /** @type {import('@sveltejs/kit').Config} */ const config = { - // Consult https://github.com/sveltejs/svelte-preprocess - // for more information about preprocessors - preprocess: [ - preprocess({ - postcss: true - }) - ], - kit: { - adapter: adapter({ - pages: `docs` - }), - paths: process.env['DEPLOY'] - ? { - base: `/mermaid-live-editor` - } - : {}, - trailingSlash: 'ignore', - prerender: { - default: true - } - } + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: [ + preprocess({ + postcss: true + }) + ], + kit: { + adapter: adapter({ + pages: `docs` + }), + paths: process.env['DEPLOY'] + ? { + base: `/mermaid-live-editor` + } + : {} + } }; export default config; diff --git a/tailwind.config.cjs b/tailwind.config.cjs index dc72ba6e..18cb32c1 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -1,10 +1,10 @@ module.exports = { - plugins: [require('daisyui')], - content: ['./src/**/*.{html,js,svelte,ts}'], - theme: { - extend: {} - }, - variants: { - extend: {} - } + plugins: [require('daisyui')], + content: ['./src/**/*.{html,js,svelte,ts}'], + theme: { + extend: {} + }, + variants: { + extend: {} + } }; diff --git a/tsconfig.json b/tsconfig.json index 120d65a2..91263b2e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,19 @@ { - "include": [ - "src/**/*.d.ts", - "src/**/*.ts", - "src/**/*.svelte", - "cypress/**/*.ts", - "cypress/**/*.js", - "static/**/*.js" - ], - "compilerOptions": { - "resolveJsonModule": true, - "allowSyntheticDefaultImports": true, - "types": ["vitest/importMeta"] - }, - "extends": "./.svelte-kit/tsconfig.json" + "include": [ + "src/**/*.d.ts", + "src/**/*.ts", + "src/**/*.svelte", + "cypress/**/*.ts", + "cypress/**/*.js", + "cypress/**/*.json", + "static/**/*.js", + "static/**/*.json" + ], + "compilerOptions": { + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "strictNullChecks": true, + "types": ["vitest/importMeta"] + }, + "extends": "./.svelte-kit/tsconfig.json" } diff --git a/vite.config.js b/vite.config.js index 27500d09..ecf6163b 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,29 +1,26 @@ import { sveltekit } from '@sveltejs/kit/vite'; /** @type {import('vite').UserConfig} */ const config = { - plugins: [sveltekit()], - envPrefix: 'MERMAID_', - optimizeDeps: { include: ['mermaid'] }, - ssr: { - noExternal: ['@macfja/svelte-persistent-store'] - }, - server: { - port: 3000, - host: true - }, - preview: { - port: 3000, - host: true - }, - test: { - environment: 'jsdom', - // in-source testing - includeSource: ['src/**/*.{js,ts,svelte}'], - setupFiles: ['./src/tests/setup.ts'], - coverage: { - exclude: ['src/mocks', '.svelte-kit', 'src/**/*.test.ts'], - reporter: ['text', 'json', 'html', 'lcov'] - } - } + plugins: [sveltekit()], + envPrefix: 'MERMAID_', + optimizeDeps: { include: ['mermaid'] }, + server: { + port: 3000, + host: true + }, + preview: { + port: 3000, + host: true + }, + test: { + environment: 'jsdom', + // in-source testing + includeSource: ['src/**/*.{js,ts,svelte}'], + setupFiles: ['./src/tests/setup.ts'], + coverage: { + exclude: ['src/mocks', '.svelte-kit', 'src/**/*.test.ts'], + reporter: ['text', 'json', 'html', 'lcov'] + } + } }; export default config; diff --git a/yarn.lock b/yarn.lock index b95adbe6..03be610a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,13 +7,22 @@ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.0.1.tgz#b38b444ad3aa5fedbb15f2f746dcd934226a12dd" integrity sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g== -"@analytics/cookie-utils@^0.2.10": +"@analytics/cookie-utils@^0.2.10", "@analytics/cookie-utils@^0.2.9": version "0.2.10" resolved "https://registry.yarnpkg.com/@analytics/cookie-utils/-/cookie-utils-0.2.10.tgz#94d1ad0766c58c4a294e5ca54f59b0a69bd574b4" integrity sha512-k7oyW1PkMCnEdCYmHCLLXAsKavQh5ZRh5EeugBEUTlPJs8x8ajF+W1T0PYVDS26Impkea1sJR2etv/6l2pKtlg== dependencies: "@analytics/global-storage-utils" "^0.1.5" +"@analytics/core@^0.10.23": + version "0.10.23" + resolved "https://registry.yarnpkg.com/@analytics/core/-/core-0.10.23.tgz#869218c28bae4948bdecfd76415064e83bb8ca8d" + integrity sha512-crOJ7tNA5xak5YGiiX8IvPyqf4Hy3tMmTH4dTvQiOapO6BiBJcxBUkjtJNPwZlhS4nmsWh0skeTBr4Kv92RzeA== + dependencies: + "@analytics/global-storage-utils" "^0.1.4" + "@analytics/type-utils" "^0.5.4" + analytics-utils "^1.0.9" + "@analytics/core@^0.11.1": version "0.11.1" resolved "https://registry.yarnpkg.com/@analytics/core/-/core-0.11.1.tgz#3d26858aeaf77b80810e269a4ecfd70173032501" @@ -23,25 +32,27 @@ "@analytics/type-utils" "^0.6.0" analytics-utils "^1.0.10" -"@analytics/global-storage-utils@^0.1.5": +"@analytics/global-storage-utils@^0.1.4", "@analytics/global-storage-utils@^0.1.5": version "0.1.5" resolved "https://registry.yarnpkg.com/@analytics/global-storage-utils/-/global-storage-utils-0.1.5.tgz#54cc14f8d678610b5fca1e98215fe29fff662f31" integrity sha512-DzOCd0qK7PGnz/dgBYNzLmaFBkxcEHM6/CpWMY7hel1IBUldMsyet4sdRgI2Nk+Wc6B/YvqVqos68p5ntB59zA== dependencies: "@analytics/type-utils" "^0.6.0" -"@analytics/google-analytics@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@analytics/google-analytics/-/google-analytics-1.0.3.tgz#4b3966c4b5729ae65f909149b9f1a58ac42dc10f" - integrity sha512-LnwefjQaqypjIXhw9GLRYpUz8dkriEC53JTLgJZ+mxSBZTkSrLSi3zuAiuV8rcsI0XfYmlWIav9RgGq92dWd4w== - -"@analytics/localstorage-utils@^0.1.8": +"@analytics/localstorage-utils@^0.1.7", "@analytics/localstorage-utils@^0.1.8": version "0.1.8" resolved "https://registry.yarnpkg.com/@analytics/localstorage-utils/-/localstorage-utils-0.1.8.tgz#eab6a9690ccd3c05d131e3a9788b4443affdb800" integrity sha512-tU5rLEHdYRc4EmRXkWacMJSmu4SeJfQuxvthSHHRVx3hGBQ00MJRDGyDHMXcrLKQXrBpsJo6t/8YRavHLOxDPQ== dependencies: "@analytics/global-storage-utils" "^0.1.5" +"@analytics/session-storage-utils@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@analytics/session-storage-utils/-/session-storage-utils-0.0.4.tgz#6aefe0eb012038f3722433c411485a2b7f540a15" + integrity sha512-HPVIUMpL9ua8uBj5kLsTOLbxUNP0GVYQowC9AwX1S/T39Eg8RKwbV/GYaDAqeCjEi8BGYOEguqI9kFGqxIt1iA== + dependencies: + "@analytics/global-storage-utils" "^0.1.4" + "@analytics/session-storage-utils@^0.0.5": version "0.0.5" resolved "https://registry.yarnpkg.com/@analytics/session-storage-utils/-/session-storage-utils-0.0.5.tgz#f0501ef73d1b94a34e94057056cadaeee4f65fdf" @@ -49,6 +60,17 @@ dependencies: "@analytics/global-storage-utils" "^0.1.5" +"@analytics/storage-utils@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@analytics/storage-utils/-/storage-utils-0.3.0.tgz#7a9795af6b73e13194edb03eb27402c4877d9d96" + integrity sha512-uxOz5wdZkuxc7RaWlNsj/7iFr0GkkFqmxyIYY4oFk91E3/hyosny59lb8DEC/MpdUUAoNI+clU+I/PYcv3p1WA== + dependencies: + "@analytics/cookie-utils" "^0.2.9" + "@analytics/global-storage-utils" "^0.1.4" + "@analytics/localstorage-utils" "^0.1.7" + "@analytics/session-storage-utils" "^0.0.4" + "@analytics/type-utils" "^0.5.4" + "@analytics/storage-utils@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@analytics/storage-utils/-/storage-utils-0.4.0.tgz#12e5c0683f0124e189650a4989a627f3318d7995" @@ -60,6 +82,11 @@ "@analytics/session-storage-utils" "^0.0.5" "@analytics/type-utils" "^0.6.0" +"@analytics/type-utils@^0.5.4": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@analytics/type-utils/-/type-utils-0.5.4.tgz#1fcaa6d1d557c0377d1fbd8615624ac918d1727d" + integrity sha512-2CT5YTsvif3gYPYp5hPIhh66mUo/Cu+k5OiHbX3k5p+YsZ5Bggcp/wLEFnrdKG4tKgGn5SOKkEtL63VYhGXX7g== + "@analytics/type-utils@^0.6.0": version "0.6.0" resolved "https://registry.yarnpkg.com/@analytics/type-utils/-/type-utils-0.6.0.tgz#1b8745516da5a654d292ed3f2db893c61cd3d9c5" @@ -149,14 +176,24 @@ debug "^3.1.0" lodash.once "^4.1.1" -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== +"@esbuild/android-arm@0.15.10": + version "0.15.10" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.10.tgz#a5f9432eb221afc243c321058ef25fe899886892" + integrity sha512-FNONeQPy/ox+5NBkcSbYJxoXj9GWu8gVGJTVmUyoOCKQFDTrHVKgNSzChdNt0I8Aj/iKcsDf2r9BFwv+FSNUXg== + +"@esbuild/linux-loong64@0.15.10": + version "0.15.10" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.10.tgz#78a42897c2cf8db9fd5f1811f7590393b77774c7" + integrity sha512-w0Ou3Z83LOYEkwaui2M8VwIp+nLi/NA60lBLMvaJ+vXVMcsARYdEzLNE7RSm4+lSg4zq4d7fAVuzk7PNQ5JFgg== + +"@eslint/eslintrc@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" + integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.2" + espree "^9.4.0" globals "^13.15.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -164,19 +201,19 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.10.4": - version "0.10.4" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" - integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== +"@humanwhocodes/config-array@^0.11.6": + version "0.11.7" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" + integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" -"@humanwhocodes/gitignore-to-minimatch@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" - integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" @@ -213,14 +250,17 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@macfja/svelte-persistent-store@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@macfja/svelte-persistent-store/-/svelte-persistent-store-1.3.0.tgz#e3ef6440cde04657ab77284dacd447b12a89cb1e" - integrity sha512-3lPsEAFe28zCNTyA+/pYfUgzRrH6KZvoG0i4IHVhYOs3Xzaqg9hN7LdHa+Qrv7GncXn/6XhDEpb36hB0f7CzXA== +"@mermaid-js/mermaid-mindmap@9.2.2": + version "9.2.2" + resolved "https://registry.yarnpkg.com/@mermaid-js/mermaid-mindmap/-/mermaid-mindmap-9.2.2.tgz#106b06733748cf3a5b9e6a9bd6d11546020bed38" + integrity sha512-uzUY0PR/itxkQxpDRg95yDPJ++mRDUmGce4EVCKFebUCs0UNI/xi5mhvV6Oq8czM2ImY0W1gJu4MS2Xq3yiQug== dependencies: - browser-cookies "^1.2.0" - esserializer "^1.3.2" - idb-keyval "^5.1.3" + "@braintree/sanitize-url" "^6.0.0" + cytoscape "^3.23.0" + cytoscape-cose-bilkent "^4.1.0" + cytoscape-fcose "^2.1.0" + d3 "^7.0.0" + non-layered-tidy-tree-layout "^2.0.2" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -235,7 +275,7 @@ resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -243,58 +283,58 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@playwright/test@^1.25.0": - version "1.25.0" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.25.0.tgz#e0de134651e78e45e986c5f16578188dd5937331" - integrity sha512-j4EZhTTQI3dBeWblE21EV//swwmBtOpIrLdOIJIRv4uqsLdHgBg1z+JtTg+AeC5o2bAXIE26kDNW5A0TimG8Bg== +"@playwright/test@^1.28.1": + version "1.28.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.28.1.tgz#e5be297e024a3256610cac2baaa9347fd57c7860" + integrity sha512-xN6spdqrNlwSn9KabIhqfZR7IWjPpFK1835tFNgjrlysaSezuX8PYUwaz38V/yI8TJLG9PkAMEXoHRXYXlpTPQ== dependencies: "@types/node" "*" - playwright-core "1.25.0" + playwright-core "1.28.1" "@polka/url@^1.0.0-next.20": version "1.0.0-next.21" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== -"@rollup/pluginutils@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" - integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== - dependencies: - estree-walker "^2.0.1" - picomatch "^2.2.2" - "@sinclair/typebox@^0.23.3": version "0.23.5" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d" integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg== -"@sveltejs/adapter-static@1.0.0-next.39": - version "1.0.0-next.39" - resolved "https://registry.yarnpkg.com/@sveltejs/adapter-static/-/adapter-static-1.0.0-next.39.tgz#ae79b95accd3af6ecfa92e9596c4d41b49cf6fea" - integrity sha512-EeD39H6iEe0UEKnKxLFTZFZpi/FcX5xfbAvsMQ+B09aDZccpQmkJBSIo+4kq1JsQGSjwi/+J3aE9bR67R6CIyQ== +"@sveltejs/adapter-static@1.0.0-next.48": + version "1.0.0-next.48" + resolved "https://registry.yarnpkg.com/@sveltejs/adapter-static/-/adapter-static-1.0.0-next.48.tgz#85c6ad2f1a8deaa50a7d156a1a5f024b9af0b52e" + integrity sha512-Z5Z+QZOav6D0KDeU3ReksGERJg/sX1k5OKWWXyQ11OwGErEEwSXHYRUyjaBmZEPeGzpVVGwwMUK8YWJlG/MKeA== -"@sveltejs/kit@1.0.0-next.405": - version "1.0.0-next.405" - resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.0.0-next.405.tgz#ab1fe94e695a4c0326cb9c52767281a760d3ac55" - integrity sha512-jHSa74F7k+hC+0fof75g/xm/+1M5sM66Qt6v8eLLMSgjkp36Lb5xOioBhbl6w0NYoE5xysLsBWuu+yHytfvCBA== +"@sveltejs/kit@1.0.0-next.561": + version "1.0.0-next.561" + resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.0.0-next.561.tgz#76ebcf472284554dde4e8c7dd7675e35caec0def" + integrity sha512-N8HQvS6gcm7R78ADfM4xjhuFS3Ir+Ezce3De8WOnISXQ1tS2npc5LMH9LRHHi14nfosAfJ7vUlcLwLE6N/I7+Q== dependencies: - "@sveltejs/vite-plugin-svelte" "^1.0.1" - chokidar "^3.5.3" + "@sveltejs/vite-plugin-svelte" "^1.3.1" + "@types/cookie" "^0.5.1" + cookie "^0.5.0" + devalue "^4.2.0" + kleur "^4.1.5" + magic-string "^0.26.7" + mime "^3.0.0" sade "^1.8.1" + set-cookie-parser "^2.5.1" + sirv "^2.0.2" tiny-glob "^0.2.9" + undici "5.12.0" -"@sveltejs/vite-plugin-svelte@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.1.tgz#7f468f03c933fcdfc60d4773671c73f33b9ef4d6" - integrity sha512-PorCgUounn0VXcpeJu+hOweZODKmGuLHsLomwqSj+p26IwjjGffmYQfVHtiTWq+NqaUuuHWWG7vPge6UFw4Aeg== +"@sveltejs/vite-plugin-svelte@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.3.1.tgz#1b0a109d49ec42981ea2e1d7bdb712fbc96354bb" + integrity sha512-2Uu2sDdIR+XQWF7QWOVSF2jR9EU6Ciw1yWfYnfLYj8HIgnNxkh/8g22Fw2pBUI8QNyW/KxtqJUWBI+8ypamSrQ== dependencies: - "@rollup/pluginutils" "^4.2.1" debug "^4.3.4" deepmerge "^4.2.2" kleur "^4.1.5" - magic-string "^0.26.2" - svelte-hmr "^0.14.12" + magic-string "^0.26.7" + svelte-hmr "^0.15.1" + vitefu "^0.2.2" "@testing-library/dom@^8.1.0": version "8.14.0" @@ -325,10 +365,10 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/svelte@3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@testing-library/svelte/-/svelte-3.1.3.tgz#a3605a0e98ea04f9ba58ec3d554a9e1a81a4a577" - integrity sha512-pyed3yMnTu7wG9Z4XKoIxdrx52hSEFDC8qUaiSsiSh8tBVj3ZjqEKnV2Nfc0IF2llEkT0B7QOXnOVTLJ3O5RCw== +"@testing-library/svelte@3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@testing-library/svelte/-/svelte-3.2.2.tgz#aa8ca6bde3136593c5f8b4554e3634d7adc9bdc5" + integrity sha512-IKwZgqbekC3LpoRhSwhd0JswRGxKdAGkf39UiDXTywK61YyLXbCYoR831e/UUC6EeNW4hiHPY+2WuovxOgI5sw== dependencies: "@testing-library/dom" "^8.1.0" @@ -354,16 +394,16 @@ dependencies: "@types/chai" "*" -"@types/chai@*": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04" - integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ== - -"@types/chai@^4.3.3": +"@types/chai@*", "@types/chai@^4.3.3": version "4.3.3" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.3.tgz#3c90752792660c4b562ad73b3fbd68bf3bc7ae07" integrity sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g== +"@types/cookie@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.5.1.tgz#b29aa1f91a59f35e29ff8f7cb24faf1a3a750554" + integrity sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g== + "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" @@ -382,11 +422,6 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/mermaid@8.2.9": - version "8.2.9" - resolved "https://registry.yarnpkg.com/@types/mermaid/-/mermaid-8.2.9.tgz#1844505dcffcd47703e94628a6200583d35c2c76" - integrity sha512-f1i8fNoVFVJXedk+R7GcEk4KoOWzWAU3CzFqlVw1qWKktfsataBERezCz1pOdKy8Ec02ZdPQXGM7NU2lPHABYQ== - "@types/node@*": version "15.0.2" resolved "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz" @@ -397,10 +432,10 @@ resolved "https://registry.npmjs.org/@types/node/-/node-14.17.0.tgz" integrity sha512-w8VZUN/f7SSbvVReb9SWp6cJFevxb4/nkG65yLAya//98WgocKm5PLDAtSs5CtJJJM+kHmJjO/6mmYW4MHShZA== -"@types/pako@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/pako/-/pako-1.0.3.tgz#2e61c2b02020b5f44e2e5e946dfac74f4ec33c58" - integrity sha512-EDxOsHAD5dqjbjEUM1xwa7rpKPFb8ECBE5irONTQU7/OsO3thI5YrNEWSPNMvYmvFM0l/OLQJ6Mgw7PEdXSjhg== +"@types/pako@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/pako/-/pako-2.0.0.tgz#12ab4c19107528452e73ac99132c875ccd43bdfb" + integrity sha512-10+iaz93qR5WYxTo+PMifD5TSxiOtdRaxBf7INGGXMQgTCu8Z/7GYWYFUOS3q/G0nE5boj1r4FEB+WSy7s5gbA== "@types/pug@^2.0.4": version "2.0.4" @@ -414,6 +449,11 @@ dependencies: "@types/node" "*" +"@types/semver@^7.3.12": + version "7.3.12" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.12.tgz#920447fdd78d76b19de0438b7f60df3c4a80bf1c" + integrity sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A== + "@types/sinonjs__fake-timers@8.1.1": version "8.1.1" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" @@ -431,6 +471,11 @@ dependencies: "@types/jest" "*" +"@types/uuid@8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/yauzl@^2.9.1": version "2.9.1" resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz" @@ -438,136 +483,93 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.0.tgz#059798888720ec52ffa96c5f868e31a8f70fa3ec" - integrity sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg== +"@typescript-eslint/eslint-plugin@5.44.0": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.44.0.tgz#105788f299050c917eb85c4d9fd04b089e3740de" + integrity sha512-j5ULd7FmmekcyWeArx+i8x7sdRHzAtXTkmDPthE4amxZOWKFK7bomoJ4r7PJ8K7PoMzD16U8MmuZFAonr1ERvw== dependencies: - "@typescript-eslint/scope-manager" "5.33.0" - "@typescript-eslint/type-utils" "5.33.0" - "@typescript-eslint/utils" "5.33.0" + "@typescript-eslint/scope-manager" "5.44.0" + "@typescript-eslint/type-utils" "5.44.0" + "@typescript-eslint/utils" "5.44.0" debug "^4.3.4" - functional-red-black-tree "^1.0.1" ignore "^5.2.0" + natural-compare-lite "^1.4.0" regexpp "^3.2.0" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.33.0.tgz#26ec3235b74f0667414613727cb98f9b69dc5383" - integrity sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w== +"@typescript-eslint/parser@5.44.0": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.44.0.tgz#99e2c710a2252191e7a79113264f438338b846ad" + integrity sha512-H7LCqbZnKqkkgQHaKLGC6KUjt3pjJDx8ETDqmwncyb6PuoigYajyAwBGz08VU/l86dZWZgI4zm5k2VaKqayYyA== dependencies: - "@typescript-eslint/scope-manager" "5.33.0" - "@typescript-eslint/types" "5.33.0" - "@typescript-eslint/typescript-estree" "5.33.0" + "@typescript-eslint/scope-manager" "5.44.0" + "@typescript-eslint/types" "5.44.0" + "@typescript-eslint/typescript-estree" "5.44.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.32.0": - version "5.32.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.32.0.tgz#763386e963a8def470580cc36cf9228864190b95" - integrity sha512-KyAE+tUON0D7tNz92p1uetRqVJiiAkeluvwvZOqBmW9z2XApmk5WSMV9FrzOroAcVxJZB3GfUwVKr98Dr/OjOg== +"@typescript-eslint/scope-manager@5.44.0": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz#988c3f34b45b3474eb9ff0674c18309dedfc3e04" + integrity sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g== dependencies: - "@typescript-eslint/types" "5.32.0" - "@typescript-eslint/visitor-keys" "5.32.0" + "@typescript-eslint/types" "5.44.0" + "@typescript-eslint/visitor-keys" "5.44.0" -"@typescript-eslint/scope-manager@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.33.0.tgz#509d7fa540a2c58f66bdcfcf278a3fa79002e18d" - integrity sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw== +"@typescript-eslint/type-utils@5.44.0": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.44.0.tgz#bc5a6e8a0269850714a870c9268c038150dfb3c7" + integrity sha512-A1u0Yo5wZxkXPQ7/noGkRhV4J9opcymcr31XQtOzcc5nO/IHN2E2TPMECKWYpM3e6olWEM63fq/BaL1wEYnt/w== dependencies: - "@typescript-eslint/types" "5.33.0" - "@typescript-eslint/visitor-keys" "5.33.0" - -"@typescript-eslint/type-utils@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.33.0.tgz#92ad1fba973c078d23767ce2d8d5a601baaa9338" - integrity sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA== - dependencies: - "@typescript-eslint/utils" "5.33.0" + "@typescript-eslint/typescript-estree" "5.44.0" + "@typescript-eslint/utils" "5.44.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.32.0": - version "5.32.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.32.0.tgz#484273021eeeae87ddb288f39586ef5efeb6dcd8" - integrity sha512-EBUKs68DOcT/EjGfzywp+f8wG9Zw6gj6BjWu7KV/IYllqKJFPlZlLSYw/PTvVyiRw50t6wVbgv4p9uE2h6sZrQ== +"@typescript-eslint/types@5.44.0": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.44.0.tgz#f3f0b89aaff78f097a2927fe5688c07e786a0241" + integrity sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ== -"@typescript-eslint/types@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.33.0.tgz#d41c584831805554b063791338b0220b613a275b" - integrity sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw== - -"@typescript-eslint/typescript-estree@5.32.0": - version "5.32.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.32.0.tgz#282943f34babf07a4afa7b0ff347a8e7b6030d12" - integrity sha512-ZVAUkvPk3ITGtCLU5J4atCw9RTxK+SRc6hXqLtllC2sGSeMFWN+YwbiJR9CFrSFJ3w4SJfcWtDwNb/DmUIHdhg== +"@typescript-eslint/typescript-estree@5.44.0": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz#0461b386203e8d383bb1268b1ed1da9bc905b045" + integrity sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw== dependencies: - "@typescript-eslint/types" "5.32.0" - "@typescript-eslint/visitor-keys" "5.32.0" + "@typescript-eslint/types" "5.44.0" + "@typescript-eslint/visitor-keys" "5.44.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.0.tgz#02d9c9ade6f4897c09e3508c27de53ad6bfa54cf" - integrity sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ== +"@typescript-eslint/utils@5.44.0", "@typescript-eslint/utils@^5.42.1": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.44.0.tgz#d733da4d79d6c30f1a68b531cdda1e0c1f00d52d" + integrity sha512-fMzA8LLQ189gaBjS0MZszw5HBdZgVwxVFShCO3QN+ws3GlPkcy9YuS3U4wkT6su0w+Byjq3mS3uamy9HE4Yfjw== dependencies: - "@typescript-eslint/types" "5.33.0" - "@typescript-eslint/visitor-keys" "5.33.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.44.0" + "@typescript-eslint/types" "5.44.0" + "@typescript-eslint/typescript-estree" "5.44.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" semver "^7.3.7" - tsutils "^3.21.0" -"@typescript-eslint/utils@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.33.0.tgz#46797461ce3146e21c095d79518cc0f8ec574038" - integrity sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw== +"@typescript-eslint/visitor-keys@5.44.0": + version "5.44.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz#10740dc28902bb903d12ee3a005cc3a70207d433" + integrity sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ== dependencies: - "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.33.0" - "@typescript-eslint/types" "5.33.0" - "@typescript-eslint/typescript-estree" "5.33.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/utils@^5.17.0": - version "5.32.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.32.0.tgz#eccb6b672b94516f1afc6508d05173c45924840c" - integrity sha512-W7lYIAI5Zlc5K082dGR27Fczjb3Q57ECcXefKU/f0ajM5ToM0P+N9NmJWip8GmGu/g6QISNT+K6KYB+iSHjXCQ== - dependencies: - "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.32.0" - "@typescript-eslint/types" "5.32.0" - "@typescript-eslint/typescript-estree" "5.32.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/visitor-keys@5.32.0": - version "5.32.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.32.0.tgz#b9715d0b11fdb5dd10fd0c42ff13987470525394" - integrity sha512-S54xOHZgfThiZ38/ZGTgB2rqx51CMJ5MCfVT2IplK4Q7hgzGfe0nLzLCcenDnc/cSjP568hdeKfeDcBgqNHD/g== - dependencies: - "@typescript-eslint/types" "5.32.0" + "@typescript-eslint/types" "5.44.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@5.33.0": - version "5.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.0.tgz#fbcbb074e460c11046e067bc3384b5d66b555484" - integrity sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw== - dependencies: - "@typescript-eslint/types" "5.33.0" - eslint-visitor-keys "^3.3.0" - -"@vitest/ui@0.21.1": - version "0.21.1" - resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-0.21.1.tgz#b941f5053663a8363910a54f680c263444cc5f09" - integrity sha512-e+AZdMG6NvrYhxB99LGxW1GkoTpqSDPKpL+wghsApWhocNwALBOBzvgsDr/WN6D6YWRXf18rsJ1kY/KaIspRdg== +"@vitest/ui@^0.25.3": + version "0.25.3" + resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-0.25.3.tgz#46af3c844c013e7680332970332ccbada045af4a" + integrity sha512-o0Bo/SPlcqopsuGaPUwIPhb0Jr3VSMO4hOOWBBNDtz2/a89HO2GHPP/tx8waWxF0bBc6Cjpcj/CRQAYy3KbLgg== dependencies: sirv "^2.0.2" @@ -586,13 +588,13 @@ abbrev@1: resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== +acorn-globals@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" + integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" + acorn "^8.1.0" + acorn-walk "^8.0.2" acorn-jsx@^5.3.2: version "5.3.2" @@ -608,26 +610,31 @@ acorn-node@^1.8.2: acorn-walk "^7.0.0" xtend "^4.0.2" -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.0.0: version "7.2.0" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.0.0, acorn@^7.1.1: +acorn-walk@^8.0.2, acorn-walk@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^7.0.0: version "7.4.1" resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.7.1: - version "8.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== - -acorn@^8.8.0: +acorn@^8.1.0, acorn@^8.8.0: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +acorn@^8.8.1: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -658,7 +665,15 @@ am-i-a-dependency@1.1.2: resolved "https://registry.npmjs.org/am-i-a-dependency/-/am-i-a-dependency-1.1.2.tgz" integrity sha1-+dNCIwTW9kL4IeTEB1ZQNfYWfx8= -analytics-utils@^1.0.10: +analytics-plugin-plausible@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/analytics-plugin-plausible/-/analytics-plugin-plausible-0.0.6.tgz#22595821f1d201cb2e58dde2bb688d78fae78725" + integrity sha512-gXeoJo85JLO91DckbPq23jn/QJW4vg1hA/bRcAbcAo5D6u6JUIg/rG6Ecwkk75sPefnGFIZ6qGHIoz1b2wFK9w== + dependencies: + analytics "^0.7.5" + plausible-tracker "^0.3.1" + +analytics-utils@^1.0.10, analytics-utils@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/analytics-utils/-/analytics-utils-1.0.10.tgz#e44078176c67005e5b11aae1dc538202744a5ca5" integrity sha512-ZKYKhip7Sf09qE85l4vZMBPR3fz6ISUTlwzkWSwJHbzLLzP5qrWQtcQlBcP9Pah7BMNSq8pqho+PX4ZKB014Yg== @@ -674,6 +689,14 @@ analytics@0.8.1: "@analytics/core" "^0.11.1" "@analytics/storage-utils" "^0.4.0" +analytics@^0.7.5: + version "0.7.23" + resolved "https://registry.yarnpkg.com/analytics/-/analytics-0.7.23.tgz#cff8d43c67fa851229232bc251e58a27e2f863eb" + integrity sha512-9zujZOUmDnRGRNoKIXwongMlOV1Odi+5ftRpfTPlYYQfX7Kl6ttSaP2caFQhKr5SenSCW2RMIxiLzX+LynE7sw== + dependencies: + "@analytics/core" "^0.10.23" + "@analytics/storage-utils" "^0.3.0" + ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" @@ -805,13 +828,13 @@ at-least-node@^1.0.0: resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -autoprefixer@10.4.8: - version "10.4.8" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.8.tgz#92c7a0199e1cfb2ad5d9427bd585a3d75895b9e5" - integrity sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw== +autoprefixer@^10.4.13: + version "10.4.13" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" + integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg== dependencies: - browserslist "^4.21.3" - caniuse-lite "^1.0.30001373" + browserslist "^4.21.4" + caniuse-lite "^1.0.30001426" fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" @@ -886,17 +909,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browser-cookies@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browser-cookies/-/browser-cookies-1.2.0.tgz#fca3ffb9b6a63aadc4d8c0999c6b57d0fa7d29b5" - integrity sha1-/KP/ubamOq3E2MCZnGtX0Pp9KbU= - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browserslist@^4.0.0, browserslist@^4.16.6, browserslist@^4.20.3, browserslist@^4.21.3: +browserslist@^4.0.0, browserslist@^4.16.6: version "4.21.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== @@ -906,6 +919,16 @@ browserslist@^4.0.0, browserslist@^4.16.6, browserslist@^4.20.3, browserslist@^4 node-releases "^2.0.6" update-browserslist-db "^1.0.5" +browserslist@^4.21.4: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + buffer-crc32@^0.2.5, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" @@ -919,6 +942,13 @@ buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + c8@7.12.0: version "7.12.0" resolved "https://registry.yarnpkg.com/c8/-/c8-7.12.0.tgz#402db1c1af4af5249153535d1c84ad70c5c96b14" @@ -967,17 +997,17 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001373: - version "1.0.30001375" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz" - integrity sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: + version "1.0.30001434" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz#ec1ec1cfb0a93a34a0600d37903853030520a4e5" + integrity sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA== caseless@~0.12.0: version "0.12.0" resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chai@4.3.6, chai@^4.3.6: +chai@^4.3.6: version "4.3.6" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== @@ -990,6 +1020,19 @@ chai@4.3.6, chai@^4.3.6: pathval "^1.1.1" type-detect "^4.0.5" +chai@^4.3.7: + version "4.3.7" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" + integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== + 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" + chalk@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1209,11 +1252,30 @@ convert-source-map@^1.6.0: dependencies: safe-buffer "~5.1.1" +cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +cose-base@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-1.0.3.tgz#650334b41b869578a543358b80cda7e0abe0a60a" + integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== + dependencies: + layout-base "^1.0.0" + +cose-base@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-2.1.0.tgz#89b2d4a59d7bd0cde3138a4689825f3e8a5abd6a" + integrity sha512-HTMm07dhxq1dIPGWwpiVrIk9n+DH7KYmqWA786mLe8jDS+1ZjGtJGIIsJVKoseZXS6/FxiUWCJ2B7XzqUCuhPw== + dependencies: + layout-base "^2.0.0" + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" @@ -1223,12 +1285,12 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-declaration-sorter@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz#72ebd995c8f4532ff0036631f7365cce9759df14" - integrity sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og== +css-declaration-sorter@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" + integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w== -css-select@^4.1.3, css-select@^4.2.1: +css-select@^4.1.3: version "4.2.1" resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== @@ -1239,6 +1301,17 @@ css-select@^4.1.3, css-select@^4.2.1: domutils "^2.8.0" nth-check "^2.0.1" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + css-selector-tokenizer@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd" @@ -1260,6 +1333,11 @@ css-what@^5.1.0: resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + css.escape@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" @@ -1270,25 +1348,25 @@ cssesc@^3.0.0: resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^5.2.12: - version "5.2.12" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" - integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== +cssnano-preset-default@^5.2.13: + version "5.2.13" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz#e7353b0c57975d1bdd97ac96e68e5c1b8c68e990" + integrity sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ== dependencies: - css-declaration-sorter "^6.3.0" + css-declaration-sorter "^6.3.1" cssnano-utils "^3.1.0" postcss-calc "^8.2.3" postcss-colormin "^5.3.0" - postcss-convert-values "^5.1.2" + postcss-convert-values "^5.1.3" postcss-discard-comments "^5.1.2" postcss-discard-duplicates "^5.1.0" postcss-discard-empty "^5.1.1" postcss-discard-overridden "^5.1.0" - postcss-merge-longhand "^5.1.6" - postcss-merge-rules "^5.1.2" + postcss-merge-longhand "^5.1.7" + postcss-merge-rules "^5.1.3" postcss-minify-font-values "^5.1.0" postcss-minify-gradients "^5.1.1" - postcss-minify-params "^5.1.3" + postcss-minify-params "^5.1.4" postcss-minify-selectors "^5.2.1" postcss-normalize-charset "^5.1.0" postcss-normalize-display-values "^5.1.0" @@ -1296,11 +1374,11 @@ cssnano-preset-default@^5.2.12: postcss-normalize-repeat-style "^5.1.1" postcss-normalize-string "^5.1.0" postcss-normalize-timing-functions "^5.1.0" - postcss-normalize-unicode "^5.1.0" + postcss-normalize-unicode "^5.1.1" postcss-normalize-url "^5.1.0" postcss-normalize-whitespace "^5.1.1" postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.0" + postcss-reduce-initial "^5.1.1" postcss-reduce-transforms "^5.1.0" postcss-svgo "^5.1.0" postcss-unique-selectors "^5.1.1" @@ -1310,12 +1388,12 @@ cssnano-utils@^3.1.0: resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== -cssnano@5.1.12: - version "5.1.12" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.12.tgz#bcd0b64d6be8692de79332c501daa7ece969816c" - integrity sha512-TgvArbEZu0lk/dvg2ja+B7kYoD7BBCmn3+k58xD0qjrGHsFzXY/wKTo9M5egcUCabPol05e/PVoIu79s2JN4WQ== +cssnano@^5.1.14: + version "5.1.14" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.14.tgz#07b0af6da73641276fe5a6d45757702ebae2eb05" + integrity sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw== dependencies: - cssnano-preset-default "^5.2.12" + cssnano-preset-default "^5.2.13" lilconfig "^2.0.3" yaml "^1.10.2" @@ -1343,20 +1421,20 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -cy-verify-downloads@0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/cy-verify-downloads/-/cy-verify-downloads-0.1.8.tgz#e16e86f1a6cc17376c39b4c5aa53e5ffa630c9c0" - integrity sha512-hfcgXd/YAtoN6TRmuy26DetcxBkApMJPBJI/T61KrV4PciOaWZtFhxPaiF7Kn2aE8XzXt1Os3HULM2Yp8A1mfw== +cy-verify-downloads@0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/cy-verify-downloads/-/cy-verify-downloads-0.1.11.tgz#9d9852066e6e6097d252872d9fbe0eacd1c1dea2" + integrity sha512-jR+0GKw9pGWy0lVQJDXhyZLyH2B6EOnqysKFIomf4eW2BVuzqAnuIIoC0gsY1Y7k8AUB8yPSJehUtAr2CKAF/Q== -cypress-localstorage-commands@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cypress-localstorage-commands/-/cypress-localstorage-commands-2.2.0.tgz#324030aba6a3915c27db95987e80223212da5d64" - integrity sha512-kIPxqe2yATmas3UcqK8Famecg6jThV/DQ2XcKCzK9BbzljU5Mfl2RtuzrXOmLc7phm8CIGbzXH57IIoyPsndwg== +cypress-localstorage-commands@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cypress-localstorage-commands/-/cypress-localstorage-commands-2.2.1.tgz#9895d75a3e8059e78d61231c5794dc46e0fc5fdd" + integrity sha512-m7IwoM+BMOJj7FzzN4It268c/i/Ur72CQX8JwLICkQ6ZgF1XNJOIKlQ7Rszg45ATLTjVTL1QElKCZECoU8cthQ== -cypress@10.4.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.4.0.tgz#bb5b3b6588ad49eff172fecf5778cc0da2980e4e" - integrity sha512-OM7F8MRE01SHQRVVzunid1ZK1m90XTxYnl+7uZfIrB4CYqUDCrZEeSyCXzIbsS6qcaijVCAhqDL60SxG8N6hew== +cypress@11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-11.2.0.tgz#63edef8c387b687066c5493f6f0ad7b9ced4b2b7" + integrity sha512-u61UGwtu7lpsNWLUma/FKNOsrjcI6wleNmda/TyKHe0dOBcVjbCPlp1N6uwFZ0doXev7f/91YDpU9bqDCFeBLA== dependencies: "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4" @@ -1377,7 +1455,7 @@ cypress@10.4.0: dayjs "^1.10.4" debug "^4.3.2" enquirer "^2.3.6" - eventemitter2 "^6.4.3" + eventemitter2 "6.4.7" execa "4.1.0" executable "^4.1.1" extract-zip "2.0.1" @@ -1401,6 +1479,28 @@ cypress@10.4.0: untildify "^4.0.0" yauzl "^2.10.0" +cytoscape-cose-bilkent@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz#762fa121df9930ffeb51a495d87917c570ac209b" + integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== + dependencies: + cose-base "^1.0.0" + +cytoscape-fcose@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cytoscape-fcose/-/cytoscape-fcose-2.1.0.tgz#04c3093776ea6b71787009de641607db7d4edf55" + integrity sha512-Q3apPl66jf8/2sMsrCjNP247nbDkyIPjA9g5iPMMWNLZgP3/mn9aryF7EFY/oRPEpv7bKJ4jYmCoU5r5/qAc1Q== + dependencies: + cose-base "^2.0.0" + +cytoscape@^3.23.0: + version "3.23.0" + resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.23.0.tgz#054ee05a6d0aa3b4f139382bbf2f4e5226df3c6d" + integrity sha512-gRZqJj/1kiAVPkrVFvz/GccxsXhF3Qwpptl32gKKypO4IlqnKBjTOu+HbXtEggSGzC5KCaHp3/F7GgENrtsFkA== + dependencies: + heap "^0.2.6" + lodash "^4.17.21" + d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: version "1.2.4" resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" @@ -1911,10 +2011,10 @@ dagre@^0.8.5: graphlib "^2.1.8" lodash "^4.17.15" -daisyui@2.22.0: - version "2.22.0" - resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-2.22.0.tgz#00ea4948fb886ad5242bd6bd3d1a229a8f28d932" - integrity sha512-H08aQP+Mfl2fQOmyaxd1NP54gQbr2xRUj2MmFFvfJ5EDGbthVBICDMNFKyia/zBfR58G8eTJo3CmydglM81/7Q== +daisyui@2.42.1: + version "2.42.1" + resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-2.42.1.tgz#68a5778249117bf013be93808ef091256ee54c54" + integrity sha512-IVeEvP8gvOzHR47fMrOp2YocQJMRmYskhdt7OsuhKJNn+YzLRGOpVpY7AGXt/56pYeYy7h03THHXRTW5cVU9rQ== dependencies: color "^4.2" css-selector-tokenizer "^0.8.0" @@ -1978,10 +2078,10 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -decimal.js@^10.3.1: - version "10.3.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" - integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== +decimal.js@^10.4.2: + version "10.4.2" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e" + integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA== deep-eql@^3.0.1: version "3.0.1" @@ -1990,6 +2090,13 @@ deep-eql@^3.0.1: dependencies: type-detect "^4.0.0" +deep-eql@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.2.tgz#270ceb902f87724077e6f6449aed81463f42fc1c" + integrity sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w== + dependencies: + type-detect "^4.0.0" + deep-is@^0.1.3: version "0.1.3" resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" @@ -2036,6 +2143,11 @@ detective@^5.2.1: defined "^1.0.0" minimist "^1.2.6" +devalue@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/devalue/-/devalue-4.2.0.tgz#3f542d7c828e317bab5fd3bcecde210af8f83d4b" + integrity sha512-mbjoAaCL2qogBKgeFxFPOXAUsZchircF+B/79LD4sHH0+NHfYm8gZpQrskKDn5gENGt35+5OI1GUF7hLVnkPDw== + didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" @@ -2092,11 +2204,25 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + domexception@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" @@ -2118,10 +2244,17 @@ domhandler@^4.3.0: dependencies: domelementtype "^2.2.0" -dompurify@2.3.10: - version "2.3.10" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.10.tgz#901f7390ffe16a91a5a556b94043314cd4850385" - integrity sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g== +domhandler@^5.0.1, domhandler@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +dompurify@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.0.tgz#c9c88390f024c2823332615c9e20a453cf3825dd" + integrity sha512-Be9tbQMZds4a3C6xTmz68NlMfeONA//4dOavl/1rNw50E+/QO0KVpbcU0PcaW0nsQxurXls9ZocqFxk8R2mWEA== domutils@^2.8.0: version "2.8.0" @@ -2132,6 +2265,15 @@ domutils@^2.8.0: domelementtype "^2.2.0" domhandler "^4.2.0" +domutils@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" + integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.1" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" @@ -2155,6 +2297,11 @@ electron-to-chromium@^1.4.202: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.211.tgz#afaa8b58313807501312d598d99b953568d60f91" integrity sha512-BZSbMpyFQU0KBJ1JG26XGeFI3i4op+qOYGxftmZXFZoHkhLgsSv4DHDJfl8ogII3hIuzGt51PaZ195OVu0yJ9A== +electron-to-chromium@^1.4.251: + version "1.4.261" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.261.tgz#31f14ad60c6f95bec404a77a2fd5e1962248e112" + integrity sha512-fVXliNUGJ7XUVJSAasPseBbVgJIeyw5M1xIkgXdTSRjlmCqBbiSTsEdLOCJS31Fc8B7CaloQ/BFAg8By3ODLdg== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" @@ -2184,141 +2331,143 @@ entities@^2.0.0: resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.1.tgz#c34062a94c865c322f9d67b4384e4169bcede6a4" - integrity sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg== +entities@^4.2.0, entities@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" + integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== es6-promise@^3.1.2: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= -esbuild-android-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.49.tgz#9e4682c36dcf6e7b71b73d2a3723a96e0fdc5054" - integrity sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww== +esbuild-android-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.10.tgz#8a59a84acbf2eca96996cadc35642cf055c494f0" + integrity sha512-UI7krF8OYO1N7JYTgLT9ML5j4+45ra3amLZKx7LO3lmLt1Ibn8t3aZbX5Pu4BjWiqDuJ3m/hsvhPhK/5Y/YpnA== -esbuild-android-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.49.tgz#9861b1f7e57d1dd1f23eeef6198561c5f34b51f6" - integrity sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g== +esbuild-android-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.10.tgz#f453851dc1d8c5409a38cf7613a33852faf4915d" + integrity sha512-EOt55D6xBk5O05AK8brXUbZmoFj4chM8u3riGflLa6ziEoVvNjRdD7Cnp82NHQGfSHgYR06XsPI8/sMuA/cUwg== -esbuild-darwin-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.49.tgz#fd30a5ebe28704a3a117126c60f98096c067c8d1" - integrity sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg== +esbuild-darwin-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.10.tgz#778bd29c8186ff47b176c8af58c08cf0fb8e6b86" + integrity sha512-hbDJugTicqIm+WKZgp208d7FcXcaK8j2c0l+fqSJ3d2AzQAfjEYDRM3Z2oMeqSJ9uFxyj/muSACLdix7oTstRA== -esbuild-darwin-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.49.tgz#c04a3a57dad94a972c66a697a68a25aa25947f41" - integrity sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A== +esbuild-darwin-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.10.tgz#b30bbefb46dc3c5d4708b0435e52f6456578d6df" + integrity sha512-M1t5+Kj4IgSbYmunf2BB6EKLkWUq+XlqaFRiGOk8bmBapu9bCDrxjf4kUnWn59Dka3I27EiuHBKd1rSO4osLFQ== -esbuild-freebsd-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.49.tgz#c404dbd66c98451395b1eef0fa38b73030a7be82" - integrity sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ== +esbuild-freebsd-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.10.tgz#ab301c5f6ded5110dbdd611140bef1a7c2e99236" + integrity sha512-KMBFMa7C8oc97nqDdoZwtDBX7gfpolkk6Bcmj6YFMrtCMVgoU/x2DI1p74DmYl7CSS6Ppa3xgemrLrr5IjIn0w== -esbuild-freebsd-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.49.tgz#b62cec96138ebc5937240ce3e1b97902963ea74a" - integrity sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA== +esbuild-freebsd-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.10.tgz#a5b09b867a6ff49110f52343b6f12265db63d43f" + integrity sha512-m2KNbuCX13yQqLlbSojFMHpewbn8wW5uDS6DxRpmaZKzyq8Dbsku6hHvh2U+BcLwWY4mpgXzFUoENEf7IcioGg== -esbuild-linux-32@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.49.tgz#495b1cc011b8c64d8bbaf65509c1e7135eb9ddbf" - integrity sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA== +esbuild-linux-32@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.10.tgz#5282fe9915641caf9c8070e4ba2c3e16d358f837" + integrity sha512-guXrwSYFAvNkuQ39FNeV4sNkNms1bLlA5vF1H0cazZBOLdLFIny6BhT+TUbK/hdByMQhtWQ5jI9VAmPKbVPu1w== -esbuild-linux-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.49.tgz#3f28dd8f986e6ff42f38888ee435a9b1fb916a56" - integrity sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg== +esbuild-linux-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.10.tgz#f3726e85a00149580cb19f8abfabcbb96f5d52bb" + integrity sha512-jd8XfaSJeucMpD63YNMO1JCrdJhckHWcMv6O233bL4l6ogQKQOxBYSRP/XLWP+6kVTu0obXovuckJDcA0DKtQA== -esbuild-linux-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.49.tgz#a52e99ae30246566dc5f33e835aa6ca98ef70e33" - integrity sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA== +esbuild-linux-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.10.tgz#2f0056e9d5286edb0185b56655caa8c574d8dbe7" + integrity sha512-GByBi4fgkvZFTHFDYNftu1DQ1GzR23jws0oWyCfhnI7eMOe+wgwWrc78dbNk709Ivdr/evefm2PJiUBMiusS1A== -esbuild-linux-arm@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.49.tgz#7c33d05a64ec540cf7474834adaa57b3167bbe97" - integrity sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg== +esbuild-linux-arm@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.10.tgz#40a9270da3c8ffa32cf72e24a79883e323dff08d" + integrity sha512-6N8vThLL/Lysy9y4Ex8XoLQAlbZKUyExCWyayGi2KgTBelKpPgj6RZnUaKri0dHNPGgReJriKVU6+KDGQwn10A== -esbuild-linux-mips64le@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.49.tgz#ed062bd844b587be649443831eb84ba304685f25" - integrity sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA== +esbuild-linux-mips64le@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.10.tgz#90ce1c4ee0202edb4ac69807dea77f7e5804abc4" + integrity sha512-BxP+LbaGVGIdQNJUNF7qpYjEGWb0YyHVSKqYKrn+pTwH/SiHUxFyJYSP3pqkku61olQiSBnSmWZ+YUpj78Tw7Q== -esbuild-linux-ppc64le@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.49.tgz#c0786fb5bddffd90c10a2078181513cbaf077958" - integrity sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw== +esbuild-linux-ppc64le@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.10.tgz#782837ae7bd5b279178106c9dd801755a21fabdf" + integrity sha512-LoSQCd6498PmninNgqd/BR7z3Bsk/mabImBWuQ4wQgmQEeanzWd5BQU2aNi9mBURCLgyheuZS6Xhrw5luw3OkQ== -esbuild-linux-riscv64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.49.tgz#579b0e7cc6fce4bfc698e991a52503bb616bec49" - integrity sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ== +esbuild-linux-riscv64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.10.tgz#d7420d806ece5174f24f4634303146f915ab4207" + integrity sha512-Lrl9Cr2YROvPV4wmZ1/g48httE8z/5SCiXIyebiB5N8VT7pX3t6meI7TQVHw/wQpqP/AF4SksDuFImPTM7Z32Q== -esbuild-linux-s390x@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.49.tgz#09eb15c753e249a500b4e28d07c5eef7524a9740" - integrity sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ== +esbuild-linux-s390x@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.10.tgz#21fdf0cb3494a7fb520a71934e4dffce67fe47be" + integrity sha512-ReP+6q3eLVVP2lpRrvl5EodKX7EZ1bS1/z5j6hsluAlZP5aHhk6ghT6Cq3IANvvDdscMMCB4QEbI+AjtvoOFpA== -esbuild-netbsd-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.49.tgz#f7337cd2bddb7cc9d100d19156f36c9ca117b58d" - integrity sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ== +esbuild-netbsd-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.10.tgz#6c06b3107e3df53de381e6299184d4597db0440f" + integrity sha512-iGDYtJCMCqldMskQ4eIV+QSS/CuT7xyy9i2/FjpKvxAuCzrESZXiA1L64YNj6/afuzfBe9i8m/uDkFHy257hTw== -esbuild-openbsd-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.49.tgz#1f8bdc49f8a44396e73950a3fb6b39828563631d" - integrity sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA== +esbuild-openbsd-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.10.tgz#4daef5f5d8e74bbda53b65160029445d582570cf" + integrity sha512-ftMMIwHWrnrYnvuJQRJs/Smlcb28F9ICGde/P3FUTCgDDM0N7WA0o9uOR38f5Xe2/OhNCgkjNeb7QeaE3cyWkQ== -esbuild-sunos-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.49.tgz#47d042739365b61aa8ca642adb69534a8eef9f7a" - integrity sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw== +esbuild-sunos-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.10.tgz#5fe7bef267a02f322fd249a8214d0274937388a7" + integrity sha512-mf7hBL9Uo2gcy2r3rUFMjVpTaGpFJJE5QTDDqUFf1632FxteYANffDZmKbqX0PfeQ2XjUDE604IcE7OJeoHiyg== -esbuild-windows-32@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.49.tgz#79198c88ec9bde163c18a6b430c34eab098ec21a" - integrity sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA== +esbuild-windows-32@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.10.tgz#48e3dde25ab0135579a288b30ab6ddef6d1f0b28" + integrity sha512-ttFVo+Cg8b5+qHmZHbEc8Vl17kCleHhLzgT8X04y8zudEApo0PxPg9Mz8Z2cKH1bCYlve1XL8LkyXGFjtUYeGg== -esbuild-windows-64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.49.tgz#b36b230d18d1ee54008e08814c4799c7806e8c79" - integrity sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw== +esbuild-windows-64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.10.tgz#387a9515bef3fee502d277a5d0a2db49a4ecda05" + integrity sha512-2H0gdsyHi5x+8lbng3hLbxDWR7mKHWh5BXZGKVG830KUmXOOWFE2YKJ4tHRkejRduOGDrBvHBriYsGtmTv3ntA== -esbuild-windows-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.49.tgz#d83c03ff6436caf3262347cfa7e16b0a8049fae7" - integrity sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA== +esbuild-windows-arm64@0.15.10: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.10.tgz#5a6fcf2fa49e895949bf5495cf088ab1b43ae879" + integrity sha512-S+th4F+F8VLsHLR0zrUcG+Et4hx0RKgK1eyHc08kztmLOES8BWwMiaGdoW9hiXuzznXQ0I/Fg904MNbr11Nktw== -esbuild@^0.14.47: - version "0.14.49" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.49.tgz#b82834760eba2ddc17b44f05cfcc0aaca2bae492" - integrity sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw== +esbuild@^0.15.9: + version "0.15.10" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.10.tgz#85c2f8446e9b1fe04fae68daceacba033eedbd42" + integrity sha512-N7wBhfJ/E5fzn/SpNgX+oW2RLRjwaL8Y0ezqNqhjD6w0H2p0rDuEz2FKZqpqLnO8DCaWumKe8dsC/ljvVSSxng== optionalDependencies: - esbuild-android-64 "0.14.49" - esbuild-android-arm64 "0.14.49" - esbuild-darwin-64 "0.14.49" - esbuild-darwin-arm64 "0.14.49" - esbuild-freebsd-64 "0.14.49" - esbuild-freebsd-arm64 "0.14.49" - esbuild-linux-32 "0.14.49" - esbuild-linux-64 "0.14.49" - esbuild-linux-arm "0.14.49" - esbuild-linux-arm64 "0.14.49" - esbuild-linux-mips64le "0.14.49" - esbuild-linux-ppc64le "0.14.49" - esbuild-linux-riscv64 "0.14.49" - esbuild-linux-s390x "0.14.49" - esbuild-netbsd-64 "0.14.49" - esbuild-openbsd-64 "0.14.49" - esbuild-sunos-64 "0.14.49" - esbuild-windows-32 "0.14.49" - esbuild-windows-64 "0.14.49" - esbuild-windows-arm64 "0.14.49" + "@esbuild/android-arm" "0.15.10" + "@esbuild/linux-loong64" "0.15.10" + esbuild-android-64 "0.15.10" + esbuild-android-arm64 "0.15.10" + esbuild-darwin-64 "0.15.10" + esbuild-darwin-arm64 "0.15.10" + esbuild-freebsd-64 "0.15.10" + esbuild-freebsd-arm64 "0.15.10" + esbuild-linux-32 "0.15.10" + esbuild-linux-64 "0.15.10" + esbuild-linux-arm "0.15.10" + esbuild-linux-arm64 "0.15.10" + esbuild-linux-mips64le "0.15.10" + esbuild-linux-ppc64le "0.15.10" + esbuild-linux-riscv64 "0.15.10" + esbuild-linux-s390x "0.15.10" + esbuild-netbsd-64 "0.15.10" + esbuild-openbsd-64 "0.15.10" + esbuild-sunos-64 "0.15.10" + esbuild-windows-32 "0.15.10" + esbuild-windows-64 "0.15.10" + esbuild-windows-arm64 "0.15.10" escalade@^3.1.1: version "3.1.1" @@ -2367,6 +2516,11 @@ eslint-plugin-es@4.1.0: eslint-utils "^2.0.0" regexpp "^3.0.0" +eslint-plugin-no-only-tests@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz#f38e4935c6c6c4842bf158b64aaa20c366fe171b" + integrity sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw== + eslint-plugin-postcss-modules@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-postcss-modules/-/eslint-plugin-postcss-modules-2.0.0.tgz#d136d6fb5bd9afa6ac73c22aea85212aa2531806" @@ -2388,21 +2542,21 @@ eslint-plugin-svelte3@4.0.0: resolved "https://registry.yarnpkg.com/eslint-plugin-svelte3/-/eslint-plugin-svelte3-4.0.0.tgz#3d4f3dcaec5761dac8bc697f81de3613b485b4e3" integrity sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g== -eslint-plugin-tailwindcss@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.6.0.tgz#b29605a53b5c27b7e74986ca7fcc0c6bdc435ad3" - integrity sha512-gWLGNWHuhh5ngwkJ2sgSByanpRw2s5GdrM2ff2/w8Ho2mWh2MyGvpnFZpL4b0XT/C0WF9zlq57+vFHJOeFhMkg== +eslint-plugin-tailwindcss@3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.7.0.tgz#09f39b18d73141a18e7cb2431bcab89f68010b31" + integrity sha512-e/Pe2jr0vbvNnDXylHoubDGwSh4Z5a4ZhZrkUKHU4MYdSUpjFSofGoMwBSU3d1TybTbo89ENCEWnl1BVAM1iuQ== dependencies: fast-glob "^3.2.5" postcss "^8.4.4" - tailwindcss "^3.1.3" + tailwindcss "^3.2.2" -eslint-plugin-vitest@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/eslint-plugin-vitest/-/eslint-plugin-vitest-0.0.8.tgz#3c04ae5fa53b284e42ea48463b70582bec0f2f4c" - integrity sha512-6xn2b4Cspn7Qc0v/ZMCq13fmsucnkEeUeKCna57M5vayvreshHEUFVgjtsksnyODlHIm9oyVfNfSFkToYz/dJg== +eslint-plugin-vitest@^0.0.20: + version "0.0.20" + resolved "https://registry.yarnpkg.com/eslint-plugin-vitest/-/eslint-plugin-vitest-0.0.20.tgz#875f1bb086e66bdd12b7c60f59ddd1dfa28252d7" + integrity sha512-c4Rap+L5L9jkjwo9EubiLaJn0gp1bDQD7kyVR8IU6gUONtBba/hC/zlpd85svWKPuU4Ko6OOk/4AUtYfaGCHzA== dependencies: - "@typescript-eslint/utils" "^5.17.0" + "@typescript-eslint/utils" "^5.42.1" eslint-scope@^5.1.1: version "5.1.1" @@ -2449,14 +2603,15 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@8.21.0: - version "8.21.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.21.0.tgz#1940a68d7e0573cef6f50037addee295ff9be9ef" - integrity sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA== +eslint@8.28.0: + version "8.28.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.28.0.tgz#81a680732634677cc890134bcdd9fdfea8e63d6e" + integrity sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ== dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.10.4" - "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + "@eslint/eslintrc" "^1.3.3" + "@humanwhocodes/config-array" "^0.11.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -2466,21 +2621,21 @@ eslint@8.21.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.3" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" find-up "^5.0.0" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" + glob-parent "^6.0.2" globals "^13.15.0" - globby "^11.1.0" grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -2492,21 +2647,11 @@ eslint@8.21.0: strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.3.2: - version "9.3.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" - integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== - dependencies: - acorn "^8.7.1" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" - -espree@^9.3.3: - version "9.3.3" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d" - integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng== +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: acorn "^8.8.0" acorn-jsx "^5.3.2" @@ -2531,10 +2676,10 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -esserializer@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/esserializer/-/esserializer-1.3.2.tgz#4788444a7d08108a57ddc6a77602e8c853d3f8da" - integrity sha512-48xQjlQ9Wr6dUfjLAC1IQF0bMIk6m62mN7BH0PklRP0NDfm2ISY16EXM8t2Wfc6WcLKser+X8ggeeFwieBkufQ== +esserializer@1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/esserializer/-/esserializer-1.3.5.tgz#f6ab48102ab53d14d51ba2821fec77e49a75ce47" + integrity sha512-eBEv+JLJWSwhxLzKcCIrFU3uYp/dB7RiXx9plISk5wIX/3LkZ2Xxyrnpy+XxJdvlkJqoAhKEn0uVNfBX9lxVDg== estraverse@^4.1.1: version "4.3.0" @@ -2546,20 +2691,15 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== -estree-walker@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - esutils@^2.0.2: version "2.0.3" resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -eventemitter2@^6.4.3: - version "6.4.4" - resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.4.tgz" - integrity sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw== +eventemitter2@6.4.7: + version "6.4.7" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== execa@4.1.0: version "4.1.0" @@ -2624,6 +2764,11 @@ extsprintf@^1.2.0: resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= +fast-clone@^1.5.13: + version "1.5.13" + resolved "https://registry.yarnpkg.com/fast-clone/-/fast-clone-1.5.13.tgz#7fe17542ae1c872e71bf80d177d00c11f51c2ea7" + integrity sha512-0ez7coyFBQFjZtId+RJqJ+EQs61w9xARfqjqK0AD9vIUkSxWD4HvPt80+5evebZ1tTnv1GYKrPTipx7kOW5ipA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -2640,6 +2785,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.5, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.2.12: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" @@ -2726,6 +2882,11 @@ folktale@2.3.2: resolved "https://registry.npmjs.org/folktale/-/folktale-2.3.2.tgz" integrity sha512-+8GbtQBwEqutP0v3uajDDoN64K2ehmHd0cjlghhxh0WpcfPzAIjPA03e1VvHlxL02FVGR0A6lwXsNQKn3H1RNQ== +font-awesome@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" + integrity sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg== + foreground-child@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" @@ -2787,11 +2948,6 @@ function-bind@^1.1.1: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" @@ -2835,7 +2991,7 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1, glob-parent@^6.0.2: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -2958,6 +3114,11 @@ he@1.2.0: resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +heap@^0.2.6: + version "0.2.7" + resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" + integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== + html-encoding-sniffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" @@ -3006,10 +3167,10 @@ human-signals@^3.0.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== -husky@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.1.tgz#511cb3e57de3e3190514ae49ed50f6bc3f50b3e9" - integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw== +husky@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.2.tgz#5816a60db02650f1f22c8b69b928fd6bcd77a236" + integrity sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg== iconv-lite@0.4: version "0.4.24" @@ -3030,13 +3191,6 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -idb-keyval@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-5.1.3.tgz#6ef5dff371897c23f144322dc6374eadd6a345d9" - integrity sha512-N9HbCK/FaXSRVI+k6Xq4QgWxbcZRUv+SfG1y7HJ28JdV8yEJu6k+C/YLea7npGckX2DQJeEVuMc4bKOBeU/2LQ== - dependencies: - safari-14-idb-fix "^1.0.4" - ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -3154,7 +3308,7 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-path-inside@^3.0.2: +is-path-inside@^3.0.2, is-path-inside@^3.0.3: 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== @@ -3246,10 +3400,10 @@ jest-matcher-utils@^28.0.0: jest-get-type "^28.0.2" pretty-format "^28.1.1" -js-base64@3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.2.tgz#816d11d81a8aff241603d19ce5761e13e41d7745" - integrity sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ== +js-base64@3.7.3: + version "3.7.3" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.3.tgz#2e784bb0851636bf1e99ef12e4f3a8a8c9b7639f" + integrity sha512-PAr6Xg2jvd7MCR6Ld9Jg3BmTcjYsHEBx1VlwEwULb/qowPf5VD9kEMagj23Gm7JRnSvE/Da/57nChZjnvL8v6A== js-beautify@1.10.3: version "1.10.3" @@ -3262,6 +3416,11 @@ js-beautify@1.10.3: mkdirp "~0.5.1" nopt "~4.0.1" +js-sdsl@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.4.tgz#78793c90f80e8430b7d8dc94515b6c77d98a26a6" + integrity sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" @@ -3279,18 +3438,18 @@ jsbn@~0.1.0: resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@20.0.0: - version "20.0.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.0.tgz#882825ac9cc5e5bbee704ba16143e1fa78361ebf" - integrity sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA== +jsdom@20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" + integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ== dependencies: abab "^2.0.6" - acorn "^8.7.1" - acorn-globals "^6.0.0" + acorn "^8.8.1" + acorn-globals "^7.0.0" cssom "^0.5.0" cssstyle "^2.3.0" data-urls "^3.0.2" - decimal.js "^10.3.1" + decimal.js "^10.4.2" domexception "^4.0.0" escodegen "^2.0.0" form-data "^4.0.0" @@ -3298,18 +3457,17 @@ jsdom@20.0.0: http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.1" is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "^7.0.0" + nwsapi "^2.2.2" + parse5 "^7.1.1" saxes "^6.0.0" symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^3.0.0" + tough-cookie "^4.1.2" + w3c-xmlserializer "^4.0.0" webidl-conversions "^7.0.0" whatwg-encoding "^2.0.0" whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" - ws "^8.8.0" + ws "^8.11.0" xml-name-validator "^4.0.0" json-schema-traverse@^0.4.1: @@ -3361,6 +3519,16 @@ kleur@^4.1.5: resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== +layout-base@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-1.0.2.tgz#1291e296883c322a9dd4c5dd82063721b53e26e2" + integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== + +layout-base@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-2.0.1.tgz#d0337913586c90f9c2c075292069f5c2da5dd285" + integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== + lazy-ass@1.6.0, lazy-ass@^1.6.0: version "1.6.0" resolved "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz" @@ -3528,10 +3696,10 @@ magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.4" -magic-string@^0.26.2: - version "0.26.2" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" - integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== +magic-string@^0.26.7: + version "0.26.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.7.tgz#caf7daf61b34e9982f8228c4527474dac8981d6f" + integrity sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow== dependencies: sourcemap-codec "^1.4.8" @@ -3557,20 +3725,24 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -mermaid@9.1.5: - version "9.1.5" - resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-9.1.5.tgz#9be3efb6b54942ab4f08bf3dd30a2ba77cfbdad7" - integrity sha512-XoikwsOTTwsf/bKrTKjE5vCWXuhrOocA+/v3ynmdb0PIO1UEdfRLUNb70Cssz4TxTADX6HzeWYsUBCATBi7F1w== +mermaid@9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-9.2.2.tgz#73cca1f0b74e7e674c0de3519d7e7e8ea83bea4a" + integrity sha512-6s7eKMqFJGS+0MYjmx8f6ZigqKBJVoSx5ql2gw6a4Aa+WJ49QiEJg7gPwywaBg3DZMs79UP7trESp4+jmaQccw== dependencies: "@braintree/sanitize-url" "^6.0.0" d3 "^7.0.0" dagre "^0.8.5" dagre-d3 "^0.6.4" - dompurify "2.3.10" + dompurify "2.4.0" + fast-clone "^1.5.13" graphlib "^2.1.8" khroma "^2.0.0" - moment-mini "2.24.0" - stylis "^4.0.10" + lodash "^4.17.21" + moment-mini "^2.24.0" + non-layered-tidy-tree-layout "^2.0.2" + stylis "^4.1.2" + uuid "^9.0.0" micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" @@ -3592,6 +3764,11 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "1.47.0" +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" @@ -3607,7 +3784,7 @@ min-indent@^1.0.0: resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -3626,25 +3803,25 @@ mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" -moment-mini@2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.24.0.tgz#fa68d98f7fe93ae65bf1262f6abb5fb6983d8d18" - integrity sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ== +moment-mini@^2.24.0: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.29.4.tgz#cbbcdc58ce1b267506f28ea6668dbe060a32758f" + integrity sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg== moment@2.29.4: version "2.29.4" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== -monaco-editor@0.34.0: - version "0.34.0" - resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.34.0.tgz#b1749870a1f795dbfc4dc03d8e9b646ddcbeefa7" - integrity sha512-VF+S5zG8wxfinLKLrWcl4WUizMx+LeJrG4PM/M78OhcwocpV0jiyhX/pG6Q9jIOhrb/ckYi6nHnaR5OojlOZCQ== +monaco-editor@0.34.1: + version "0.34.1" + resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.34.1.tgz#1b75c4ad6bc4c1f9da656d740d98e0b850a22f87" + integrity sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ== -monaco-mermaid@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/monaco-mermaid/-/monaco-mermaid-1.0.6.tgz#2f0db5b38cb0c6539a28d5e5758dc24f88d931f3" - integrity sha512-ntPXb1DPQ9k4/3pV3GLXF39KZOXrpns9nfB5On77nFATuUwN81N/clOR9SvGnoQhcP7n8A0ppE8JVNeYfVF97g== +monaco-mermaid@1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/monaco-mermaid/-/monaco-mermaid-1.0.8.tgz#6bc461c0529f5a8d707d03ad88c90425107fc127" + integrity sha512-D6v777Vkt62+ODZkoX9guv5Jlqe50tu+dZnnDQ86lAba4fIaFTjG3o8tbToniE1WCfIPGW6t+X/uXQuSPdkfMA== mri@^1.1.0: version "1.1.6" @@ -3676,6 +3853,11 @@ nanoid@^3.3.4: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" @@ -3686,12 +3868,12 @@ node-addon-api@^1.7.1: resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz" integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== -node-html-parser@5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-5.4.1.tgz#c9938b9521ef542c2374e4923078f8f2a365f50d" - integrity sha512-xy/O2wOEBJsIRLs4avwa1lVY7tIpXXOoHHUJLa0GvnoPPqMG1hgBVl1tNI3GHOwRktTVZy+Y6rjghk4B9/NLyg== +node-html-parser@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-6.1.4.tgz#763cd362497e427d51fc73dda3dcd8ac52ba85a3" + integrity sha512-3muP9Uy/Pz7bQa9TNYVQzWJhNZMqyCx7xJle8kz2/y1UgzAUyXXShc1IcPaJy6u07CE3K5rQcRwlvHzmlySRjg== dependencies: - css-select "^4.2.1" + css-select "^5.1.0" he "1.2.0" node-releases@^2.0.6: @@ -3699,6 +3881,11 @@ node-releases@^2.0.6: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +non-layered-tidy-tree-layout@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz#57d35d13c356643fc296a55fb11ac15e74da7804" + integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw== + nopt@~4.0.1: version "4.0.3" resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz" @@ -3743,10 +3930,10 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -nwsapi@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.1.tgz#10a9f268fbf4c461249ebcfe38e359aa36e2577c" - integrity sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg== +nwsapi@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" + integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== object-assign@^4.0.1: version "4.1.1" @@ -3852,10 +4039,10 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -pako@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" - integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== +pako@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== parent-module@^1.0.0: version "1.0.1" @@ -3864,12 +4051,12 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse5@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.0.0.tgz#51f74a5257f5fcc536389e8c2d0b3802e1bfa91a" - integrity sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g== +parse5@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.1.tgz#4649f940ccfb95d8754f37f73078ea20afe0c746" + integrity sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg== dependencies: - entities "^4.3.0" + entities "^4.4.0" path-exists@^4.0.0: version "4.0.0" @@ -3921,7 +4108,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2: +picomatch@^2.0.4, picomatch@^2.2.1: version "2.3.0" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== @@ -3941,10 +4128,15 @@ pify@^2.2.0, pify@^2.3.0: resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= -playwright-core@1.25.0: - version "1.25.0" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.25.0.tgz#54dc867c6c2cc5e4233905e249206a02914d14f1" - integrity sha512-kZ3Jwaf3wlu0GgU0nB8UMQ+mXFTqBIFz9h1svTlNduNKjnbPXFxw7mJanLVjqxHJRn62uBfmgBj93YHidk2N5Q== +plausible-tracker@^0.3.1: + version "0.3.8" + resolved "https://registry.yarnpkg.com/plausible-tracker/-/plausible-tracker-0.3.8.tgz#9b8b322cc41e0e1d6473869ef234deea365a5a40" + integrity sha512-lmOWYQ7s9KOUJ1R+YTOR3HrjdbxIS2Z4de0P/Jx2dQPteznJl2eX3tXxKClpvbfyGP59B5bbhW8ftN59HbbFSg== + +playwright-core@1.28.1: + version "1.28.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.28.1.tgz#8400be9f4a8d1c0489abdb9e75a4cc0ffc3c00cb" + integrity sha512-3PixLnGPno0E8rSBJjtwqTwJe3Yw72QwBBBxNoukIj3lEeBNXwbNiKrNuB1oyQgTBw5QHUhNO3SteEtHaMK6ag== postcss-calc@^8.2.3: version "8.2.4" @@ -3964,12 +4156,12 @@ postcss-colormin@^5.3.0: colord "^2.9.1" postcss-value-parser "^4.2.0" -postcss-convert-values@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz#31586df4e184c2e8890e8b34a0b9355313f503ab" - integrity sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g== +postcss-convert-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" + integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== dependencies: - browserslist "^4.20.3" + browserslist "^4.21.4" postcss-value-parser "^4.2.0" postcss-discard-comments@^5.1.2: @@ -4024,20 +4216,20 @@ postcss-load-config@^3.1.0, postcss-load-config@^3.1.4: lilconfig "^2.0.5" yaml "^1.10.2" -postcss-merge-longhand@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" - integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== +postcss-merge-longhand@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" + integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== dependencies: postcss-value-parser "^4.2.0" - stylehacks "^5.1.0" + stylehacks "^5.1.1" -postcss-merge-rules@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" - integrity sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ== +postcss-merge-rules@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz#8f97679e67cc8d08677a6519afca41edf2220894" + integrity sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" cssnano-utils "^3.1.0" postcss-selector-parser "^6.0.5" @@ -4058,12 +4250,12 @@ postcss-minify-gradients@^5.1.1: cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" -postcss-minify-params@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz#ac41a6465be2db735099bbd1798d85079a6dc1f9" - integrity sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg== +postcss-minify-params@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" + integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" @@ -4109,6 +4301,13 @@ postcss-nested@5.0.6: dependencies: postcss-selector-parser "^6.0.6" +postcss-nested@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.0.tgz#1572f1984736578f360cffc7eb7dca69e30d1735" + integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== + dependencies: + postcss-selector-parser "^6.0.10" + postcss-normalize-charset@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" @@ -4149,12 +4348,12 @@ postcss-normalize-timing-functions@^5.1.0: dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-unicode@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" - integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== +postcss-normalize-unicode@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" + integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" postcss-value-parser "^4.2.0" postcss-normalize-url@^5.1.0: @@ -4180,12 +4379,12 @@ postcss-ordered-values@^5.1.3: cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" -postcss-reduce-initial@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" - integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== +postcss-reduce-initial@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz#c18b7dfb88aee24b1f8e4936541c29adbd35224e" + integrity sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w== dependencies: - browserslist "^4.16.6" + browserslist "^4.21.4" caniuse-api "^3.0.0" postcss-reduce-transforms@^5.1.0: @@ -4223,7 +4422,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.4.16, postcss@^8.3.0, postcss@^8.4.14, postcss@^8.4.16, postcss@^8.4.4: +postcss@^8.3.0, postcss@^8.4.14, postcss@^8.4.16, postcss@^8.4.4: version "8.4.16" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== @@ -4232,6 +4431,24 @@ postcss@8.4.16, postcss@^8.3.0, postcss@^8.4.14, postcss@^8.4.16, postcss@^8.4.4 picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.18: + version "8.4.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.18.tgz#6d50046ea7d3d66a85e0e782074e7203bc7fbca2" + integrity sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^8.4.19: + version "8.4.19" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc" + integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" @@ -4242,15 +4459,15 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -prettier-plugin-svelte@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.7.0.tgz#ecfa4fe824238a4466a3497df1a96d15cf43cabb" - integrity sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA== +prettier-plugin-svelte@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.8.1.tgz#5b7df5bd0d953b133281607295a3e5131052bb8b" + integrity sha512-KA3K1J3/wKDnCxW7ZDRA/QL2Q67N7Xs3gOERqJ5X1qFjq1DdnN3K1R29scSKwh+kA8FF67pXbYytUpvN/i3iQw== -prettier@2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" - integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== +prettier@2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.0.tgz#c7df58393c9ba77d6fba3921ae01faf994fb9dc9" + integrity sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA== pretty-bytes@^5.6.0: version "5.6.0" @@ -4319,6 +4536,11 @@ qs@~6.5.2: resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" @@ -4393,6 +4615,11 @@ require-directory@^2.1.1: resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" @@ -4444,10 +4671,17 @@ robust-predicates@^3.0.0: resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a" integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g== -"rollup@>=2.75.6 <2.77.0 || ~2.77.0": - version "2.77.3" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.3.tgz#8f00418d3a2740036e15deb653bed1a90ee0cc12" - integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== +rollup@^2.79.1: + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + +rollup@~2.78.0: + version "2.78.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.78.1.tgz#52fe3934d9c83cb4f7c4cb5fb75d88591be8648f" + integrity sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg== optionalDependencies: fsevents "~2.3.2" @@ -4484,11 +4718,6 @@ sade@^1.8.1: dependencies: mri "^1.1.0" -safari-14-idb-fix@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/safari-14-idb-fix/-/safari-14-idb-fix-1.0.4.tgz#5c68ba63e2a8ae0d89a0aa1e13fe89e3aef7da19" - integrity sha512-4+Y2baQdgJpzu84d0QjySl70Kyygzf0pepVg8NVg4NnQEPpfC91fAn0baNvtStlCjUUxxiu0BOMiafa98fRRuA== - safe-buffer@^5.0.1, safe-buffer@^5.1.2: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -4538,6 +4767,11 @@ semver@^7.3.2, semver@^7.3.7: dependencies: lru-cache "^6.0.0" +set-cookie-parser@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.5.1.tgz#ddd3e9a566b0e8e0862aca974a6ac0e01349430b" + integrity sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -4681,6 +4915,11 @@ stable@^0.1.8: resolved "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + string-argv@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" @@ -4754,18 +4993,25 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -stylehacks@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" - integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== +strip-literal@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-0.4.2.tgz#4f9fa6c38bb157b924e9ace7155ebf8a2342cbcf" + integrity sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw== dependencies: - browserslist "^4.16.6" + acorn "^8.8.0" + +stylehacks@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== + dependencies: + browserslist "^4.21.4" postcss-selector-parser "^6.0.4" -stylis@^4.0.10: - version "4.0.10" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" - integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg== +stylis@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.2.tgz#870b3c1c2275f51b702bb3da9e94eedad87bba41" + integrity sha512-Nn2CCrG2ZaFziDxaZPN43CXqn+j7tcdjPFCkRBkFue8QYXC2HdEwnw5TCBo4yQZ2WxKYeSi0fdoOrtEqgDrXbA== supports-color@^2.0.0: version "2.0.0" @@ -4798,10 +5044,10 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -svelte-hmr@^0.14.12: - version "0.14.12" - resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f" - integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w== +svelte-hmr@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.15.1.tgz#d11d878a0bbb12ec1cba030f580cd2049f4ec86b" + integrity sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA== svelte-preprocess@4.10.7: version "4.10.7" @@ -4815,12 +5061,12 @@ svelte-preprocess@4.10.7: sorcery "^0.10.0" strip-indent "^3.0.0" -svelte@3.49.0: - version "3.49.0" - resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.49.0.tgz#5baee3c672306de1070c3b7888fc2204e36a4029" - integrity sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA== +svelte@3.53.1: + version "3.53.1" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.53.1.tgz#db9d7df7a8f570e8e22547444c149208b1914442" + integrity sha512-Q4/hHkktZogGhN5iqxqSi9sjEVoe/NbIxX4hXEHoasTxj+TxEQVAq66LnDMdAZxjmsodkoI5F3slqsS68U7FNw== -svg-pan-zoom@^3.6.1: +svg-pan-zoom@3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/svg-pan-zoom/-/svg-pan-zoom-3.6.1.tgz#f880a1bb32d18e9c625d7715350bebc269b450cf" integrity sha512-JaKkGHHfGvRrcMPdJWkssLBeWqM+Isg/a09H7kgNNajT1cX5AztDTNs+C8UzpCxjCTRrG34WbquwaovZbmSk9g== @@ -4843,7 +5089,7 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -tailwindcss@3.1.8, tailwindcss@^3, tailwindcss@^3.1.3: +tailwindcss@^3: version "3.1.8" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.8.tgz#4f8520550d67a835d32f2f4021580f9fddb7b741" integrity sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g== @@ -4871,6 +5117,35 @@ tailwindcss@3.1.8, tailwindcss@^3, tailwindcss@^3.1.3: quick-lru "^5.1.1" resolve "^1.22.1" +tailwindcss@^3.2.2, tailwindcss@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.4.tgz#afe3477e7a19f3ceafb48e4b083e292ce0dc0250" + integrity sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ== + dependencies: + arg "^5.0.2" + chokidar "^3.5.3" + color-name "^1.1.4" + detective "^5.2.1" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.2.12" + glob-parent "^6.0.2" + is-glob "^4.0.3" + lilconfig "^2.0.6" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.18" + postcss-import "^14.1.0" + postcss-js "^4.0.0" + postcss-load-config "^3.1.4" + postcss-nested "6.0.0" + postcss-selector-parser "^6.0.10" + postcss-value-parser "^4.2.0" + quick-lru "^5.1.1" + resolve "^1.22.1" + test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -4903,15 +5178,20 @@ tiny-glob@^0.2.9: globalyzer "0.1.0" globrex "^0.1.2" -tinypool@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.2.4.tgz#4d2598c4689d1a2ce267ddf3360a9c6b3925a20c" - integrity sha512-Vs3rhkUH6Qq1t5bqtb816oT+HeJTXfwt2cbPH17sWHIYKTotQIFPk3tf2fgqRrVyMDVOc1EnPgzIxfIulXVzwQ== +tinybench@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.3.1.tgz#14f64e6b77d7ef0b1f6ab850c7a808c6760b414d" + integrity sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA== -tinyspy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-1.0.0.tgz#0cb34587287b0432b33fe36a9bd945fe22b1eb89" - integrity sha512-FI5B2QdODQYDRjfuLF+OrJ8bjWRMCXokQPcwKm0W3IzcbUmBNv536cQc7eXGoAuXphZwgx1DFbqImwzz08Fnhw== +tinypool@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.3.0.tgz#c405d8b743509fc28ea4ca358433190be654f819" + integrity sha512-NX5KeqHOBZU6Bc0xj9Vr5Szbb1j8tUHIeD18s41aDJaPeC5QTdEhK0SpdpUrZlj2nv5cctNcSjaKNanXlfcVEQ== + +tinyspy@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-1.0.2.tgz#6da0b3918bfd56170fb3cd3a2b5ef832ee1dff0d" + integrity sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q== tmp@~0.2.1: version "0.2.1" @@ -4932,14 +5212,15 @@ totalist@^3.0.0: resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.0.tgz#4ef9c58c5f095255cdc3ff2a0a55091c57a3a1bd" integrity sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw== -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== +tough-cookie@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" + integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== dependencies: psl "^1.1.33" punycode "^2.1.1" - universalify "^0.1.2" + universalify "^0.2.0" + url-parse "^1.5.3" tough-cookie@~2.5.0: version "2.5.0" @@ -4956,16 +5237,21 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" -tslib@2.4.0, tslib@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + tslib@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" @@ -5019,15 +5305,22 @@ type-fest@^0.21.3: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typescript@4.7.4: - version "4.7.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" - integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +typescript@4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db" + integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA== -universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +undici@5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.12.0.tgz#c758ffa704fbcd40d506e4948860ccaf4099f531" + integrity sha512-zMLamCG62PGjd9HHMpo05bSLvvwWOZgGeiWlN/vlqu3+lRo3elxktVGEyLMX+IO7c2eflLjcW74AlkhEZm15mg== + dependencies: + busboy "^1.6.0" + +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: version "2.0.0" @@ -5047,6 +5340,14 @@ update-browserslist-db@^1.0.5: escalade "^3.1.1" picocolors "^1.0.0" +update-browserslist-db@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" + integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" @@ -5054,21 +5355,29 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +uuid@9.0.0, uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - v8-to-istanbul@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" @@ -5095,49 +5404,59 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vite@3.0.6, "vite@^2.9.12 || ^3.0.0-0": - version "3.0.6" - resolved "https://registry.yarnpkg.com/vite/-/vite-3.0.6.tgz#08e85ebaa34a3b647cb1365c87675b45f3511be0" - integrity sha512-pjfsWIzfUlQME/VAmU6SsjdHkTt6WAHysuqPkHDcjzNu6IGtxDSZ/VfRYOwHaCqX4M3Ivz0kxuSfAPM6gAIX+w== +vite@^3.0.0: + version "3.1.7" + resolved "https://registry.yarnpkg.com/vite/-/vite-3.1.7.tgz#9fc2b57a395f79175d38fa3cffd15080b0d9cbfc" + integrity sha512-5vCAmU4S8lyVdFCInu9M54f/g8qbOMakVw5xJ4pjoaDy5wgy9sLLZkGdSLN52dlsBqh0tBqxjaqqa8LgPqwRAA== dependencies: - esbuild "^0.14.47" + esbuild "^0.15.9" postcss "^8.4.16" resolve "^1.22.1" - rollup ">=2.75.6 <2.77.0 || ~2.77.0" + rollup "~2.78.0" optionalDependencies: fsevents "~2.3.2" -vitest-svelte-kit@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/vitest-svelte-kit/-/vitest-svelte-kit-0.0.7.tgz#002b943a2946beffaadf20838ff0d950e8f861f3" - integrity sha512-B83C14BAQEwNqTHcZ1dEV9EuCwOEKglcix32zBqRFonTmnc652JUOPJhMDAkQmOzHlA+SIXZ3FNEKiJjXyd1JA== +vite@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/vite/-/vite-3.2.4.tgz#d8c7892dd4268064e04fffbe7d866207dd24166e" + integrity sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw== + dependencies: + esbuild "^0.15.9" + postcss "^8.4.18" + resolve "^1.22.1" + rollup "^2.79.1" + optionalDependencies: + fsevents "~2.3.2" -vitest@0.21.1: - version "0.21.1" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.21.1.tgz#b4f5b901c9a23a3aaec76d3404f3072821d93d00" - integrity sha512-WBIxuFmIDPuK47GO6Lu9eNeRMqHj/FWL3dk73OHH3eyPPWPiu+UB3QHLkLK2PEggCqJW4FaWoWg8R68S7p9+9Q== +vitefu@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-0.2.2.tgz#d03215f351a1fd65f6c277d546f2d30956b970f9" + integrity sha512-8CKEIWPm4B4DUDN+h+hVJa9pyNi7rzc5MYmbxhs1wcMakueGFNWB5/DL30USm9qU3xUPnL4/rrLEAwwFiD1tag== + +vitest@^0.25.3: + version "0.25.3" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.25.3.tgz#4e5ed481e4da6a0ce014bdb71dfc9661fd62b722" + integrity sha512-/UzHfXIKsELZhL7OaM2xFlRF8HRZgAHtPctacvNK8H4vOcbJJAMEgbWNGSAK7Y9b1NBe5SeM7VTuz2RsTHFJJA== dependencies: "@types/chai" "^4.3.3" "@types/chai-subset" "^1.3.3" "@types/node" "*" + acorn "^8.8.0" + acorn-walk "^8.2.0" chai "^4.3.6" debug "^4.3.4" local-pkg "^0.4.2" - tinypool "^0.2.4" - tinyspy "^1.0.0" - vite "^2.9.12 || ^3.0.0-0" + source-map "^0.6.1" + strip-literal "^0.4.2" + tinybench "^2.3.1" + tinypool "^0.3.0" + tinyspy "^1.0.2" + vite "^3.0.0" -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" - integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg== +w3c-xmlserializer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" + integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw== dependencies: xml-name-validator "^4.0.0" @@ -5201,10 +5520,10 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769" - integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ== +ws@^8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== xml-name-validator@^4.0.0: version "4.0.0"